Add __metatable and __tostring metatags.

This commit is contained in:
James Roseborough
2010-08-18 22:45:41 +00:00
parent 4acf8ed2ce
commit 2066e41ecd
4 changed files with 108 additions and 87 deletions

View File

@@ -120,14 +120,10 @@ public class LuaTable extends LuaValue {
}
public LuaValue getmetatable() {
if ( m_metatable!=null )
return m_metatable.rawget(METATABLE).optvalue(m_metatable);
return m_metatable;
}
public LuaValue setmetatable(LuaValue metatable) {
if ( m_metatable!=null && !m_metatable.rawget(METATABLE).isnil() )
error("cannot change a protected metatable");
m_metatable = metatable;
LuaValue mode;
if ( m_metatable!=null && (mode=m_metatable.rawget(MODE)).isstring() ) {

View File

@@ -77,6 +77,7 @@ public class LuaValue extends Varargs {
public static final LuaString EQ = valueOf("__eq");
public static final LuaString LT = valueOf("__lt");
public static final LuaString LE = valueOf("__le");
public static final LuaString TOSTRING = valueOf("__tostring");
public static final LuaString EMPTYSTRING = valueOf("");
private static int MAXSTACK = 250;

View File

@@ -204,7 +204,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
case 3: // "getmetatable", // ( object ) -> table
{
LuaValue mt = args.checkvalue(1).getmetatable();
return mt!=null? mt: NIL;
return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL;
}
case 4: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
{
@@ -294,12 +294,19 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
case 16: { // "setmetatable", // (table, metatable) -> table
final LuaValue t = args.arg1();
final LuaValue mt0 = t.getmetatable();
if ( mt0!=null && !mt0.rawget(METATABLE).isnil() )
error("cannot change a protected metatable");
final LuaValue mt = args.checkvalue(2);
return t.setmetatable(mt.isnil()? null: mt.checktable());
}
case 17: { // "tostring", // (e) -> value
LuaValue arg = args.checkvalue(1);
return arg.type() == LuaValue.TSTRING? arg: valueOf(arg.tojstring());
LuaValue h = arg.metatag(TOSTRING);
if ( ! h.isnil() ) return h.call(arg);
LuaValue v = arg.tostring();
if ( ! v.isnil() ) return v;
return valueOf(arg.tojstring());
}
case 18: { // "tonumber", // (e [,base]) -> value
LuaValue arg1 = args.checkvalue(1);