Mercurial Hosting > luan
view core/src/luan/AbstractLuanTable.java @ 369:85bf9f0379aa
template statements no longer depend on 'Io' being defined
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 17 Apr 2015 06:25:38 -0600 |
parents | 1a464e090538 |
children | 5e0acdeaea93 |
line wrap: on
line source
package luan; import java.util.Iterator; import java.util.ListIterator; import java.util.Map; import java.util.LinkedHashMap; import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Set; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.regex.Pattern; public abstract class AbstractLuanTable implements LuanTable, LuanRepr { protected final Map<Object,Object> newMap() { return new LinkedHashMap<Object,Object>(); } @Override public boolean isEmpty() { return isList() && length()==0; } @Override public boolean isList() { return asList().size() == asMap().size(); } @Override public List<Object> asList() { return Collections.emptyList(); } @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; } // shouldn't include list protected Map<Object,Object> map() { return asMap(); } protected abstract String type(); @Override public final String toString() { return type() + ": " + Integer.toHexString(hashCode()); } @Override public void put(Object key,Object val) { throw new UnsupportedOperationException("can't put into a "+type()); } @Override public void insert(int pos,Object value) { throw new UnsupportedOperationException("can't insert into a "+type()); } @Override public void add(Object value) { throw new UnsupportedOperationException("can't add to a "+type()); } @Override public Object remove(int pos) { throw new UnsupportedOperationException("can't remove from a "+type()); } @Override public void sort(Comparator<Object> cmp) { } @Override public int length() { return 0; } @Override public LuanTable subList(int from,int to) { throw new UnsupportedOperationException("can't get a sub-list of a "+type()); } @Override public LuanTable getMetatable() { return null; } @Override public void setMetatable(LuanTable metatable) { throw new UnsupportedOperationException("can't set a metatable on a "+type()); } @Override public LuanTable cloneTable() { return isList() ? new LuanTableImpl(new ArrayList<Object>(asList())) : new LuanTableImpl(asMap()); } @Override public boolean hasJava() { throw new UnsupportedOperationException(); } @Override public void setJava() { throw new UnsupportedOperationException(); } @Override public String repr() { return repr( Collections.newSetFromMap(new IdentityHashMap<AbstractLuanTable,Boolean>()) ); } private String repr(Set<AbstractLuanTable> 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<AbstractLuanTable> 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<AbstractLuanTable> set,Object obj) { if( obj instanceof AbstractLuanTable ) { AbstractLuanTable t = (AbstractLuanTable)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; } } }