Many built-ins: ipairs, table.insert, require, pcall

This commit is contained in:
James Roseborough
2007-09-21 00:34:14 +00:00
parent d45bd96536
commit 2db26b0844
7 changed files with 240 additions and 62 deletions

View File

@@ -25,13 +25,16 @@ final class Builtin extends LFunction {
"getmetatable",
"setmetatable",
"type",
"pcall" };
"pcall",
"ipairs",
};
private static final int PRINT = 0;
private static final int PAIRS = 1;
private static final int GETMETATABLE = 2;
private static final int SETMETATABLE = 3;
private static final int TYPE = 4;
private static final int PCALL = 5;
private static final int IPAIRS = 6;
private static PrintStream stdout = System.out;
@@ -47,18 +50,20 @@ final class Builtin extends LFunction {
// perform a lua call
public boolean luaStackCall(VM vm) {
switch ( id ) {
case PRINT:
int n = vm.getArgCount();
for ( int i=0; i<n; i++ ) {
if ( i > 0 )
stdout.print( "\t" );
stdout.print( vm.getArg(i).luaAsString() );
case PRINT: {
int n = vm.getArgCount();
for ( int i=0; i<n; i++ ) {
if ( i > 0 )
stdout.print( "\t" );
stdout.print( vm.getArg(i).luaAsString() );
}
stdout.println();
vm.setResult();
}
stdout.println();
vm.setResult();
break;
case PAIRS:
vm.setResult( vm.getArg(0).luaPairs() );
case IPAIRS:
vm.setResult( vm.getArg(0).luaPairs(id==PAIRS) );
break;
case GETMETATABLE:
vm.setResult( vm.getArg(0).luaGetMetatable() );
@@ -71,13 +76,16 @@ final class Builtin extends LFunction {
case TYPE:
vm.setResult( vm.getArg(0).luaGetType() );
break;
case PCALL:
if ( 0 != vm.lua_pcall( vm.getArgCount()-1, Lua.LUA_MULTRET ) ) {
LValue v = vm.getArg(0);
vm.setResult( LBoolean.FALSE );
vm.push( v );
} else {
vm.setResult( LBoolean.TRUE );
case PCALL: {
int n = vm.getArgCount();
int s = vm.lua_pcall( n-1, Lua.LUA_MULTRET );
if ( s != 0 ) {
LValue v = vm.lua_tolvalue(-1);
vm.setResult( LBoolean.FALSE );
vm.push( v );
} else {
vm.setResult( LBoolean.TRUE );
}
}
break;
default:

View File

@@ -179,4 +179,11 @@ public interface VM {
* @return 0 if successful, LUA_ERRMEM if no memory, LUA_ERRSYNTAX for i/o or any other errors
*/
public int lua_load( InputStream is, String chunkname );
/**
* Get a value on the stack, relative to the top or bottom
* @param i index from bottom if 0 or greater, index from top if less than 0
* @return
*/
public LValue lua_tolvalue(int i);
}

View File

@@ -5,7 +5,6 @@ import java.util.Map;
import java.util.StringTokenizer;
import lua.CallInfo;
import lua.Print;
import lua.StackState;
import lua.io.LocVars;
import lua.io.Proto;
@@ -38,22 +37,34 @@ public class DebugStackState extends StackState implements DebugRequestListener
return source+":"+line+"("+func+")";
}
private String addLineInfo( String message ) {
return getFileLine(cc)+": "+message;
}
private void printLuaTrace(String message) {
System.out.println( "Lua error: "+message );
System.out.println( "Lua error: "+addLineInfo( message ) );
for ( int cindex=cc-1; cindex>=0; cindex-- )
System.out.println( "\tcalled by "+getFileLine( cindex ) );
}
protected void debugPcallError(Throwable t) {
System.out.println(addLineInfo("(caught in pcall) "+t.getMessage()));
System.out.flush();
}
public void lua_error(String message) {
throw new RuntimeException( message );
}
// intercept exceptions and fill in line numbers
public void exec() {
try {
super.exec();
} catch ( RuntimeException t ) {
String message = getFileLine(cc)+": "+t.getMessage();
t.printStackTrace();
printLuaTrace(message);
printLuaTrace(t.getMessage());
System.out.flush();
throw new RuntimeException( message, t );
throw t;
}
}
@@ -63,6 +74,9 @@ public class DebugStackState extends StackState implements DebugRequestListener
if ( exiting )
throw new java.lang.RuntimeException("exiting");
// make sure line numbers are current in any stack traces
calls[cc].pc = pc;
synchronized ( this ) {
// anytime the line doesn't change we keep going

View File

@@ -1,6 +1,7 @@
package lua.value;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
@@ -185,6 +186,10 @@ public class LString extends LValue {
os.write( m_bytes, m_offset+offset, len );
}
public void write(OutputStream os) throws IOException {
write(os, 0, m_length);
}
/**
* Copy the bytes of the string into the given byte array.

View File

@@ -267,18 +267,20 @@ public class LTable extends LValue {
}
/** Valid for tables */
public LValue luaPairs() {
return new LTableIterator();
public LValue luaPairs(boolean isPairs) {
return new LTableIterator(isPairs);
}
/** Iterator for tables */
private final class LTableIterator extends LFunction {
private int arrayIndex;
private int hashIndex;
private final boolean isPairs;
private LTableIterator() {
private LTableIterator(boolean isPairs) {
this.arrayIndex = 0;
this.hashIndex = 0;
this.isPairs = isPairs;
}
// perform a lua call
@@ -292,7 +294,7 @@ public class LTable extends LValue {
return false;
}
}
if ( m_hashKeys != null ) {
if ( isPairs && (m_hashKeys != null) ) {
while ( ( i = hashIndex++ ) < m_hashKeys.length ) {
if ( m_hashKeys[i] != null ) {
vm.push( m_hashKeys[i] );
@@ -513,5 +515,26 @@ public class LTable extends LValue {
int getArrayCapacity() {
return m_vector.length;
}
/*
* @pos index to insert at, or 0 to insert at end.
*/
public void luaInsertPos(int pos, LValue value) {
if ( pos != 0 )
throw new RuntimeException("luaInsertPos() not implemented");
put( m_arrayEntries + m_hashEntries + 1, value );
}
public void luaSort() {
throw new RuntimeException("luaSort() not implemented");
}
public void luaRemovePos(int pos) {
throw new RuntimeException("luaRemovePos() not implemented");
}
public int luaMaxN() {
throw new RuntimeException("luaMaxN() not implemented");
}
}

View File

@@ -151,8 +151,9 @@ public class LValue {
return luaUnsupportedOperation();
}
/** Valid for tables */
public LValue luaPairs() {
/** Valid for tables
* @param isPairs true to iterate over non-integers as well */
public LValue luaPairs(boolean isPairs) {
return luaUnsupportedOperation();
}