Mercurial Hosting > luan
changeset 502:d3183a330ff5
improve the __index metamethod to work with any type;
simplify luan_proxy to eliminate base;
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 19 May 2015 17:57:20 -0600 |
parents | f26485a3692c |
children | 92c3d22745b8 |
files | core/src/luan/LuanState.java core/src/luan/LuanTable.java core/src/luan/impl/IndexExpr.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/JavaLuan.java website/src/manual.html.luan |
diffstat | 6 files changed, 48 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
diff -r f26485a3692c -r d3183a330ff5 core/src/luan/LuanState.java --- a/core/src/luan/LuanState.java Mon May 18 23:23:01 2015 -0600 +++ b/core/src/luan/LuanState.java Tue May 19 17:57:20 2015 -0600 @@ -50,7 +50,7 @@ // convenience methods - private final LuanBit JAVA = bit(null); + final LuanBit JAVA = bit(null); public LuanException exception(Object msg) throws LuanException { return JAVA.exception(msg);
diff -r f26485a3692c -r d3183a330ff5 core/src/luan/LuanTable.java --- a/core/src/luan/LuanTable.java Mon May 18 23:23:01 2015 -0600 +++ b/core/src/luan/LuanTable.java Tue May 19 17:57:20 2015 -0600 @@ -13,6 +13,9 @@ import java.util.HashSet; import java.util.IdentityHashMap; import java.util.regex.Pattern; +import luan.modules.StringLuan; +import luan.modules.BinaryLuan; +import luan.modules.JavaLuan; public final class LuanTable implements DeepCloneable { @@ -120,11 +123,25 @@ LuanMeta meta = (LuanMeta)h; return meta.__index(luan,this,key); } - if( h instanceof LuanTable ) { - LuanTable tbl = (LuanTable)h; + return index(luan.JAVA,h,key); + } + + public static Object index(LuanBit bit,Object obj,Object key) throws LuanException { + LuanState luan = bit.luan; + if( obj instanceof LuanTable ) { + LuanTable tbl = (LuanTable)obj; return tbl.get(luan,key); } - throw luan.exception("invalid type "+Luan.type(h)+" for metamethod __index"); + if( obj instanceof String ) + return StringLuan.__index(luan,(String)obj,key); + if( obj instanceof byte[] ) + return BinaryLuan.__index(luan,(byte[])obj,key); + if( obj != null && luan.currentEnvironment().hasJava() ) + return JavaLuan.__index(luan,obj,key); + else if( bit.el==null ) + throw bit.exception( "attempt to index a " + Luan.type(obj) + " value" ); + else + throw bit.exception( "attempt to index '"+bit.el.text()+"' (a " + Luan.type(obj) + " value)" ); } public Object rawGet(Object key) {
diff -r f26485a3692c -r d3183a330ff5 core/src/luan/impl/IndexExpr.java --- a/core/src/luan/impl/IndexExpr.java Mon May 18 23:23:01 2015 -0600 +++ b/core/src/luan/impl/IndexExpr.java Tue May 19 17:57:20 2015 -0600 @@ -1,14 +1,8 @@ package luan.impl; -import luan.Luan; import luan.LuanException; import luan.LuanTable; -import luan.LuanFunction; import luan.LuanElement; -import luan.LuanMeta; -import luan.modules.StringLuan; -import luan.modules.BinaryLuan; -import luan.modules.JavaLuan; final class IndexExpr extends BinaryOpExpr { @@ -18,21 +12,7 @@ } @Override public Object eval(LuanStateImpl luan) throws LuanException { - return index(luan,op1.eval(luan),op2.eval(luan)); + return LuanTable.index( luan.bit(op1.el()), op1.eval(luan), op2.eval(luan) ); } - private Object index(LuanStateImpl luan,Object obj,Object key) throws LuanException { - if( obj instanceof LuanTable ) { - LuanTable tbl = (LuanTable)obj; - return tbl.get(luan,key); - } - if( obj instanceof String ) - return StringLuan.__index(luan,(String)obj,key); - if( obj instanceof byte[] ) - return BinaryLuan.__index(luan,(byte[])obj,key); - if( obj != null && luan.currentEnvironment().hasJava() ) - return JavaLuan.__index(luan,obj,key); - else - throw luan.bit(op1.el()).exception( "attempt to index '"+op1.el().text()+"' (a " + Luan.type(obj) + " value)" ); - } }
diff -r f26485a3692c -r d3183a330ff5 core/src/luan/modules/BasicLuan.java --- a/core/src/luan/modules/BasicLuan.java Mon May 18 23:23:01 2015 -0600 +++ b/core/src/luan/modules/BasicLuan.java Tue May 19 17:57:20 2015 -0600 @@ -64,7 +64,8 @@ }; } - public static Object get_metatable(LuanTable table) { + public static Object get_metatable(LuanState luan,LuanTable table) throws LuanException { + Utils.checkNotNull(luan,table); LuanTable metatable = table.getMetatable(); if( metatable == null ) return null; @@ -73,6 +74,7 @@ } public static void set_metatable(LuanState luan,LuanTable table,LuanTable metatable) throws LuanException { + Utils.checkNotNull(luan,table); if( table.getHandler("__metatable") != null ) throw luan.exception("cannot change a protected metatable"); table.setMetatable(metatable);
diff -r f26485a3692c -r d3183a330ff5 core/src/luan/modules/JavaLuan.java --- a/core/src/luan/modules/JavaLuan.java Mon May 18 23:23:01 2015 -0600 +++ b/core/src/luan/modules/JavaLuan.java Tue May 19 17:57:20 2015 -0600 @@ -307,7 +307,7 @@ return cls.isSynthetic(); } - public Object luan_proxy(final LuanState luan,final LuanTable t,final Object base) throws LuanException { + public Object luan_proxy(final LuanState luan,final LuanTable t) throws LuanException { return Proxy.newProxyInstance( cls.getClassLoader(), new Class[]{cls}, @@ -319,8 +319,8 @@ args = new Object[0]; String name = method.getName(); Object fnObj = t.get(luan,name); - if( fnObj==null && base!=null ) - return method.invoke(base,args); + if( fnObj == null ) + throw new NullPointerException("luan_proxy couldn't find method '"+name+"'"); LuanFunction fn = luan.checkFunction(fnObj); return Luan.first(luan.call(fn,name,args)); } @@ -331,7 +331,7 @@ private static final Method luan_proxyMethod; static { try { - luan_proxyMethod = Static.class.getMethod("luan_proxy",LuanState.class,LuanTable.class,Object.class); + luan_proxyMethod = Static.class.getMethod("luan_proxy",LuanState.class,LuanTable.class); luan_proxyMethod.setAccessible(true); } catch(NoSuchMethodException e) { throw new RuntimeException(e);
diff -r f26485a3692c -r d3183a330ff5 website/src/manual.html.luan --- a/website/src/manual.html.luan Mon May 18 23:23:01 2015 -0600 +++ b/website/src/manual.html.luan Tue May 19 17:57:20 2015 -0600 @@ -343,7 +343,7 @@ <ul> -<li><b>"add": </b> +<li><p><b>"add": </b> the <tt>+</tt> operation. If any operand for an addition is a table, @@ -360,49 +360,49 @@ it raises an error. </li> -<li><b>"sub": </b> +<li><p><b>"sub": </b> the <tt>-</tt> operation. Behavior similar to the "add" operation. </li> -<li><b>"mul": </b> +<li><p><b>"mul": </b> the <tt>*</tt> operation. Behavior similar to the "add" operation. </li> -<li><b>"div": </b> +<li><p><b>"div": </b> the <tt>/</tt> operation. Behavior similar to the "add" operation. </li> -<li><b>"mod": </b> +<li><p><b>"mod": </b> the <tt>%</tt> operation. Behavior similar to the "add" operation. </li> -<li><b>"pow": </b> +<li><p><b>"pow": </b> the <tt>^</tt> (exponentiation) operation. Behavior similar to the "add" operation. </li> -<li><b>"unm": </b> +<li><p><b>"unm": </b> the <tt>-</tt> (unary minus) operation. Behavior similar to the "add" operation. </li> -<li><b>"concat": </b> +<li><p><b>"concat": </b> the <tt>..</tt> (concatenation) operation. Behavior similar to the "add" operation. </li> -<li><b>"len": </b> +<li><p><b>"len": </b> the <tt>#</tt> (length) operation. If there is a metamethod, @@ -415,7 +415,7 @@ Otherwise, Luan raises an error. </li> -<li><b>"eq": </b> +<li><p><b>"eq": </b> the <tt>==</tt> (equal) operation. Behavior similar to the "add" operation, @@ -425,14 +425,14 @@ The result of the call is always converted to a boolean. </li> -<li><b>"lt": </b> +<li><p><b>"lt": </b> the <tt><</tt> (less than) operation. Behavior similar to the "add" operation. The result of the call is always converted to a boolean. </li> -<li><b>"le": </b> +<li><p><b>"le": </b> the <tt><=</tt> (less equal) operation. Unlike other operations, @@ -446,7 +446,7 @@ the result is always a boolean. </li> -<li><b>"index": </b> +<li><p><b>"index": </b> The indexing access <tt>table[key]</tt>. This event happens @@ -456,16 +456,16 @@ <p> Despite the name, -the metamethod for this event can be either a function or a table. +the metamethod for this event can be any type. If it is a function, it is called with <tt>table</tt> and <tt>key</tt> as arguments. -If it is a table, -the final result is the result of indexing this table with <tt>key</tt>. +Otherwise +the final result is the result of indexing this metamethod object with <tt>key</tt>. (This indexing is regular, not raw, -and therefore can trigger another metamethod.) +and therefore can trigger another metamethod if the metamethod object is a table.) </li> -<li><b>"new_index": </b> +<li><p><b>"new_index": </b> The indexing assignment <tt>table[key] = value</tt>. Like the index event, @@ -493,7 +493,7 @@ to do the assignment.) </li> -<li><b>"call": </b> +<li><p><b>"call": </b> The call operation <tt>func(args)</tt>. This event happens when Luan tries to call a table.