diff core/src/luan/LuanTableImpl.java @ 406:9321a33b9b1c

remove AbstractLuanTable
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 29 Apr 2015 11:24:00 -0600
parents 5e0acdeaea93
children
line wrap: on
line diff
--- a/core/src/luan/LuanTableImpl.java	Wed Apr 29 11:10:11 2015 -0600
+++ b/core/src/luan/LuanTableImpl.java	Wed Apr 29 11:24:00 2015 -0600
@@ -4,6 +4,7 @@
 import java.util.ListIterator;
 import java.util.Map;
 import java.util.AbstractMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -14,7 +15,7 @@
 import java.util.regex.Pattern;
 
 
-class LuanTableImpl extends AbstractLuanTable implements LuanTable, DeepCloneable<LuanTableImpl> {
+class LuanTableImpl implements LuanTable, LuanRepr, DeepCloneable<LuanTableImpl> {
 	private Map<Object,Object> map = null;
 	private List<Object> list = null;
 	private LuanTable metatable = null;
@@ -81,7 +82,7 @@
 		return list!=null ? list : Collections.emptyList();
 	}
 
-	@Override protected Map<Object,Object> map() {
+	protected Map<Object,Object> map() {
 		return map!=null ? map : Collections.emptyMap();
 	}
 /*
@@ -111,7 +112,7 @@
 		return rtn;
 	}
 */
-	@Override protected String type() {
+	protected String type() {
 		return "table";
 	}
 
@@ -290,4 +291,98 @@
 	@Override public void setJava() {
 		hasJava = true;
 	}
+
+
+	// from AbstractLuanTable
+
+	protected final Map<Object,Object> newMap() {
+		return new LinkedHashMap<Object,Object>();
+	}
+
+	@Override public boolean isEmpty() {
+		return isList() && length()==0;
+	}
+
+	@Override public boolean isSet() {
+		for( Map.Entry<Object,Object> entry : this ) {
+			if( !entry.getValue().equals(Boolean.TRUE) )
+				return false;
+		}
+		return true;
+	}
+
+	@Override public Set<Object> asSet() {
+		Set<Object> set = new HashSet<Object>();
+		for( Map.Entry<Object,Object> entry : this ) {
+			set.add(entry.getKey());
+		}
+		return set;
+	}
+
+	@Override public Map<Object,Object> asMap() {
+		Map<Object,Object> map = newMap();
+		for( Map.Entry<Object,Object> entry : this ) {
+			map.put(entry.getKey(),entry.getValue());
+		}
+		return map;
+	}
+
+	@Override public LuanTable cloneTable() {
+		return isList() ? new LuanTableImpl(new ArrayList<Object>(asList())) : new LuanTableImpl(asMap());
+	}
+
+	@Override public String repr() {
+		return repr( Collections.newSetFromMap(new IdentityHashMap<LuanTableImpl,Boolean>()) );
+	}
+
+	private String repr(Set<LuanTableImpl> set) {
+		if( !set.add(this) ) {
+			return "\"<circular reference>\"";
+		}
+		StringBuilder sb = new StringBuilder();
+		sb.append('{');
+		boolean isFirst = true;
+		for( Object obj : asList() ) {
+			if( isFirst ) {
+				isFirst = false;
+			} else {
+				sb.append(", ");
+			}
+			sb.append(repr(set,obj));
+		}
+		for( Map.Entry<Object,Object> entry : map().entrySet() ) {
+			if( isFirst ) {
+				isFirst = false;
+			} else {
+				sb.append(", ");
+			}
+			sb.append(reprKey(set,entry.getKey())).append('=').append(repr(set,entry.getValue()));
+		}
+		sb.append('}');
+		return sb.toString();
+	}
+
+	private static final Pattern namePtn = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*");
+
+	private String reprKey(Set<LuanTableImpl> set,Object obj) {
+		if( obj instanceof String ) {
+			String s = (String)obj;
+			if( namePtn.matcher(s).matches() )
+				return s;
+		}
+		return "[" + repr(set,obj) + "]";
+	}
+
+	String repr(Set<LuanTableImpl> set,Object obj) {
+		if( obj instanceof LuanTableImpl ) {
+			LuanTableImpl t = (LuanTableImpl)obj;
+			return t.repr(set);
+		} else {
+			String s = Luan.repr(obj);
+			if( s == null )
+				s = "<couldn't repr: " + Luan.stringEncode(Luan.toString(obj)) + ">";
+			return s;
+		}
+	}
+
 }