Reconcile C & Java typechecking on table.concat() and string .. concat operator

This commit is contained in:
James Roseborough
2008-04-22 04:52:24 +00:00
parent 3c3b43bcfd
commit bba4cf9a99
7 changed files with 58 additions and 41 deletions

View File

@@ -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;
}

View File

@@ -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 );
}
}

View File

@@ -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 );
}
}

View File

@@ -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)");
}
}

View File

@@ -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: {

View File

@@ -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) )