Improve __concat
This commit is contained in:
@@ -236,14 +236,14 @@ public class LuaClosure extends LuaFunction {
|
|||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
c = (i>>14)&0x1ff;
|
c = (i>>14)&0x1ff;
|
||||||
{
|
{
|
||||||
LuaValue r = stack[c-1].concat(stack[c]);
|
if ( c > b+1 ) {
|
||||||
if ( (c-=2) >= b ) {
|
Buffer sb = stack[c].buffer();
|
||||||
Buffer sb = r.buffer();
|
while ( --c>=b )
|
||||||
while ( c>=b )
|
sb = stack[c].concat(sb);
|
||||||
sb = stack[c--].concat(sb);
|
stack[a] = sb.value();
|
||||||
r = sb.value();
|
} else {
|
||||||
|
stack[a] = stack[c-1].concat(stack[c]);
|
||||||
}
|
}
|
||||||
stack[a] = r;
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class LuaNumber extends LuaValue {
|
|||||||
|
|
||||||
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
|
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
|
||||||
public Buffer concat(Buffer rhs) { return rhs.prepend(this.strvalue()); }
|
public Buffer concat(Buffer rhs) { return rhs.prepend(this.strvalue()); }
|
||||||
|
public LuaValue concatTo(LuaValue lhs) { return lhs.concaterror(); }
|
||||||
public LuaValue concatTo(LuaNumber lhs) { return strvalue().concatTo(lhs.strvalue()); }
|
public LuaValue concatTo(LuaNumber lhs) { return strvalue().concatTo(lhs.strvalue()); }
|
||||||
public LuaValue concatTo(LuaString lhs) { return strvalue().concatTo(lhs); }
|
public LuaValue concatTo(LuaString lhs) { return strvalue().concatTo(lhs); }
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ public class LuaString extends LuaValue {
|
|||||||
// concatenation
|
// concatenation
|
||||||
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
|
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
|
||||||
public Buffer concat(Buffer rhs) { return rhs.prepend(this); }
|
public Buffer concat(Buffer rhs) { return rhs.prepend(this); }
|
||||||
|
public LuaValue concatTo(LuaValue lhs) { return lhs.concaterror(); }
|
||||||
public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); }
|
public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); }
|
||||||
public LuaValue concatTo(LuaString lhs) {
|
public LuaValue concatTo(LuaString lhs) {
|
||||||
byte[] b = new byte[lhs.m_length+this.m_length];
|
byte[] b = new byte[lhs.m_length+this.m_length];
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public class LuaValue extends Varargs {
|
|||||||
protected LuaValue aritherror(String fun) { throw new LuaError("attempt to perform arithmetic '"+fun+"' on "+typename()); }
|
protected LuaValue aritherror(String fun) { throw new LuaError("attempt to perform arithmetic '"+fun+"' on "+typename()); }
|
||||||
protected LuaValue compareerror(String rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs); }
|
protected LuaValue compareerror(String rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs); }
|
||||||
protected LuaValue compareerror(LuaValue rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs.typename()); }
|
protected LuaValue compareerror(LuaValue rhs) { throw new LuaError("attempt to compare "+typename()+" with "+rhs.typename()); }
|
||||||
|
protected LuaValue concaterror() { throw new LuaError("attempt to concatenate "+typename()); }
|
||||||
|
|
||||||
// table operations
|
// table operations
|
||||||
public LuaValue get( LuaValue key ) { return gettable(this,key); }
|
public LuaValue get( LuaValue key ) { return gettable(this,key); }
|
||||||
@@ -344,18 +345,17 @@ public class LuaValue extends Varargs {
|
|||||||
public int strcmp( LuaString rhs ) { error("attempt to compare "+typename()); return 0; }
|
public int strcmp( LuaString rhs ) { error("attempt to compare "+typename()); return 0; }
|
||||||
|
|
||||||
// concatenation
|
// concatenation
|
||||||
public LuaValue concat(LuaValue rhs) { return this.concatmt(rhs); }
|
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
|
||||||
public LuaValue concatTo(LuaNumber lhs) { return lhs.concatmt(this); }
|
public LuaValue concatTo(LuaValue lhs) { return lhs.concatmt(this); }
|
||||||
public LuaValue concatTo(LuaString lhs) { return lhs.concatmt(this); }
|
public LuaValue concatTo(LuaNumber lhs) { return concaterror(); }
|
||||||
|
public LuaValue concatTo(LuaString lhs) { return concaterror(); }
|
||||||
public Buffer buffer() { return new Buffer(this); }
|
public Buffer buffer() { return new Buffer(this); }
|
||||||
public Buffer concat(Buffer rhs) {
|
public Buffer concat(Buffer rhs) { return rhs.setvalue(concat(rhs.value())); }
|
||||||
return rhs.setvalue(checkmetatag(CONCAT,"attempt to concatenate ").call(this, rhs.value()));
|
|
||||||
}
|
|
||||||
public LuaValue concatmt(LuaValue rhs) {
|
public LuaValue concatmt(LuaValue rhs) {
|
||||||
LuaValue h=metatag(CONCAT);
|
LuaValue h=metatag(CONCAT);
|
||||||
LuaValue v=this;
|
LuaValue v=this;
|
||||||
if ( h.isnil() || (h=(v=rhs).metatag(CONCAT)).isnil())
|
if ( h.isnil() && (h=(v=rhs).metatag(CONCAT)).isnil())
|
||||||
v.typerror("attempt to concatenate ");
|
return v.concaterror();
|
||||||
return h.call(this,rhs);
|
return h.call(this,rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.luaj.vm2.LuaDouble;
|
|||||||
import org.luaj.vm2.LuaInteger;
|
import org.luaj.vm2.LuaInteger;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.lib.TwoArgFunction;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@@ -646,4 +647,57 @@ public class UnaryBinaryOperatorsTest extends TestCase {
|
|||||||
b = def.concat(b); assertEquals( "def123", b.value().tojstring() );
|
b = def.concat(b); assertEquals( "def123", b.value().tojstring() );
|
||||||
b = abc.concat(b); assertEquals( "abcdef123", b.value().tojstring() );
|
b = abc.concat(b); assertEquals( "abcdef123", b.value().tojstring() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testConcatMetatag() {
|
||||||
|
LuaValue def = LuaValue.valueOf("abcdefghi").substring(3,6);
|
||||||
|
LuaValue ghi = LuaValue.valueOf("abcdefghi").substring(6,9);
|
||||||
|
LuaValue tru = LuaValue.TRUE;
|
||||||
|
LuaValue fal = LuaValue.FALSE;
|
||||||
|
LuaValue tbl = new LuaTable();
|
||||||
|
LuaValue uda = new LuaUserdata(new Object());
|
||||||
|
try {
|
||||||
|
// always use left argument
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] {
|
||||||
|
LuaValue.CONCAT, new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
} } );
|
||||||
|
assertEquals( tru, tru.concat(tbl) );
|
||||||
|
assertEquals( tbl, tbl.concat(tru) );
|
||||||
|
assertEquals( tru, tru.concat(new Buffer(tbl)).value() );
|
||||||
|
assertEquals( tbl, tbl.concat(new Buffer(tru)).value() );
|
||||||
|
assertEquals( fal, fal.concat(tbl.concat(new Buffer(tru))).value() );
|
||||||
|
assertEquals( uda, uda.concat(tru.concat(new Buffer(tbl))).value() );
|
||||||
|
try { tru.concat(def); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { def.concat(tru); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.concat(new Buffer(def)).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { def.concat(new Buffer(tru)).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { fal.concat(def.concat(new Buffer(tru))).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { ghi.concat(tru.concat(new Buffer(def))).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
// always use right argument
|
||||||
|
LuaBoolean.s_metatable = LuaValue.tableOf( new LuaValue[] {
|
||||||
|
LuaValue.CONCAT, new TwoArgFunction() {
|
||||||
|
public LuaValue call(LuaValue lhs, LuaValue rhs) {
|
||||||
|
return rhs;
|
||||||
|
}
|
||||||
|
} } );
|
||||||
|
assertEquals( tbl, tru.concat(tbl) );
|
||||||
|
assertEquals( tru, tbl.concat(tru) );
|
||||||
|
assertEquals( tbl, tru.concat(new Buffer(tbl)).value() );
|
||||||
|
assertEquals( tru, tbl.concat(new Buffer(tru)).value() );
|
||||||
|
assertEquals( tru, uda.concat(tbl.concat(new Buffer(tru))).value() );
|
||||||
|
assertEquals( tbl, fal.concat(tru.concat(new Buffer(tbl))).value() );
|
||||||
|
try { tru.concat(def); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { def.concat(tru); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { tru.concat(new Buffer(def)).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { def.concat(new Buffer(tru)).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { uda.concat(def.concat(new Buffer(tru))).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
try { fal.concat(tru.concat(new Buffer(def))).value(); fail("did not throw error"); } catch ( LuaError le ) { };
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
LuaBoolean.s_metatable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user