Implement most of metatables
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
package lua;
|
package lua;
|
||||||
|
|
||||||
import lua.value.LFunction;
|
import lua.value.LFunction;
|
||||||
import lua.value.LNil;
|
|
||||||
import lua.value.LString;
|
import lua.value.LString;
|
||||||
import lua.value.LTable;
|
import lua.value.LTable;
|
||||||
import lua.value.LValue;
|
import lua.value.LValue;
|
||||||
@@ -13,7 +12,7 @@ final class Builtin extends LFunction {
|
|||||||
|
|
||||||
static void addBuiltins(LTable table) {
|
static void addBuiltins(LTable table) {
|
||||||
for ( int i=0; i<NAMES.length; i++ )
|
for ( int i=0; i<NAMES.length; i++ )
|
||||||
table.luaSetTable( new LString( NAMES[i] ), new Builtin(i) );
|
table.m_hash.put( new LString( NAMES[i] ), new Builtin(i) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int PRINT = 0;
|
private static final int PRINT = 0;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package lua;
|
|||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import lua.value.LString;
|
||||||
import lua.value.LTable;
|
import lua.value.LTable;
|
||||||
import lua.value.LValue;
|
import lua.value.LValue;
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ public class GlobalState {
|
|||||||
public static LValue getGlobalsTable() {
|
public static LValue getGlobalsTable() {
|
||||||
LTable table = new LTable();
|
LTable table = new LTable();
|
||||||
Builtin.addBuiltins( table );
|
Builtin.addBuiltins( table );
|
||||||
|
table.m_hash.put(new LString("_G"), table);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,28 @@
|
|||||||
package lua.value;
|
package lua.value;
|
||||||
|
|
||||||
|
import lua.StackState;
|
||||||
|
|
||||||
public class LFunction extends LValue {
|
public class LFunction extends LValue {
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "function: "+hashCode();
|
return "function: "+hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void luaSetTable(StackState state, int base, LValue table, LValue key, LValue val) {
|
||||||
|
state.top = base;
|
||||||
|
state.push( this );
|
||||||
|
state.push( table );
|
||||||
|
state.push( key );
|
||||||
|
state.push( val );
|
||||||
|
this.luaStackCall(state, base, state.top, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void luaGetTable(StackState state, int base, LValue table, LValue key) {
|
||||||
|
state.top = base;
|
||||||
|
state.push( this );
|
||||||
|
state.push( table );
|
||||||
|
state.push( key );
|
||||||
|
this.luaStackCall(state, base, state.top, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,14 @@ import lua.StackState;
|
|||||||
|
|
||||||
public class LTable extends LValue {
|
public class LTable extends LValue {
|
||||||
|
|
||||||
private Hashtable m_hash = new Hashtable();
|
/** Metatable tag for intercepting table gets */
|
||||||
private LValue m_metatable;
|
private static final LString TM_INDEX = new LString("__index");
|
||||||
|
|
||||||
|
/** Metatable tag for intercepting table sets */
|
||||||
|
private static final LString TM_NEWINDEX = new LString("__newindex");
|
||||||
|
|
||||||
|
public Hashtable m_hash = new Hashtable();
|
||||||
|
private LTable m_metatable;
|
||||||
|
|
||||||
public LTable() {
|
public LTable() {
|
||||||
}
|
}
|
||||||
@@ -16,13 +22,32 @@ public class LTable extends LValue {
|
|||||||
public LTable(int narray, int nhash) {
|
public LTable(int narray, int nhash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void luaSetTable(LValue key, LValue val) {
|
public void luaSetTable(StackState state, int base, LValue table, LValue key, LValue val) {
|
||||||
|
if ( m_metatable != null ) {
|
||||||
|
if ( ! m_hash.containsKey(key) ) {
|
||||||
|
LValue event = (LValue) m_metatable.m_hash.get( TM_NEWINDEX );
|
||||||
|
if ( event != null && event != LNil.NIL ) {
|
||||||
|
event.luaSetTable( state, base, table, key, val );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
m_hash.put( key, val );
|
m_hash.put( key, val );
|
||||||
}
|
}
|
||||||
|
|
||||||
public LValue luaGetTable(LValue key) {
|
public void luaGetTable(StackState state, int base, LValue table, LValue key) {
|
||||||
Object o = m_hash.get(key);
|
LValue val = (LValue) m_hash.get(key);
|
||||||
return (o!=null? (LValue)o: LNil.NIL);
|
if ( val == null || val == LNil.NIL ) {
|
||||||
|
if ( m_metatable != null ) {
|
||||||
|
LValue event = (LValue) m_metatable.m_hash.get( TM_INDEX );
|
||||||
|
if ( event != null && event != LNil.NIL ) {
|
||||||
|
event.luaGetTable( state, base, table, key );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = LNil.NIL;
|
||||||
|
}
|
||||||
|
state.stack[base] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String luaAsString() {
|
public String luaAsString() {
|
||||||
@@ -41,7 +66,7 @@ public class LTable extends LValue {
|
|||||||
|
|
||||||
/** Valid for tables */
|
/** Valid for tables */
|
||||||
public void luaSetMetatable(LValue metatable) {
|
public void luaSetMetatable(LValue metatable) {
|
||||||
this.m_metatable = metatable;
|
this.m_metatable = (LTable) metatable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Valid for tables */
|
/** Valid for tables */
|
||||||
@@ -64,8 +89,9 @@ public class LTable extends LValue {
|
|||||||
public void luaStackCall(StackState state, int base, int top, int nresults) {
|
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();
|
||||||
|
LValue val = (LValue) t.m_hash.get(key);
|
||||||
state.stack[base] = key;
|
state.stack[base] = key;
|
||||||
state.stack[base+1] = t.luaGetTable(key);
|
state.stack[base+1] = val;
|
||||||
state.top = base+2;
|
state.top = base+2;
|
||||||
} else {
|
} else {
|
||||||
state.stack[base] = LNil.NIL;
|
state.stack[base] = LNil.NIL;
|
||||||
|
|||||||
@@ -68,14 +68,21 @@ public class LValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** set a value in a table
|
/** set a value in a table
|
||||||
|
* @param state the stack state
|
||||||
|
* @param base the base of the stack, in case a function is put on the stack
|
||||||
|
* @param table the table to operate on
|
||||||
|
* @param the key to set
|
||||||
|
* @param the value to set
|
||||||
*/
|
*/
|
||||||
public void luaSetTable(LValue key, LValue value) {
|
public void luaSetTable(StackState state, int base, LValue table, LValue key, LValue val) {
|
||||||
luaUnsupportedOperation();
|
luaUnsupportedOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a value from a table */
|
/** Get a value from a table
|
||||||
public LValue luaGetTable(LValue value) {
|
* @param base TODO
|
||||||
return luaUnsupportedOperation();
|
* @param table TODO*/
|
||||||
|
public void luaGetTable(StackState state, int base, LValue table, LValue key) {
|
||||||
|
luaUnsupportedOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the value as a String
|
/** Get the value as a String
|
||||||
@@ -121,5 +128,4 @@ public class LValue {
|
|||||||
luaUnsupportedOperation();
|
luaUnsupportedOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
t = { 11, 22, 33, you='one', me='two' }
|
t = { 11, 22, 33, you='one', me='two' }
|
||||||
--[[
|
|
||||||
for a,b in pairs(t) do
|
for a,b in pairs(t) do
|
||||||
print( a, b )
|
print( a, b )
|
||||||
end
|
end
|
||||||
@@ -12,7 +12,6 @@ print( "me", me )
|
|||||||
print( "fred", fred )
|
print( "fred", fred )
|
||||||
print( "t[me]", t[me] )
|
print( "t[me]", t[me] )
|
||||||
print( "t[fred]", t[fred] )
|
print( "t[fred]", t[fred] )
|
||||||
--]]
|
|
||||||
|
|
||||||
-- basic metatable setting
|
-- basic metatable setting
|
||||||
t = { 11, 22, 33, you='one', me='two' }
|
t = { 11, 22, 33, you='one', me='two' }
|
||||||
|
|||||||
Reference in New Issue
Block a user