Mercurial Hosting > luan
changeset 419:8fbb961aabd5
improve repr() to check metamethod recursively
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 30 Apr 2015 23:15:40 -0600 |
parents | 455784e2227d |
children | e9d4d5854e54 |
files | core/src/luan/Luan.java core/src/luan/LuanBit.java core/src/luan/LuanFunction.java core/src/luan/LuanRepr.java core/src/luan/LuanState.java core/src/luan/LuanTable.java core/src/luan/impl/FnCall.java core/src/luan/impl/IndexExpr.java core/src/luan/impl/SetTableEntry.java core/src/luan/modules/BasicLuan.java |
diffstat | 10 files changed, 40 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/Luan.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/Luan.java Thu Apr 30 23:15:40 2015 -0600 @@ -135,19 +135,5 @@ return s; } - public static String repr(Object obj) { - if( obj == null ) - return "nil"; - if( obj instanceof Boolean ) - return Luan.toString((Boolean)obj); - if( obj instanceof Number ) - return Luan.toString((Number)obj); - if( obj instanceof String ) - return "\"" + stringEncode((String)obj) + "\""; - if( obj instanceof LuanRepr ) - return ((LuanRepr)obj).repr(); - return null; - } - private Luan() {} // never }
--- a/core/src/luan/LuanBit.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/LuanBit.java Thu Apr 30 23:15:40 2015 -0600 @@ -90,7 +90,7 @@ public String toString(Object obj) throws LuanException { if( obj instanceof LuanTable ) { LuanTable tbl = (LuanTable)obj; - Object h = luan.getHandler("__tostring",tbl); + Object h = tbl.getHandler("__tostring"); if( h instanceof LuanMeta ) { LuanMeta meta = (LuanMeta)h; return meta.__tostring(luan,tbl); @@ -103,19 +103,21 @@ } public String repr(Object obj) throws LuanException { - 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; + if( obj == null ) + return "nil"; + if( obj instanceof Boolean ) + return Luan.toString((Boolean)obj); + if( obj instanceof Number ) + return Luan.toString((Number)obj); + if( obj instanceof String ) + return "\"" + Luan.stringEncode((String)obj) + "\""; + if( obj instanceof LuanRepr ) + return ((LuanRepr)obj).repr(luan); + throw exception( "value '" + obj + "' doesn't support repr()" ); } public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { - Object f = luan.getHandler(op,t); + Object f = t.getHandler(op); if( f == null ) return null; return checkFunction(f);
--- a/core/src/luan/LuanFunction.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/LuanFunction.java Thu Apr 30 23:15:40 2015 -0600 @@ -8,10 +8,10 @@ public static final Object[] NOTHING = new Object[0]; @Override public String toString() { - return "function: " + Integer.toHexString(hashCode()); + return "function:" + Integer.toHexString(hashCode()); } - @Override public String repr() { + @Override public String repr(LuanState luan) { return "<" + toString() + ">"; }
--- a/core/src/luan/LuanRepr.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/LuanRepr.java Thu Apr 30 23:15:40 2015 -0600 @@ -2,5 +2,5 @@ public interface LuanRepr { - public String repr(); + public String repr(LuanState luan) throws LuanException; }
--- a/core/src/luan/LuanState.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/LuanState.java Thu Apr 30 23:15:40 2015 -0600 @@ -46,14 +46,9 @@ return new LuanBit(this,el); } - public final static Object getHandler(String op,LuanTable table) { - LuanTable t = table.getMetatable(); - return t==null ? null : t.get(op); - } - // convenience methods - private final LuanBit JAVA = bit(LuanElement.JAVA); + final LuanBit JAVA = bit(LuanElement.JAVA); public LuanException exception(Object msg) { return JAVA.exception(msg);
--- a/core/src/luan/LuanTable.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/LuanTable.java Thu Apr 30 23:15:40 2015 -0600 @@ -281,6 +281,11 @@ this.metatable = metatable; } + public Object getHandler(String op) { + LuanTable t = getMetatable(); + return t==null ? null : t.get(op); + } + public boolean hasJava() { return hasJava; } @@ -328,11 +333,14 @@ return isList() ? new LuanTable(new ArrayList<Object>(asList())) : new LuanTable(asMap()); } - @Override public String repr() { - return repr( Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); + @Override public String repr(LuanState luan) throws LuanException { + LuanFunction fn = luan.JAVA.getHandlerFunction("__repr",this); + if( fn != null ) + return luan.JAVA.checkString( Luan.first( luan.call(fn,"__repr",new Object[]{this}) ) ); + return repr( luan, Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); } - private String repr(Set<LuanTable> set) { + private String repr(LuanState luan,Set<LuanTable> set) throws LuanException { if( !set.add(this) ) { return "\"<circular reference>\""; } @@ -345,7 +353,7 @@ } else { sb.append(", "); } - sb.append(repr(set,obj)); + sb.append(repr(luan,set,obj)); } for( Map.Entry<Object,Object> entry : map().entrySet() ) { if( isFirst ) { @@ -353,7 +361,7 @@ } else { sb.append(", "); } - sb.append(reprKey(set,entry.getKey())).append('=').append(repr(set,entry.getValue())); + sb.append(reprKey(luan,set,entry.getKey())).append('=').append(repr(luan,set,entry.getValue())); } sb.append('}'); return sb.toString(); @@ -361,21 +369,21 @@ private static final Pattern namePtn = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*"); - private String reprKey(Set<LuanTable> set,Object obj) { + private String reprKey(LuanState luan,Set<LuanTable> set,Object obj) throws LuanException { if( obj instanceof String ) { String s = (String)obj; if( namePtn.matcher(s).matches() ) return s; } - return "[" + repr(set,obj) + "]"; + return "[" + repr(luan,set,obj) + "]"; } - private String repr(Set<LuanTable> set,Object obj) { + private String repr(LuanState luan,Set<LuanTable> set,Object obj) throws LuanException { if( obj instanceof LuanTable ) { LuanTable t = (LuanTable)obj; - return t.repr(set); + return t.repr(luan,set); } else { - String s = Luan.repr(obj); + String s = luan.repr(obj); if( s == null ) s = "<couldn't repr: " + Luan.stringEncode(Luan.toString(obj)) + ">"; return s;
--- a/core/src/luan/impl/FnCall.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/impl/FnCall.java Thu Apr 30 23:15:40 2015 -0600 @@ -29,7 +29,8 @@ return luan.bit(se).call( fn, fnName, Luan.array(args.eval(luan)) ); } if( o instanceof LuanTable ) { - Object h = luan.getHandler("__call",(LuanTable)o); + LuanTable t = (LuanTable)o; + Object h = t.getHandler("__call"); if( h != null ) return call(luan,h); }
--- a/core/src/luan/impl/IndexExpr.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/impl/IndexExpr.java Thu Apr 30 23:15:40 2015 -0600 @@ -27,7 +27,7 @@ Object value = tbl.get(key); if( value != null ) return value; - Object h = luan.getHandler("__index",tbl); + Object h = tbl.getHandler("__index"); if( h==null ) return null; if( h instanceof LuanFunction ) {
--- a/core/src/luan/impl/SetTableEntry.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/impl/SetTableEntry.java Thu Apr 30 23:15:40 2015 -0600 @@ -26,7 +26,7 @@ private void newindex(LuanStateImpl luan,Object t,Object key,Object value) throws LuanException { if( t instanceof LuanTable ) { LuanTable table = (LuanTable)t; - Object h = luan.getHandler("__newindex",table); + Object h = table.getHandler("__newindex"); if( h==null || table.get(key)!=null ) { try { table.put(key,value);
--- a/core/src/luan/modules/BasicLuan.java Thu Apr 30 21:52:20 2015 -0600 +++ b/core/src/luan/modules/BasicLuan.java Thu Apr 30 23:15:40 2015 -0600 @@ -50,7 +50,7 @@ public static LuanFunction pairs(LuanState luan,final LuanTable t) throws LuanException { Utils.checkNotNull(luan,t); - Object obj = luan.getHandler("__pairs",t); + Object obj = t.getHandler("__pairs"); if( obj != null ) { if( obj instanceof LuanFunction ) { obj = Luan.first(luan.call((LuanFunction)obj,"__pairs",new Object[]{t}));