Implement string.dump

This commit is contained in:
James Roseborough
2008-07-22 22:32:28 +00:00
parent 89c38d00cc
commit ef48f8cd12
6 changed files with 113 additions and 45 deletions

View File

@@ -13,14 +13,11 @@ import java.io.PrintStream;
import org.luaj.vm.CallInfo; import org.luaj.vm.CallInfo;
import org.luaj.vm.LClosure; import org.luaj.vm.LClosure;
import org.luaj.vm.LFunction; import org.luaj.vm.LFunction;
import org.luaj.vm.LInteger;
import org.luaj.vm.LNil; import org.luaj.vm.LNil;
import org.luaj.vm.LNumber;
import org.luaj.vm.LString; import org.luaj.vm.LString;
import org.luaj.vm.LTable; import org.luaj.vm.LTable;
import org.luaj.vm.LValue; import org.luaj.vm.LValue;
import org.luaj.vm.Lua; import org.luaj.vm.Lua;
import org.luaj.vm.LuaErrorException;
import org.luaj.vm.LuaState; import org.luaj.vm.LuaState;
import org.luaj.vm.Platform; import org.luaj.vm.Platform;
@@ -134,21 +131,38 @@ public class BaseLib extends LFunction {
vm.resettop(); vm.resettop();
break; break;
} }
case IPAIRS: case IPAIRS: {
LTable t = vm.checktable(2);
vm.resettop();
vm.pushjavafunction( inext );
vm.pushlvalue( t );
vm.pushinteger( 0 );
break;
}
case PAIRS: { case PAIRS: {
LTable t = vm.checktable(2); LTable t = vm.checktable(2);
vm.resettop(); vm.resettop();
vm.pushjavafunction( (id==IPAIRS)? inext: next ); vm.pushjavafunction( next );
vm.pushlvalue( t ); vm.pushlvalue( t );
vm.pushnil(); vm.pushnil();
break; break;
} }
case INEXT: case INEXT: {
int i = vm.checkint(3) + 1;
LTable t = vm.checktable(2);
LValue v = t.get(i);
vm.resettop();
if ( !v.isNil() ) {
vm.pushinteger(i);
vm.pushlvalue(v);
}
break;
}
case NEXT: { case NEXT: {
LTable t = vm.checktable(2); LTable t = vm.checktable(2);
LValue v = vm.topointer(3); LValue k = vm.topointer(3);
vm.resettop(); vm.resettop();
t.next(vm,v,(id==INEXT)); t.next(vm,k,false);
break; break;
} }
case GETMETATABLE: { case GETMETATABLE: {
@@ -230,7 +244,7 @@ public class BaseLib extends LFunction {
} }
case LOADFILE: case LOADFILE:
loadfile(vm, vm.optstring(2,"")); loadfile(vm, vm.optstring(2,null));
break; break;
case TONUMBER: { case TONUMBER: {
@@ -411,6 +425,13 @@ public class BaseLib extends LFunction {
} }
// return true if loaded, false if error put onto the stack // return true if loaded, false if error put onto the stack
/** Load a chunk from an input stream, leaving it on the stack if successful,
* then close the input stream if it is not STDIN
*
* @param vm LuaState to load into
* @param is input stream to load from
* @return true if loaded and only item on stack, false if nil+error put onto stack
*/
static boolean loadis(LuaState vm, InputStream is, String chunkname ) { static boolean loadis(LuaState vm, InputStream is, String chunkname ) {
try { try {
vm.resettop(); vm.resettop();
@@ -426,12 +447,17 @@ public class BaseLib extends LFunction {
} }
// return true if loaded, false if error put onto stack /** Load a file into a chunk given a filename, leaving it on the stack if successful
public static boolean loadfile( LuaState vm, String fileName ) { *
* @param vm LuaState to load into
* @param fileName file to load, or null to use STDIN
* @return true if loaded and only item on stack, false if nil+error put onto stack
*/
private static boolean loadfile( LuaState vm, String fileName ) {
InputStream is; InputStream is;
String script; String script;
if ( ! "".equals(fileName) ) { if ( fileName != null ) {
script = fileName; script = fileName;
is = Platform.getInstance().openFile(fileName); is = Platform.getInstance().openFile(fileName);
if ( is == null ) { if ( is == null ) {
@@ -439,7 +465,7 @@ public class BaseLib extends LFunction {
return false; return false;
} }
} else { } else {
is = STDIN; is = STDIN != null? STDIN: new ByteArrayInputStream(new byte[0]);
script = "-"; script = "-";
} }
@@ -449,12 +475,11 @@ public class BaseLib extends LFunction {
// if load succeeds, return 0 for success, 1 for error (as per lua spec) // if load succeeds, return 0 for success, 1 for error (as per lua spec)
private void dofile( LuaState vm ) { private void dofile( LuaState vm ) {
String filename = vm.checkstring(2); String filename = vm.optstring(2,null);
if ( loadfile( vm, filename ) ) { if ( loadfile( vm, filename ) ) {
int s = vm.pcall(1, 0, 0); vm.call(0, 0);
setResult( vm, LInteger.valueOf( s!=0? 1: 0 ) );
} else { } else {
vm.error("cannot open "+filename); vm.error( vm.tostring(-1) );
} }
} }

View File

@@ -21,12 +21,16 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.lib; package org.luaj.lib;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.luaj.compiler.DumpState;
import org.luaj.vm.LClosure;
import org.luaj.vm.LFunction; import org.luaj.vm.LFunction;
import org.luaj.vm.LNumber; import org.luaj.vm.LNumber;
import org.luaj.vm.LString; import org.luaj.vm.LString;
import org.luaj.vm.LTable; import org.luaj.vm.LTable;
import org.luaj.vm.LValue; import org.luaj.vm.LValue;
import org.luaj.vm.Lua;
import org.luaj.vm.LuaState; import org.luaj.vm.LuaState;
@@ -204,7 +208,15 @@ public class StringLib extends LFunction {
* TODO: port dumping code as optional add-on * TODO: port dumping code as optional add-on
*/ */
static void dump( LuaState vm ) { static void dump( LuaState vm ) {
vm.error("dump() not supported"); LFunction f = vm.checkfunction(2);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
DumpState.dump( ((LClosure)f).p, baos, true );
vm.resettop();
vm.pushlstring(baos.toByteArray());
} catch (IOException e) {
vm.error( e.getMessage() );
}
} }
/** /**

View File

@@ -1,7 +1,6 @@
package.path = "?.lua;src/test/errors/?.lua" package.path = "?.lua;src/test/errors/?.lua"
require 'args' require 'args'
-- arg types for basic library functions -- arg types for basic library functions
-- assert -- assert
@@ -17,7 +16,8 @@ checkallerrors('collectgarbage',{notanil},'bad argument #1')
-- dofile -- dofile
banner('dofile') banner('dofile')
checkallpass('dofile', {{nil,'src/test/errors/args.lua'}}) checkallpass('dofile', {})
checkallpass('dofile', {{'src/test/errors/args.lua'}})
checkallerrors('dofile', {{'args.lua'}}, 'cannot open args.lua') checkallerrors('dofile', {{'args.lua'}}, 'cannot open args.lua')
checkallerrors('dofile', {nonstring}, 'bad argument #1') checkallerrors('dofile', {nonstring}, 'bad argument #1')
@@ -50,11 +50,17 @@ checkallerrors('load', {somefunction,{afunction,atable}}, 'bad argument #2')
-- loadfile -- loadfile
banner('loadfile') banner('loadfile')
checkallpass('loadfile', {}) checkallpass('loadfile', {})
checkallpass('loadfile', {{'bogus'}})
checkallpass('loadfile', {{'src/test/errors/args.lua'}})
checkallpass('loadfile', {{'args.lua'}})
checkallerrors('loadfile', {nonstring}, 'bad argument #1') checkallerrors('loadfile', {nonstring}, 'bad argument #1')
-- loadstring -- loadstring
banner('loadstring') banner('loadstring')
checkallpass('loadstring', {{'return'},{nil,astring}}) checkallpass('loadstring', {{'return'}})
checkallpass('loadstring', {{'return'},{'mychunk'}})
checkallpass('loadstring', {{'return a ... b'},{'mychunk'}})
checkallerrors('loadstring', {{'return a ... b'},{'mychunk'}},'hello')
checkallerrors('loadstring', {notastring,{nil,astring,anumber}}, 'bad argument #1') checkallerrors('loadstring', {notastring,{nil,astring,anumber}}, 'bad argument #1')
checkallerrors('loadstring', {{'return'},{afunction,atable}}, 'bad argument #2') checkallerrors('loadstring', {{'return'},{afunction,atable}}, 'bad argument #2')

View File

@@ -5,13 +5,13 @@ require 'args'
-- require -- require
banner('require') banner('require')
checkallpass('require',{{'math'}}) checkallpass('require',{{'math','coroutine','package','string','table'}},true)
checkallerrors('require',{{anumber}},'not found') checkallerrors('require',{{anumber}},'not found')
checkallerrors('require',{{anil,aboolean,afunction,atable}},'bad argument') checkallerrors('require',{{anil,aboolean,afunction,atable}},'bad argument')
-- package.loadlib -- package.loadlib
banner('package.loadlib') banner('package.loadlib')
checkallpass('package.loadlib',{{'foo'},{'bar'}}) checkallpass('package.loadlib',{{'foo'},{'bar'}},true)
checkallerrors('package.loadlib',{notastring},'bad argument') checkallerrors('package.loadlib',{notastring},'bad argument')
-- package.seeall -- package.seeall
@@ -20,11 +20,30 @@ checkallpass('package.seeall',{sometable})
checkallerrors('package.seeall',{notatable},'bad argument') checkallerrors('package.seeall',{notatable},'bad argument')
-- module (last because it pretty much breaks this chunk) -- module tests - require special rigging
banner('module')
print( pcall( function() print( pcall( function()
banner('module') checkallpass('module',{{20001}})
checkallpass('module',{somenumber,{package.seeall},{nil,afunction}}) end ) )
checkallerrors('module',{{aboolean,atable,afunction}},'bad argument') print( pcall( function()
checkallerrors('module',{{aboolean,atable,afunction},{package.seeall}},'bad argument') checkallpass('module',{{20002},{package.seeall}})
checkallerrors('module',{somestring,{astring,anumber,aboolean,atable}},'attempt to call a') end ) )
print( pcall( function()
checkallpass('module',{{20003},{package.seeall},{function() end}})
end ) )
print( pcall( function()
checkallerrors('module',{{aboolean,atable,function() end}},'bad argument')
checkallerrors('module',{{aboolean,atable,function() end},{package.seeall}},'bad argument')
end ) )
print( pcall( function()
checkallerrors('module',{{'testmodule1'},{'pqrs'}},'attempt to call')
end ) )
print( pcall( function()
checkallerrors('module',{{'testmodule2'},{aboolean}},'attempt to call')
end ) )
print( pcall( function()
checkallerrors('module',{{'testmodule3'},{athread}},'attempt to call')
end ) )
print( pcall( function()
checkallerrors('module',{{'testmodule4'},{atable}},'attempt to call')
end ) ) end ) )

View File

@@ -12,17 +12,27 @@ checkallerrors('string.byte',{somestring,{astring,afunction,atable}},'bad argume
checkallerrors('string.byte',{notastring,{nil,111}},'bad argument') checkallerrors('string.byte',{notastring,{nil,111}},'bad argument')
-- string.char -- string.char
banner('string.char') function string_char(...)
checkallpass('string.char',{{nil,0,1,40,127,128,255,'0','1','255','1.2',1.2}}) return string.byte( string.char( ... ) )
checkallpass('string.char',{{0,127,255},{0,127,255}}) end
checkallpass('string.char',{}) banner('string_char')
checkallerrors('string.char',{{-1,256}},'bad argument #1') checkallpass('string.char',{{60}})
checkallerrors('string.char',{notanumber,{23,'45',6.7}},'bad argument #1') checkallpass('string.char',{{60},{70}})
checkallerrors('string.char',{{23,'45',6.7},nonnumber},'bad argument #2') checkallpass('string.char',{{60},{70},{80}})
checkallpass('string_char',{{nil,0,9,40,127,128,255,'0','9','255','9.2',9.2}})
checkallpass('string_char',{{0,127,255},{0,127,255}})
checkallpass('string_char',{})
checkallerrors('string_char',{},'bad argument #1')
checkallerrors('string_char',{{-1,256}},'bad argument #1')
checkallerrors('string_char',{notanumber,{23,'45',6.7}},'bad argument #1')
checkallerrors('string_char',{{23,'45',6.7},nonnumber},'bad argument #2')
-- string.dump -- string.dump
banner('string.dump') banner('string.dump')
checkallpass('string.dump',{{afunction}}) local someupval = 435
local function funcwithupvals() return someupval end
checkallpass('string.dump',{{function() return 123 end}})
checkallpass('string.dump',{{funcwithupvals}})
checkallerrors('string.dump',{notafunction},'bad argument') checkallerrors('string.dump',{notafunction},'bad argument')
-- string.find -- string.find

View File

@@ -27,11 +27,7 @@ public class ScriptDrivenTest extends TestCase {
InterruptedException { InterruptedException {
// set platform relative to directory // set platform relative to directory
Platform.setInstance(new J2sePlatform() { Platform.setInstance(new J2sePlatform());
public InputStream openFile(String fileName) {
return super.openFile(basedir+"/"+fileName);
}
});
// new lua state // new lua state
LuaState state = Platform.newLuaState(); LuaState state = Platform.newLuaState();