comparison 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
comparison
equal deleted inserted replaced
1577:60e5c324adf9 1578:c922446f53aa
8 import java.util.HashMap; 8 import java.util.HashMap;
9 import java.util.LinkedHashMap; 9 import java.util.LinkedHashMap;
10 import java.util.Iterator; 10 import java.util.Iterator;
11 import java.util.Arrays; 11 import java.util.Arrays;
12 import java.util.Set; 12 import java.util.Set;
13 import java.util.Collection;
13 import goodjava.logging.Logger; 14 import goodjava.logging.Logger;
14 import goodjava.logging.LoggerFactory; 15 import goodjava.logging.LoggerFactory;
15 import luan.modules.JavaLuan; 16 import luan.modules.JavaLuan;
16 import luan.modules.PackageLuan; 17 import luan.modules.PackageLuan;
17 import luan.modules.IoLuan; 18 import luan.modules.IoLuan;
18 import luan.modules.logging.LuanLogger; 19 import luan.modules.logging.LuanLogger;
19 import luan.impl.LuanCompiler; 20 import luan.impl.LuanCompiler;
20 21
21 22
22 public final class Luan implements LuanCloneable { 23 public final class Luan {
23 private static final Logger logger = LoggerFactory.getLogger(Luan.class); 24 private static final Logger logger = LoggerFactory.getLogger(Luan.class);
24 25
25 private final List<LuanClosure> stack = new ArrayList<LuanClosure>(); 26 private final List<LuanClosure> stack = new ArrayList<LuanClosure>();
26 private Map registry; 27 private final Map registry;
27 private boolean isLocked = false; 28 private final Map localOnly = new HashMap();
28 29
29 public Luan() { 30 public Luan() {
30 registry = new HashMap(); 31 registry = new HashMap();
31 } 32 }
32 33
33 private Luan(Luan luan) {} 34 public Luan(Luan luan) {
34 35 LuanMutable.makeImmutable(luan.registry);
35 @Override public Luan shallowClone() { 36 this.registry = clone(luan.registry);
36 return new Luan(this); 37 }
37 } 38
38 39 private static Object[] clone(Object[] obj) {
39 @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { 40 if( obj.length == 0 )
40 Luan clone = (Luan)dc; 41 return obj;
41 clone.registry = cloner.clone(registry); 42 Object[] rtn = obj.clone();
42 if( cloner.type == LuanCloner.Type.INCREMENTAL ) 43 for( int i=0; i<rtn.length; i++ ) {
43 isLocked = true; 44 rtn[i] = clone(rtn[i]);
44 } 45 }
45 46 return rtn;
46 @Override public void makeImmutable(LuanImmutabler immutabler) {} 47 }
48
49 private static Map clone(Map obj) {
50 Map rtn;
51 try {
52 rtn = obj.getClass().newInstance();
53 } catch(InstantiationException e) {
54 throw new RuntimeException(e);
55 } catch(IllegalAccessException e) {
56 throw new RuntimeException(e);
57 }
58 for( Object stupid : obj.entrySet() ) {
59 Map.Entry entry = (Map.Entry)stupid;
60 rtn.put( clone(entry.getKey()), clone(entry.getValue()) );
61 }
62 return rtn;
63 }
64
65 private static Collection clone(Collection obj) {
66 Collection rtn;
67 try {
68 rtn = obj.getClass().newInstance();
69 } catch(InstantiationException e) {
70 throw new RuntimeException(e);
71 } catch(IllegalAccessException e) {
72 throw new RuntimeException(e);
73 }
74 for( Object entry : (Collection)obj ) {
75 rtn.add( clone(entry) );
76 }
77 return rtn;
78 }
79
80 private static Object clone(Object obj) {
81 if( obj instanceof Object[] )
82 return clone((Object[])obj);
83 if( obj instanceof Map )
84 return clone((Map)obj);
85 if( obj instanceof Collection )
86 return clone((Collection)obj);
87 return obj;
88 }
89
90 private Map clonedLocals(Object obj) {
91 Map locals = (Map)registry.get("Luan.local");
92 if( locals==null ) {
93 locals = new HashMap();
94 registry.put("Luan.local",locals);
95 }
96 Map local = (Map)locals.get(obj);
97 if( local==null ) {
98 local = new HashMap();
99 locals.put(obj,local);
100 }
101 return local;
102 }
103
104 public Object getLocalCloned(Object obj,Object key) {
105 return clonedLocals(obj).get(key);
106 }
107
108 public void setLocalCloned(Object obj,Object key,Object value) {
109 if( value==null )
110 clonedLocals(obj).remove(key);
111 else
112 clonedLocals(obj).put(key,value);
113 }
114
115 private Map onlyLocals(Object obj) {
116 Map local = (Map)localOnly.get(obj);
117 if( local==null ) {
118 local = new HashMap();
119 localOnly.put(obj,local);
120 }
121 return local;
122 }
123
124 public Object getLocalOnly(Object obj,Object key) {
125 return onlyLocals(obj).get(key);
126 }
127
128 public void setLocalOnly(Object obj,Object key,Object value) {
129 if( value==null )
130 onlyLocals(obj).remove(key);
131 else
132 onlyLocals(obj).put(key,value);
133 }
47 134
48 public LuanClosure peek() { 135 public LuanClosure peek() {
49 return peek(1); 136 return peek(1);
50 } 137 }
51 138
53 int n = stack.size(); 140 int n = stack.size();
54 return n < i ? null : stack.get(n-i); 141 return n < i ? null : stack.get(n-i);
55 } 142 }
56 143
57 void push(LuanClosure closure) { 144 void push(LuanClosure closure) {
58 if( isLocked )
59 throw new RuntimeException(this+" is locked "+closure);
60 stack.add(closure); 145 stack.add(closure);
61 } 146 }
62 147
63 void pop() { 148 void pop() {
64 stack.remove(stack.size()-1); 149 stack.remove(stack.size()-1);
116 if( fn != null ) 201 if( fn != null )
117 return Luan.checkBoolean( Luan.first(fn.call(this,o1,o2)) ); 202 return Luan.checkBoolean( Luan.first(fn.call(this,o1,o2)) );
118 throw new LuanException( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) ); 203 throw new LuanException( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
119 } 204 }
120 205
121 public static LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException { 206 public LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException {
122 if( o1 instanceof LuanTable ) { 207 if( o1 instanceof LuanTable ) {
123 LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1); 208 LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1);
124 if( f1 != null ) 209 if( f1 != null )
125 return f1; 210 return f1;
126 } 211 }
127 return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null; 212 return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null;
128 } 213 }
129 214
130 public static LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { 215 public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException {
131 Object f = t.getHandler(op); 216 Object f = t.getHandler(this,op);
132 if( f == null ) 217 if( f == null )
133 return null; 218 return null;
134 return Luan.checkFunction(f); 219 return Luan.checkFunction(f);
135 } 220 }
136 221