Mercurial Hosting > luan
diff src/luan/Luan.java @ 1578:c922446f53aa
immutable threading
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 08 Feb 2021 14:16:19 -0700 |
parents | 8fbcc4747091 |
children | 2975c932864d |
line wrap: on
line diff
--- a/src/luan/Luan.java Sun Jan 31 16:04:39 2021 -0700 +++ b/src/luan/Luan.java Mon Feb 08 14:16:19 2021 -0700 @@ -10,6 +10,7 @@ import java.util.Iterator; import java.util.Arrays; import java.util.Set; +import java.util.Collection; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; import luan.modules.JavaLuan; @@ -19,31 +20,117 @@ import luan.impl.LuanCompiler; -public final class Luan implements LuanCloneable { +public final class Luan { private static final Logger logger = LoggerFactory.getLogger(Luan.class); private final List<LuanClosure> stack = new ArrayList<LuanClosure>(); - private Map registry; - private boolean isLocked = false; + private final Map registry; + private final Map localOnly = new HashMap(); public Luan() { registry = new HashMap(); } - private Luan(Luan luan) {} + public Luan(Luan luan) { + LuanMutable.makeImmutable(luan.registry); + this.registry = clone(luan.registry); + } + + private static Object[] clone(Object[] obj) { + if( obj.length == 0 ) + return obj; + Object[] rtn = obj.clone(); + for( int i=0; i<rtn.length; i++ ) { + rtn[i] = clone(rtn[i]); + } + return rtn; + } - @Override public Luan shallowClone() { - return new Luan(this); + private static Map clone(Map obj) { + Map rtn; + try { + rtn = obj.getClass().newInstance(); + } catch(InstantiationException e) { + throw new RuntimeException(e); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } + for( Object stupid : obj.entrySet() ) { + Map.Entry entry = (Map.Entry)stupid; + rtn.put( clone(entry.getKey()), clone(entry.getValue()) ); + } + return rtn; + } + + private static Collection clone(Collection obj) { + Collection rtn; + try { + rtn = obj.getClass().newInstance(); + } catch(InstantiationException e) { + throw new RuntimeException(e); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } + for( Object entry : (Collection)obj ) { + rtn.add( clone(entry) ); + } + return rtn; } - @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { - Luan clone = (Luan)dc; - clone.registry = cloner.clone(registry); - if( cloner.type == LuanCloner.Type.INCREMENTAL ) - isLocked = true; + private static Object clone(Object obj) { + if( obj instanceof Object[] ) + return clone((Object[])obj); + if( obj instanceof Map ) + return clone((Map)obj); + if( obj instanceof Collection ) + return clone((Collection)obj); + return obj; + } + + private Map clonedLocals(Object obj) { + Map locals = (Map)registry.get("Luan.local"); + if( locals==null ) { + locals = new HashMap(); + registry.put("Luan.local",locals); + } + Map local = (Map)locals.get(obj); + if( local==null ) { + local = new HashMap(); + locals.put(obj,local); + } + return local; } - @Override public void makeImmutable(LuanImmutabler immutabler) {} + public Object getLocalCloned(Object obj,Object key) { + return clonedLocals(obj).get(key); + } + + public void setLocalCloned(Object obj,Object key,Object value) { + if( value==null ) + clonedLocals(obj).remove(key); + else + clonedLocals(obj).put(key,value); + } + + private Map onlyLocals(Object obj) { + Map local = (Map)localOnly.get(obj); + if( local==null ) { + local = new HashMap(); + localOnly.put(obj,local); + } + return local; + } + + public Object getLocalOnly(Object obj,Object key) { + return onlyLocals(obj).get(key); + } + + public void setLocalOnly(Object obj,Object key,Object value) { + if( value==null ) + onlyLocals(obj).remove(key); + else + onlyLocals(obj).put(key,value); + } public LuanClosure peek() { return peek(1); @@ -55,8 +142,6 @@ } void push(LuanClosure closure) { - if( isLocked ) - throw new RuntimeException(this+" is locked "+closure); stack.add(closure); } @@ -118,7 +203,7 @@ throw new LuanException( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) ); } - public static LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException { + public LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException { if( o1 instanceof LuanTable ) { LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1); if( f1 != null ) @@ -127,8 +212,8 @@ return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null; } - public static LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { - Object f = t.getHandler(op); + public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { + Object f = t.getHandler(this,op); if( f == null ) return null; return Luan.checkFunction(f);