Reconcile C & Java typechecking on table.concat() and string .. concat operator
This commit is contained in:
@@ -98,26 +98,17 @@ public class TableLib extends LFunction {
|
||||
int n = vm.gettop();
|
||||
LTable table = vm.totable(2);
|
||||
LString sep = (n>=3? vm.tolstring(3): null);
|
||||
int i = vm.tointeger(4);
|
||||
int j = vm.tointeger(5);
|
||||
int len = table.luaLength();
|
||||
if ( i == 0 )
|
||||
i = 1;
|
||||
if ( j == 0 )
|
||||
j = len;
|
||||
int i = (n>=4? vm.tointeger(4): 1);
|
||||
int j = (n>=5? vm.tointeger(5): table.luaLength());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
for ( int k=i; k<=j; k++ ) {
|
||||
LValue v = table.get(k);
|
||||
v.luaAsString().write(baos);
|
||||
if ( k<j && sep!=null )
|
||||
sep.write( baos );
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlstring( baos.toByteArray() );
|
||||
} catch (IOException e) {
|
||||
vm.error(e.getMessage());
|
||||
for ( int k=i; k<=j; k++ ) {
|
||||
LValue v = table.get(k);
|
||||
v.luaConcatTo(baos);
|
||||
if ( k<j && sep!=null )
|
||||
sep.luaConcatTo( baos );
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlstring( baos.toByteArray() );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
|
||||
abstract
|
||||
public class LNumber extends LValue {
|
||||
@@ -83,4 +85,9 @@ public class LNumber extends LValue {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Write as a string */
|
||||
public void luaConcatTo(ByteArrayOutputStream baos) {
|
||||
luaAsString().luaConcatTo( baos );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package org.luaj.vm;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@@ -262,23 +263,6 @@ public class LString extends LValue {
|
||||
return new LString( s );
|
||||
}
|
||||
|
||||
public static LString concat( final LString[] strings ) {
|
||||
int length = 0;
|
||||
for ( int i = 0; i < strings.length; ++i ) {
|
||||
length += strings[i].length();
|
||||
}
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
for ( int i = 0, offset = 0; i < strings.length; ++i ) {
|
||||
LString s = strings[i];
|
||||
final int len = s.length();
|
||||
System.arraycopy( s.m_bytes, s.m_offset, bytes, offset, len );
|
||||
offset += len;
|
||||
}
|
||||
|
||||
return new LString( bytes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the specified substring of this string to the given output stream.
|
||||
*/
|
||||
@@ -437,5 +421,8 @@ public class LString extends LValue {
|
||||
return m_bytes[m_offset + index] & 0x0FF;
|
||||
}
|
||||
|
||||
public void luaConcatTo(ByteArrayOutputStream baos) {
|
||||
baos.write( m_bytes, m_offset, m_length );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
|
||||
abstract
|
||||
public class LValue {
|
||||
@@ -322,4 +324,9 @@ public class LValue {
|
||||
public LValue toStrongReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Concatenate this value to a ByteArrayOutputStream */
|
||||
public void luaConcatTo(ByteArrayOutputStream baos) {
|
||||
throw new LuaErrorException( "attempt to concat ? (a "+luaGetTypeName()+" value)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,13 +639,11 @@ public class LuaState extends Lua {
|
||||
b = LuaState.GETARG_B(i);
|
||||
c = LuaState.GETARG_C(i);
|
||||
int numValues = c - b + 1;
|
||||
LString[] strings = new LString[numValues];
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (int j = b, l = 0; j <= c; j++, l++) {
|
||||
LString s = this.stack[base + j].luaAsString();
|
||||
strings[l] = s;
|
||||
this.stack[base + j].luaConcatTo( baos );
|
||||
}
|
||||
this.stack[base + a] = LString.concat( strings );
|
||||
this.stack[base + a] = new LString( baos.toByteArray() );
|
||||
continue;
|
||||
}
|
||||
case LuaState.OP_JMP: {
|
||||
|
||||
@@ -60,6 +60,33 @@ print( 'a(-a) ', a(function() return -a end) )
|
||||
print( 'a(-s) ', a(function() return -s end) )
|
||||
print( 'a(-true)', a(function() local b = true; return -b end) )
|
||||
|
||||
-- string concatenation
|
||||
local function concatsuite(comparefunc)
|
||||
print( '"a".."b"', comparefunc("a","b") )
|
||||
print( '"a"..nil', comparefunc("a",nil) )
|
||||
print( 'nil.."b"', comparefunc(nil,"b") )
|
||||
print( '"a"..{}', comparefunc("a",{}) )
|
||||
print( '{}.."b"', comparefunc({},"b") )
|
||||
print( '"a"..2', comparefunc("a",2) )
|
||||
print( '2.."b"', comparefunc(2,"b") )
|
||||
print( '"a"..print', comparefunc("a",print) )
|
||||
print( 'print.."b"', comparefunc(print,"b") )
|
||||
print( '"a"..true', comparefunc("a",true) )
|
||||
print( 'true.."b"', comparefunc(true,"b") )
|
||||
print( 'nil..true', comparefunc(nil,true) )
|
||||
print( '"a"..3.5', comparefunc("a",3.5) )
|
||||
print( '3.5.."b"', comparefunc(3.5,"b") )
|
||||
end
|
||||
local function strconcat(a,b)
|
||||
return pcall( function() return a..b end )
|
||||
end
|
||||
local function tblconcat(a,b)
|
||||
local t={a,b}
|
||||
return pcall( function() return table.concat(t,'-') end )
|
||||
end
|
||||
-- concatsuite(strconcat)
|
||||
concatsuite(tblconcat)
|
||||
|
||||
-- pairs
|
||||
print( 'a(pairs(nil))', a(function() return id(pairs(nil,{})) end) )
|
||||
print( 'a(pairs(a)) ', a(function() return id(pairs(a,{})) end) )
|
||||
|
||||
Reference in New Issue
Block a user