Partial implementation of metatables.

This commit is contained in:
James Roseborough
2007-06-16 15:31:27 +00:00
parent 7449605d56
commit 5d3c86e552
10 changed files with 108 additions and 14 deletions

View File

@@ -0,0 +1,12 @@
#Sat Jun 16 07:29:29 PDT 2007
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.4
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
org.eclipse.jdt.core.compiler.source=1.3

View File

@@ -0,0 +1,3 @@
#Sat Jun 16 07:29:29 PDT 2007
eclipse.preferences.version=1
internal.default.compliance=default

View File

@@ -18,8 +18,10 @@ final class Builtin extends LFunction {
private static final int PRINT = 0; private static final int PRINT = 0;
private static final int PAIRS = 1; private static final int PAIRS = 1;
private static final int GETMETATABLE = 2;
private static final int SETMETATABLE = 3;
private static final String[] NAMES = { "print", "pairs" }; private static final String[] NAMES = { "print", "pairs", "getmetatable", "setmetatable" };
private int id; private int id;
private Builtin( int id ) { private Builtin( int id ) {
@@ -31,7 +33,7 @@ final class Builtin extends LFunction {
} }
// perform a lua call // perform a lua call
public void luaStackCall(StackState state, int base, int top) { public void luaStackCall(StackState state, int base, int top, int nresults) {
switch ( id ) { switch ( id ) {
case PRINT: case PRINT:
for ( int i=base+1; i<top; i++ ) { for ( int i=base+1; i<top; i++ ) {
@@ -39,16 +41,26 @@ final class Builtin extends LFunction {
System.out.print( "\t" ); System.out.print( "\t" );
} }
System.out.println(); System.out.println();
state.adjustTop(base); state.top = base;
return; break;
case PAIRS: case PAIRS:
LValue value = state.stack[base+1].luaPairs(); LValue value = state.stack[base+1].luaPairs();
state.top = base+1;
state.stack[base] = value; state.stack[base] = value;
return; state.top = base+1;
break;
case GETMETATABLE:
state.stack[base] = state.stack[base+1].luaGetMetatable();
state.top = base+1;
break;
case SETMETATABLE:
state.stack[base+1].luaSetMetatable(state.stack[base+2]);
state.top = base;
break;
default: default:
luaUnsupportedOperation(); luaUnsupportedOperation();
} }
if (nresults >= 0)
state.adjustTop(base + nresults);
} }
} }

View File

@@ -16,7 +16,7 @@ public class Closure extends LValue {
} }
// perform a lua call // perform a lua call
public void luaStackCall(StackState state, int base, int top) { public void luaStackCall(StackState state, int base, int top, int nresults) {
state.setupCall( this, base, top ); state.setupCall( this, base, top );
} }

View File

@@ -2,13 +2,13 @@ package lua.value;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Vector;
import lua.StackState; import lua.StackState;
public class LTable extends LValue { public class LTable extends LValue {
private Hashtable m_hash = new Hashtable(); private Hashtable m_hash = new Hashtable();
private LValue m_metatable;
public LTable() { public LTable() {
} }
@@ -34,6 +34,16 @@ public class LTable extends LValue {
return new LInteger( m_hash.size() ); return new LInteger( m_hash.size() );
} }
/** Valid for tables */
public LValue luaGetMetatable() {
return this.m_metatable;
}
/** Valid for tables */
public void luaSetMetatable(LValue metatable) {
this.m_metatable = metatable;
}
/** Valid for tables */ /** Valid for tables */
public LValue luaPairs() { public LValue luaPairs() {
Enumeration e = m_hash.keys(); Enumeration e = m_hash.keys();
@@ -51,15 +61,18 @@ public class LTable extends LValue {
} }
// perform a lua call // perform a lua call
public void luaStackCall(StackState state, int base, int top) { public void luaStackCall(StackState state, int base, int top, int nresults) {
if ( e.hasMoreElements() ) { if ( e.hasMoreElements() ) {
LValue key = (LValue) e.nextElement(); LValue key = (LValue) e.nextElement();
state.adjustTop(base+2);
state.stack[base] = key; state.stack[base] = key;
state.stack[base+1] = t.luaGetTable(key); state.stack[base+1] = t.luaGetTable(key);
state.top = base+2;
} else { } else {
state.adjustTop(base); state.stack[base] = LNil.NIL;
state.top = base+1;
} }
if ( nresults >= 0 )
state.adjustTop(base + nresults);
} }
} }

View File

@@ -16,7 +16,7 @@ public class LValue {
} }
// perform a lua call, return number of results actually produced // perform a lua call, return number of results actually produced
public void luaStackCall(StackState state, int base, int top) { public void luaStackCall(StackState state, int base, int top, int nresults) {
luaUnsupportedOperation(); luaUnsupportedOperation();
} }
@@ -111,5 +111,15 @@ public class LValue {
return luaUnsupportedOperation(); return luaUnsupportedOperation();
} }
/** Valid for tables */
public LValue luaGetMetatable() {
return luaUnsupportedOperation();
}
/** Valid for tables */
public void luaSetMetatable(LValue metatable) {
luaUnsupportedOperation();
}
} }

View File

@@ -38,7 +38,7 @@ public class LuacRunner {
state.push( c ); state.push( c );
for ( int i=0; i<args.length; i++ ) for ( int i=0; i<args.length; i++ )
state.push( new LString(args[i]) ); state.push( new LString(args[i]) );
state.docall(args.length, false); state.docall(args.length, 0);
// print result? // print result?
System.out.println("stack:"); System.out.println("stack:");

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
LUA_HOME=/cygdrive/c/programs/lua5.1 LUA_HOME=/cygdrive/c/programs/lua5.1
TESTS="test1 test2 test3 test4 test5" TESTS="test1 test2 test3 test4 test5"
TESTS="test5" TESTS="test6"
for x in $TESTS for x in $TESTS
do do
echo compiling $x echo compiling $x

44
src/test/res/test6.lua Normal file
View File

@@ -0,0 +1,44 @@
t = { 11, 22, 33, you='one', me='two' }
--[[
for a,b in pairs(t) do
print( a, b )
end
print( "t[2]", t[2] )
print( "t.me", t.me )
print( "t.fred", t.fred )
print( "t['me']", t["me"] )
print( "t['fred']", t["fred"] )
print( "me", me )
print( "fred", fred )
print( "t[me]", t[me] )
print( "t[fred]", t[fred] )
--]]
-- basic metatable setting
t = { 11, 22, 33, you='one', me='two' }
mt = { __index = print, __newindex = print }
setmetatable(t,mt)
a = t[11]
b = t.one
c = t[1]
d = t.you
t[4] = 'rat'
t[1] = 'pipe'
print( a, b, c, d )
for a,b in pairs(t) do
print( a, b )
end
-- delegate to actual metatable
s = { }
mt = { __newindex = s, __index = _G }
setmetatable(t, mt)
print( t.you )
x = 'wow'
print( t.x )
me = 'here'
print( t.me )
t[5] = 99
for a,b in pairs(s) do
print( a, b )
end

BIN
src/test/res/test6.luac Normal file

Binary file not shown.