Mercurial Hosting > luan
diff src/luan/LuanTable.java @ 1578:c922446f53aa
immutable threading
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 08 Feb 2021 14:16:19 -0700 |
parents | 364859d29ff5 |
children | fa066aaa068c |
line wrap: on
line diff
--- a/src/luan/LuanTable.java Sun Jan 31 16:04:39 2021 -0700 +++ b/src/luan/LuanTable.java Mon Feb 08 14:16:19 2021 -0700 @@ -13,14 +13,12 @@ import java.util.HashSet; -public final class LuanTable implements LuanCloneable { +public final class LuanTable implements LuanMutable { private Map map = null; private List list = null; private LuanTable metatable = null; public LuanClosure closure; - private LuanCloner cloner; private boolean immutable = false; - private Luan luan; public LuanTable() {} @@ -71,59 +69,23 @@ this.metatable = tbl.metatable; } - @Override public LuanTable shallowClone() { - if(immutable) throw new RuntimeException(); - return new LuanTable(); - } - - @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { - check(); - LuanTable clone = (LuanTable)dc; - switch( cloner.type ) { - case COMPLETE: - completeClone(clone,cloner); - return; - case INCREMENTAL: - clone.cloner = cloner; - clone.map = map; - clone.list = list; - clone.metatable = metatable; - clone.closure = closure; - return; - } + @Override public boolean isImmutable() { + return immutable; } - private void check() { - if( cloner != null ) { - completeClone(this,cloner); - cloner = null; - } - } - - private void checkLuan(Luan luan) { - check(); - if( this.luan==null ) { - this.luan = luan; - } else if( this.luan != luan ) { - throw new RuntimeException("wrong luan"); - } + @Override public void makeImmutable() { + if(immutable) + return; + immutable = true; + LuanMutable.makeImmutable(map); + LuanMutable.makeImmutable(list); + LuanMutable.makeImmutable(metatable); + LuanMutable.makeImmutable(closure); } - private void completeClone(LuanTable clone,LuanCloner cloner) { - clone.map = cloner.clone(map); - clone.list = (List)cloner.clone(list); - clone.metatable = (LuanTable)cloner.clone(metatable); - clone.closure = (LuanClosure)cloner.clone(closure); - clone.luan = (Luan)cloner.clone(luan); - } - - @Override public void makeImmutable(LuanImmutabler immutabler) throws LuanException { - check(); - immutabler.makeImmutable(map); - immutabler.makeImmutable(list); - immutabler.makeImmutable(metatable); - immutabler.makeImmutable(closure); - immutable = true; + private void checkMutable() throws LuanException { + if( immutable ) + throw new LuanException("table is immutable"); } public boolean isList() { @@ -135,17 +97,15 @@ } public List<Object> asList() { - check(); return list!=null ? list : Collections.emptyList(); } public Map rawMap() { - check(); return map!=null ? map : Collections.emptyMap(); } public String toStringLuan(Luan luan) throws LuanException { - Object h = getHandler("__to_string"); + Object h = getHandler(luan,"__to_string"); if( h == null ) return rawToString(); LuanFunction fn = Luan.checkFunction(h); @@ -161,7 +121,7 @@ Object value = rawGet(key); if( value != null ) return value; - Object h = getHandler("__index"); + Object h = getHandler(luan,"__index"); if( h==null ) return null; if( h instanceof LuanFunction ) { @@ -172,7 +132,6 @@ } public Object rawGet(Object key) { - check(); if( list != null ) { Integer iT = Luan.asInteger(key); if( iT != null ) { @@ -192,7 +151,7 @@ public void put(Luan luan,Object key,Object value) throws LuanException { //checkLuan(luan); - Object h = getHandler("__new_index"); + Object h = getHandler(luan,"__new_index"); if( h==null || rawGet(key)!=null ) { rawPut(key,value); return; @@ -211,9 +170,7 @@ } public Object rawPut(Object key,Object val) throws LuanException { - if( immutable ) - throw new LuanException("table is immutable"); - check(); + checkMutable(); if( key==null ) throw new LuanException("table index is nil"); Integer iT = Luan.asInteger(key); @@ -284,34 +241,34 @@ return list; } - public void rawInsert(int pos,Object value) { - check(); + public void rawInsert(int pos,Object value) throws LuanException { + checkMutable(); if( value==null ) throw new IllegalArgumentException("can't insert a nil value"); list().add(pos-1,value); mapToList(); } - public void rawAdd(Object value) { - check(); + public void rawAdd(Object value) throws LuanException { + checkMutable(); if( value==null ) throw new IllegalArgumentException("can't insert a nil value"); list().add(value); mapToList(); } - public Object removeFromList(int pos) { - check(); + public Object removeFromList(int pos) throws LuanException { + checkMutable(); return list().remove(pos-1); } - public void rawSort(Comparator<Object> cmp) { - check(); + public void rawSort(Comparator<Object> cmp) throws LuanException { + checkMutable(); Collections.sort(list(),cmp); } public int length(Luan luan) throws LuanException { - Object h = getHandler("__len"); + Object h = getHandler(luan,"__len"); if( h != null ) { LuanFunction fn = Luan.checkFunction(h); return (Integer)Luan.first(fn.call(luan,this)); @@ -320,7 +277,6 @@ } public int rawLength() { - check(); return list==null ? 0 : list.size(); } @@ -343,7 +299,7 @@ } public Iterator<Map.Entry> iterator(final Luan luan) throws LuanException { - if( getHandler("__pairs") == null ) + if( getHandler(luan,"__pairs") == null ) return rawIterator(); final LuanFunction fn = pairs(luan); return new Iterator<Map.Entry>() { @@ -380,7 +336,7 @@ } public LuanFunction pairs(Luan luan) throws LuanException { - Object h = getHandler("__pairs"); + Object h = getHandler(luan,"__pairs"); if( h != null ) { if( h instanceof LuanFunction ) { LuanFunction fn = (LuanFunction)h; @@ -408,7 +364,6 @@ } public Iterator<Map.Entry> rawIterator() { - check(); if( list == null ) { if( map == null ) return Collections.<Map.Entry>emptyList().iterator(); @@ -462,25 +417,22 @@ } public LuanTable rawSubList(int from,int to) { - check(); LuanTable tbl = new LuanTable(); tbl.list = new ArrayList<Object>(list().subList(from-1,to-1)); return tbl; } public LuanTable getMetatable() { - check(); return metatable; } public void setMetatable(LuanTable metatable) throws LuanException { - check(); + checkMutable(); this.metatable = metatable; } - public Object getHandler(String op) throws LuanException { - check(); - return metatable==null ? null : metatable.rawGet(op); + public Object getHandler(Luan luan,String op) throws LuanException { + return metatable==null ? null : luan==null ? metatable.rawGet(op) : metatable.get(luan,op); } private static Map<Object,Object> newMap() { @@ -511,8 +463,8 @@ return map; } - public void rawClear() { - check(); + public void rawClear() throws LuanException { + checkMutable(); map = null; list = null; } @@ -540,15 +492,14 @@ } public Object remove(Object key) throws LuanException { - if( immutable ) - throw new LuanException("table is immutable"); + checkMutable(); Object old = rawGet(key); rawPut(key,null); return old; } protected void finalize() throws Throwable { - Object h = getHandler("__gc"); + Object h = getHandler(null,"__gc"); if( h != null ) { LuanFunction fn = Luan.checkFunction(h); fn.call(new Luan(),this); // ??? should be immutable