diff core/src/luan/LuanTable.java @ 419:8fbb961aabd5

improve repr() to check metamethod recursively
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 30 Apr 2015 23:15:40 -0600
parents d2ab2240cc65
children af82b266fe89
line wrap: on
line diff
--- 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;