Mercurial Hosting > luan
changeset 404:d55e873e1f0d
metatables now only apply to tables
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 29 Apr 2015 07:04:40 -0600 |
parents | 637f7ad85654 |
children | 3e68917a0dc6 |
files | core/src/luan/LuanBit.java core/src/luan/LuanState.java core/src/luan/impl/EqExpr.java core/src/luan/impl/FnCall.java core/src/luan/impl/IndexExpr.java core/src/luan/impl/LenExpr.java core/src/luan/impl/SetTableEntry.java core/src/luan/impl/UnmExpr.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/BinaryLuan.java core/src/luan/modules/JavaLuan.java core/src/luan/modules/StringLuan.java |
diffstat | 12 files changed, 103 insertions(+), 140 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/LuanBit.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/LuanBit.java Wed Apr 29 07:04:40 2015 -0600 @@ -88,34 +88,40 @@ } public String toString(Object obj) throws LuanException { - LuanFunction fn = getHandlerFunction("__tostring",obj); - if( fn != null ) - return checkString( Luan.first( call(fn,"__tostring",new Object[]{obj}) ) ); + if( obj instanceof LuanTable ) { + LuanFunction fn = getHandlerFunction("__tostring",(LuanTable)obj); + if( fn != null ) + return checkString( Luan.first( call(fn,"__tostring",new Object[]{obj}) ) ); + } return Luan.toString(obj); } public String repr(Object obj) throws LuanException { - LuanFunction fn = getHandlerFunction("__repr",obj); - if( fn != null ) - return checkString( Luan.first( call(fn,"__repr",new Object[]{obj}) ) ); + if( obj instanceof LuanTable ) { + LuanFunction fn = getHandlerFunction("__repr",(LuanTable)obj); + if( fn != null ) + return checkString( Luan.first( call(fn,"__repr",new Object[]{obj}) ) ); + } String repr = Luan.repr(obj); if( repr==null ) throw exception( "value '" + obj + "' doesn't support repr()" ); return repr; } - public LuanFunction getHandlerFunction(String op,Object obj) throws LuanException { - Object f = luan.getHandler(op,obj); + public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { + Object f = luan.getHandler(op,t); if( f == null ) return null; return checkFunction(f); } public LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException { - LuanFunction f1 = getHandlerFunction(op,o1); - if( f1 != null ) - return f1; - return getHandlerFunction(op,o2); + if( o1 instanceof LuanTable ) { + LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1); + if( f1 != null ) + return f1; + } + return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null; } public boolean isLessThan(Object o1,Object o2) throws LuanException {
--- a/core/src/luan/LuanState.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/LuanState.java Wed Apr 29 07:04:40 2015 -0600 @@ -21,18 +21,15 @@ final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); private LuanTableImpl registry; - private LuanTableImpl metatable; // generic metatable protected LuanState() { registry = new LuanTableImpl(); - metatable = newMetatable(); } protected LuanState(LuanState luan) {} @Override public void deepenClone(LuanState clone,DeepCloner cloner) { clone.registry = cloner.deepClone(registry); - clone.metatable = cloner.deepClone(metatable); } public abstract LuanTable currentEnvironment(); @@ -59,63 +56,15 @@ return call(fn); } - public final LuanTable getMetatable(Object obj) { - if( obj==null ) - return null; - if( obj instanceof LuanTable ) { - LuanTable table = (LuanTable)obj; - return table.getMetatable(); - } - return metatable; - } - public final LuanBit bit(LuanElement el) { return new LuanBit(this,el); } - public final Object getHandler(String op,Object obj) { - LuanTable t = getMetatable(obj); - return t==null ? null : t.get(op); - } - - public final Object getHandler(String op,LuanTable table) { + public final static Object getHandler(String op,LuanTable table) { LuanTable t = table.getMetatable(); return t==null ? null : t.get(op); } - private static LuanTableImpl newMetatable() { - LuanTableImpl metatable = new LuanTableImpl(); - try { - metatable.put( "__index", new LuanJavaFunction( - LuanState.class.getMethod("__index",LuanState.class,Object.class,Object.class), null - ) ); - metatable.put( "__newindex", new LuanJavaFunction( - LuanState.class.getMethod("__newindex",LuanState.class,Object.class,Object.class,Object.class), null - ) ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); - } - return metatable; - } - - public static Object __index(LuanState luan,Object obj,Object key) throws LuanException { - if( obj instanceof String ) { - Object rtn = StringLuan.__index(luan,(String)obj,key); - if( rtn != null ) - return rtn; - } - if( obj instanceof byte[] ) { - Object rtn = BinaryLuan.__index(luan,(byte[])obj,key); - if( rtn != null ) - return rtn; - } - return JavaLuan.__index(luan,obj,key); - } - - public static void __newindex(LuanState luan,Object obj,Object key,Object value) throws LuanException { - JavaLuan.__newindex(luan,obj,key,value); - } - // convenience methods private final LuanBit JAVA = bit(LuanElement.JAVA);
--- a/core/src/luan/impl/EqExpr.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/EqExpr.java Wed Apr 29 07:04:40 2015 -0600 @@ -34,10 +34,12 @@ byte[] b2 = (byte[])o2; return Arrays.equals(b1,b2); } - if( o1==null || o2==null || !o1.getClass().equals(o2.getClass()) ) + if( !(o1 instanceof LuanTable && o2 instanceof LuanTable) ) return false; - LuanTable mt1 = luan.getMetatable(o1); - LuanTable mt2 = luan.getMetatable(o2); + LuanTable t1 = (LuanTable)o1; + LuanTable t2 = (LuanTable)o2; + LuanTable mt1 = t1.getMetatable(); + LuanTable mt2 = t2.getMetatable(); if( mt1==null || mt2==null ) return false; Object f = mt1.get("__eq");
--- a/core/src/luan/impl/FnCall.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/FnCall.java Wed Apr 29 07:04:40 2015 -0600 @@ -4,6 +4,7 @@ import luan.LuanFunction; import luan.LuanException; import luan.LuanSource; +import luan.LuanTable; final class FnCall extends CodeImpl implements Expressions { @@ -27,9 +28,11 @@ LuanFunction fn = (LuanFunction)o; return luan.bit(se).call( fn, fnName, Luan.array(args.eval(luan)) ); } - Object h = luan.getHandler("__call",o); - if( h != null ) - return call(luan,h); + if( o instanceof LuanTable ) { + Object h = luan.getHandler("__call",(LuanTable)o); + if( h != null ) + return call(luan,h); + } throw luan.bit(fnExpr.se()).exception( "attempt to call '"+fnExpr.se().text()+"' (a " + Luan.type(o) + " value)" ); }
--- a/core/src/luan/impl/IndexExpr.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/IndexExpr.java Wed Apr 29 07:04:40 2015 -0600 @@ -5,6 +5,9 @@ import luan.LuanTable; import luan.LuanFunction; import luan.LuanSource; +import luan.modules.StringLuan; +import luan.modules.BinaryLuan; +import luan.modules.JavaLuan; final class IndexExpr extends BinaryOpExpr { @@ -17,25 +20,28 @@ return index(luan,op1.eval(luan),op2.eval(luan)); } - private Object index(LuanStateImpl luan,Object t,Object key) throws LuanException { - Object h; - if( t instanceof LuanTable ) { - LuanTable tbl = (LuanTable)t; + private Object index(LuanStateImpl luan,Object obj,Object key) throws LuanException { + if( obj instanceof LuanTable ) { + LuanTable tbl = (LuanTable)obj; Object value = tbl.get(key); if( value != null ) return value; - h = luan.getHandler("__index",t); + Object h = luan.getHandler("__index",tbl); if( h==null ) return null; - } else { - h = luan.getHandler("__index",t); - if( h==null ) - throw luan.bit(op1.se()).exception( "attempt to index '"+op1.se().text()+"' (a " + Luan.type(t) + " value)" ); + if( h instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)h; + return Luan.first(luan.bit(se).call(fn,"__index",new Object[]{tbl,key})); + } + return index(luan,h,key); } - if( h instanceof LuanFunction ) { - LuanFunction fn = (LuanFunction)h; - return Luan.first(luan.bit(se).call(fn,"__index",new Object[]{t,key})); - } - return index(luan,h,key); + if( obj instanceof String ) + return StringLuan.__index(luan,(String)obj,key); + if( obj instanceof byte[] ) + return BinaryLuan.__index(luan,(byte[])obj,key); + Object value = JavaLuan.__index(luan,obj,key); + if( value != null ) + return value; + throw luan.bit(op1.se()).exception( "attempt to index '"+op1.se().text()+"' (a " + Luan.type(obj) + " value)" ); } }
--- a/core/src/luan/impl/LenExpr.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/LenExpr.java Wed Apr 29 07:04:40 2015 -0600 @@ -25,13 +25,12 @@ return a.length; } LuanBit bit = luan.bit(se); - LuanFunction fn = bit.getHandlerFunction("__len",o); + if( !(o instanceof LuanTable) ) + throw bit.exception( "attempt to get length of a " + Luan.type(o) + " value" ); + LuanTable t = (LuanTable)o; + LuanFunction fn = bit.getHandlerFunction("__len",t); if( fn != null ) return Luan.first(bit.call(fn,"__len",new Object[]{o})); - if( o instanceof LuanTable ) { - LuanTable t = (LuanTable)o; - return t.length(); - } - throw bit.exception( "attempt to get length of a " + Luan.type(o) + " value" ); + return t.length(); } }
--- a/core/src/luan/impl/SetTableEntry.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/SetTableEntry.java Wed Apr 29 07:04:40 2015 -0600 @@ -5,6 +5,7 @@ import luan.Luan; import luan.LuanFunction; import luan.LuanSource; +import luan.modules.JavaLuan; final class SetTableEntry extends CodeImpl implements Settable { @@ -22,10 +23,9 @@ } private void newindex(LuanStateImpl luan,Object t,Object key,Object value) throws LuanException { - Object h; if( t instanceof LuanTable ) { LuanTable table = (LuanTable)t; - h = luan.getHandler("__newindex",table); + Object h = luan.getHandler("__newindex",table); if( h==null || table.get(key)!=null ) { try { table.put(key,value); @@ -36,17 +36,15 @@ } return; } - } else { - h = luan.getHandler("__newindex",t); - if( h==null ) - throw luan.bit(se).exception( "attempt to index '"+tableExpr.se().text()+"' (a " + Luan.type(t) + " value)" ); + if( h instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)h; + luan.bit(se).call(fn,"__newindex",new Object[]{t,key,value}); + return; + } + newindex(luan,h,key,value); } - if( h instanceof LuanFunction ) { - LuanFunction fn = (LuanFunction)h; - luan.bit(se).call(fn,"__newindex",new Object[]{t,key,value}); - return; - } - newindex(luan,h,key,value); + if( !JavaLuan.__newindex(luan,t,key,value) ) + throw luan.bit(se).exception( "attempt to index '"+tableExpr.se().text()+"' (a " + Luan.type(t) + " value)" ); } }
--- a/core/src/luan/impl/UnmExpr.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/impl/UnmExpr.java Wed Apr 29 07:04:40 2015 -0600 @@ -5,6 +5,7 @@ import luan.LuanException; import luan.LuanSource; import luan.LuanBit; +import luan.LuanTable; // unary minus @@ -20,9 +21,11 @@ if( n != null ) return -n.doubleValue(); LuanBit bit = luan.bit(se); - LuanFunction fn = bit.getHandlerFunction("__unm",o); - if( fn != null ) { - return Luan.first(bit.call(fn,"__unm",new Object[]{o})); + if( o instanceof LuanTable ) { + LuanFunction fn = bit.getHandlerFunction("__unm",(LuanTable)o); + if( fn != null ) { + return Luan.first(bit.call(fn,"__unm",new Object[]{o})); + } } throw bit.exception("attempt to perform arithmetic on a "+Luan.type(o)+" value"); }
--- a/core/src/luan/modules/BasicLuan.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/modules/BasicLuan.java Wed Apr 29 07:04:40 2015 -0600 @@ -77,8 +77,8 @@ }; } - public static LuanTable get_metatable(LuanState luan,Object obj) { - return luan.getMetatable(obj); + public static LuanTable get_metatable(LuanTable table) { + return table.getMetatable(); } public static LuanTable set_metatable(LuanTable table,LuanTable metatable) {
--- a/core/src/luan/modules/BinaryLuan.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/modules/BinaryLuan.java Wed Apr 29 07:04:40 2015 -0600 @@ -11,20 +11,18 @@ public final class BinaryLuan { public static Object __index(LuanState luan,final byte[] binary,Object key) throws LuanException { - LuanTable mod = (LuanTable)PackageLuan.loaded(luan).get("luan:Binary"); - if( mod!=null ) { - Object obj = mod.get(key); - if( obj instanceof LuanFunction ) { - final LuanFunction fn = (LuanFunction)obj; - return new LuanFunction() { - @Override public Object call(LuanState luan,Object[] args) throws LuanException { - Object[] a = new Object[args.length+1]; - a[0] = binary; - System.arraycopy(args,0,a,1,args.length); - return fn.call(luan,a); - } - }; - } + LuanTable mod = (LuanTable)luan.require("luan:Binary"); + Object obj = mod.get(key); + if( obj instanceof LuanFunction ) { + final LuanFunction fn = (LuanFunction)obj; + return new LuanFunction() { + @Override public Object call(LuanState luan,Object[] args) throws LuanException { + Object[] a = new Object[args.length+1]; + a[0] = binary; + System.arraycopy(args,0,a,1,args.length); + return fn.call(luan,a); + } + }; } return null; }
--- a/core/src/luan/modules/JavaLuan.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/modules/JavaLuan.java Wed Apr 29 07:04:40 2015 -0600 @@ -143,8 +143,9 @@ } } - public static void __newindex(LuanState luan,Object obj,Object key,Object value) throws LuanException { - checkJava(luan); + public static boolean __newindex(LuanState luan,Object obj,Object key,Object value) throws LuanException { + if( !luan.currentEnvironment().hasJava() ) + return false; if( obj instanceof Static ) { if( key instanceof String ) { String name = (String)key; @@ -155,7 +156,7 @@ if( members.size() != 1 ) throw new RuntimeException("not field '"+name+"' of "+obj); setMember(obj,members,value); - return; + return true; } } throw luan.exception("invalid member '"+key+"' for: "+obj); @@ -165,7 +166,7 @@ Integer i = Luan.asInteger(key); if( i != null ) { Array.set(obj,i,value); - return; + return true; } throw luan.exception("invalid member '"+key+"' for java array: "+obj); } @@ -176,7 +177,7 @@ if( members.size() != 1 ) throw new RuntimeException("not field '"+name+"' of "+obj); setMember(obj,members,value); - return; + return true; } } throw luan.exception("invalid member '"+key+"' for java object: "+obj);
--- a/core/src/luan/modules/StringLuan.java Tue Apr 28 22:49:33 2015 -0600 +++ b/core/src/luan/modules/StringLuan.java Wed Apr 29 07:04:40 2015 -0600 @@ -15,20 +15,18 @@ public final class StringLuan { public static Object __index(LuanState luan,final String s,Object key) throws LuanException { - LuanTable mod = (LuanTable)PackageLuan.loaded(luan).get("luan:String"); - if( mod!=null ) { - Object obj = mod.get(key); - if( obj instanceof LuanFunction ) { - final LuanFunction fn = (LuanFunction)obj; - return new LuanFunction() { - @Override public Object call(LuanState luan,Object[] args) throws LuanException { - Object[] a = new Object[args.length+1]; - a[0] = s; - System.arraycopy(args,0,a,1,args.length); - return fn.call(luan,a); - } - }; - } + LuanTable mod = (LuanTable)luan.require("luan:String"); + Object obj = mod.get(key); + if( obj instanceof LuanFunction ) { + final LuanFunction fn = (LuanFunction)obj; + return new LuanFunction() { + @Override public Object call(LuanState luan,Object[] args) throws LuanException { + Object[] a = new Object[args.length+1]; + a[0] = s; + System.arraycopy(args,0,a,1,args.length); + return fn.call(luan,a); + } + }; } return null; }