diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-06-29 16:03:25 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-06-29 16:03:25 +0000 |
commit | 21cb093d49c39537d26c0f7735b9b2b2b7684b8f (patch) | |
tree | 48db7b94a8aac216b83a2eb850e5ee95e97a2062 | |
parent | 58d22d11d8313d630a43da8bf716bf0212227505 (diff) |
interim checkin
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 62 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 35 | ||||
-rw-r--r-- | src/jvm/clojure/lang/TRef.java | 10 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Transaction.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 76 |
6 files changed, 99 insertions, 92 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 1a3faa01..63bb0500 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -21,7 +21,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Compiler { -///* +//* static Symbol DEF = Symbol.intern("def"); static Symbol FN = Symbol.intern("fn"); static Symbol DO = Symbol.intern("do"); @@ -45,19 +45,45 @@ static public Var _CRT_MODULE = RT._CT_MODULE; static NilExpr NIL_EXPR = new NilExpr(); //short-name-string->full-name-string -static public Var IMPORTS = Module.intern("clojure", "^compiler-imports"); +static public Var IMPORTS; + +static + { + try + { + IMPORTS = Module.intern("clojure", "^compiler-imports"); + KEYWORDS = Module.intern("clojure", "^compiler-keywords"); + VARS = Module.intern("clojure", "^compiler-vars"); + LOCAL_ENV = Module.intern("clojure", "^compiler-local-env"); + METHOD = Module.intern("clojure", "^compiler-method"); + USES = Module.intern("clojure", "^compiler-uses"); + FNS = Module.intern("clojure", "^compiler-fns"); + } + catch(Exception e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + //keyword->keywordexpr -static public Var KEYWORDS = Module.intern("clojure", "^compiler-keywords"); +static public Var KEYWORDS; + //var->var -static public Var VARS = Module.intern("clojure", "^compiler-vars"); +static public Var VARS; + //symbol->localbinding -static public Var LOCAL_ENV = Module.intern("clojure", "^compiler-local-env"); +static public Var LOCAL_ENV; + + //FnFrame -static public Var METHOD = Module.intern("clojure", "^compiler-method"); +static public Var METHOD; + //module->module -static public Var USES = Module.intern("clojure", "^compiler-uses"); +static public Var USES; + + //ISeq FnExprs -static public Var FNS = Module.intern("clojure", "^compiler-fns"); +static public Var FNS; static public IPersistentMap CHAR_MAP = new PersistentArrayMap('-', "_DSH_", @@ -1460,7 +1486,7 @@ private static FnMethod analyzeMethod(FnExpr fn, ISeq form) throws Exception { } -static LocalBindingExpr createParamBinding(Symbol p) { +static LocalBindingExpr createParamBinding(Symbol p) throws Exception{ Symbol basep = baseSymbol(p); LocalBinding b = new LocalBinding(basep); b.isParam = true; @@ -1535,7 +1561,7 @@ private static Expr analyzeSymbol(Symbol sym, boolean inFnPosition) throws Excep } } -static Var lookupVar(Symbol sym) { +static Var lookupVar(Symbol sym) throws Exception{ Module module = (Module) _CRT_MODULE.getValue(); Var v = module.find(sym); if (v != null) @@ -1544,7 +1570,7 @@ static Var lookupVar(Symbol sym) { { module = (Module) ((IMapEntry) RT.first(seq)).key(); v = module.find(sym); - if (v != null && !v.hidden) + if (v != null && !v.exported) return v; } return null; @@ -1554,7 +1580,7 @@ static Object macroexpand(Object x) { return x; //placeholder } -private static KeywordExpr registerKeyword(Keyword keyword) { +private static KeywordExpr registerKeyword(Keyword keyword) throws Exception{ IPersistentMap keywordsMap = (IPersistentMap) KEYWORDS.getValue(); KeywordExpr ke = (KeywordExpr) RT.get(keyword, keywordsMap); if (ke == null) @@ -1562,13 +1588,13 @@ private static KeywordExpr registerKeyword(Keyword keyword) { return ke; } -private static void registerVar(Var var) { +private static void registerVar(Var var) throws Exception{ IPersistentMap varsMap = (IPersistentMap) VARS.getValue(); if (RT.get(var, varsMap) == null) VARS.setValue(RT.assoc(var, var, varsMap)); } -private static void registerFn(FnExpr fn) { +private static void registerFn(FnExpr fn) throws Exception{ FNS.setValue(RT.cons(fn, (IPersistentCollection) FNS.getValue())); } @@ -1581,7 +1607,7 @@ static void closeOver(LocalBinding b, FnMethod method) { } } -static LocalBinding referenceLocal(Symbol sym) { +static LocalBinding referenceLocal(Symbol sym) throws Exception{ LocalBinding b = (LocalBinding) RT.get(sym, LOCAL_ENV.getValue()); if (b != null) { @@ -1590,7 +1616,7 @@ static LocalBinding referenceLocal(Symbol sym) { return b; } -private static void registerLocal(LocalBinding b) { +private static void registerLocal(LocalBinding b) throws Exception{ IPersistentMap localsMap = (IPersistentMap) LOCAL_ENV.getValue(); LOCAL_ENV.setValue(RT.assoc(b.sym, b, localsMap)); FnMethod method = (FnMethod) METHOD.getValue(); @@ -1656,13 +1682,13 @@ static Class getTypeNamed(String classname) throws ClassNotFoundException { static class KeyParam { - public KeyParam(LocalBindingExpr b, Expr init) { + public KeyParam(LocalBindingExpr b, Expr init) throws Exception{ this.bindingExpression = b; this.init = init; kw = registerKeyword((Keyword) Symbol.intern(":" + bindingExpression.b.sym.name)); } - public KeyParam(LocalBindingExpr b) { + public KeyParam(LocalBindingExpr b) throws Exception{ this(b, NIL_EXPR); } diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index be6a9344..c804e3d7 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -209,7 +209,7 @@ static private Object readMember(PushbackReader r) throws Exception { }
*/
-static private Object interpretToken(String s) {
+static private Object interpretToken(String s) throws Exception{
if (s.equals("null"))
{
return null;
@@ -248,7 +248,7 @@ private static Object matchSymbol(String s) { }
*/
-private static Object matchVar(String s) {
+private static Object matchVar(String s) throws Exception{
Matcher m = varPat.matcher(s);
if(m.matches())
return Module.intern(m.group(1),m.group(2));
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index a4ce4795..87fd7aaf 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -19,20 +19,31 @@ import java.io.*; public class RT{ static public Symbol T = Symbol.intern(":t"); - static public Var OUT = Module.intern("clojure","^out"); - static public Var _CT_MODULE = Module.intern("clojure", "^module"); - static public final Object[] EMPTY_ARRAY = new Object[]{}; - static public final Character[] chars; - static AtomicInteger id = new AtomicInteger(1); +static public Var OUT; - static { - chars = new Character[256]; - for(int i=0;i<chars.length;i++) - chars[i] = new Character((char)i); +static public Var _CT_MODULE; - OUT.bind(new OutputStreamWriter(System.out)); - _CT_MODULE.bind((Module.findOrCreate("clj-user"))); - } +static public final Object[] EMPTY_ARRAY = new Object[]{}; +static public final Character[] chars; +static AtomicInteger id = new AtomicInteger(1); + + static { + chars = new Character[256]; + for(int i=0;i<chars.length;i++) + chars[i] = new Character((char)i); try + { + OUT = Module.intern("clojure", "^out"); + _CT_MODULE = Module.intern("clojure", "^module"); + + + OUT.bind(new OutputStreamWriter(System.out)); + _CT_MODULE.bind((Module.findOrCreate("clj-user"))); + } + catch(Exception e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } static public int nextID(){ return id.getAndIncrement(); diff --git a/src/jvm/clojure/lang/TRef.java b/src/jvm/clojure/lang/TRef.java index 6f246cb2..c827302f 100644 --- a/src/jvm/clojure/lang/TRef.java +++ b/src/jvm/clojure/lang/TRef.java @@ -42,6 +42,12 @@ public T get() throws Exception{ } public T set(T val) throws Exception{ + //allow out-of-transaction inits + if(!isBound()) + { + tvals.set(new TVal(val, Transaction.ZERO_POINT, null)); + return val; + } return (T) Transaction.getEx().doSet(this,val); } @@ -53,6 +59,10 @@ public void touch() throws Exception{ Transaction.getEx().doTouch(this); } +boolean isBound(){ + return tvals.get() != null; +} + TVal getCurrentTVal(){ TVal head = tvals.get(); if(head == null || head.tstamp.status == TStamp.Status.COMMITTED) diff --git a/src/jvm/clojure/lang/Transaction.java b/src/jvm/clojure/lang/Transaction.java index d81037d2..1d978852 100644 --- a/src/jvm/clojure/lang/Transaction.java +++ b/src/jvm/clojure/lang/Transaction.java @@ -88,7 +88,7 @@ static void statusTransition(TStamp tstamp, TStamp.Status newStatus){ TStamp tstamp; TVal lock(TRef tref, boolean ensurePoint) throws Exception{ - TVal head = tref.tvals.get(); + TVal head = (TVal)tref.tvals.get(); //already locked by this transaction if(head != null && head.tstamp == tstamp) return head; @@ -204,7 +204,7 @@ Object run(IFn fn) throws Exception{ Object doGet(TRef tref) throws Exception{ - TVal head = tref.tvals.get(); + TVal head = (TVal)tref.tvals.get(); if(head == null) return null; if(head.tstamp == tstamp) diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java index 8fa87cb7..3058860b 100644 --- a/src/jvm/clojure/lang/Var.java +++ b/src/jvm/clojure/lang/Var.java @@ -20,17 +20,15 @@ public class Var extends AFn { public final Symbol name; public Module module; -public Binding binding; -public boolean hidden = false; -AtomicInteger tcount = new AtomicInteger(0); -AtomicReference<IPersistentMap> threadBindings = new AtomicReference(PersistentArrayMap.EMPTY); - +public final TRef binding; +public boolean exported = false; Var(Symbol sym, Module ns) { if (!(sym.getClass() == Symbol.class)) throw new IllegalArgumentException("Only simple symbols can be var names"); this.module = ns; this.name = sym; + this.binding = new TRef(); } public String toString() { @@ -39,75 +37,37 @@ public String toString() { return module.name + ":" + name; } -public Var bind(Object val) { - synchronized(this){ - if (binding == null) - binding = new Binding(val); - else - binding.val = val; +public Var bind(Object val) throws Exception{ + //must be called in transaction + binding.set(val); - return this; - } + return this; } -public Object getValue() { - Binding b = getBinding(); - if (b != null) - return b.val; +public Object getValue() throws Exception{ + if(binding.isBound()) + return binding.get(); throw new IllegalStateException(this.toString() + " is unbound."); } -public Object setValue(Object val) { - Binding b = getThreadBinding(); - if (b != null) - return b.val = val; - if (binding == null) - throw new IllegalStateException(this.toString() + " is unbound."); - - return binding.val = val; +public Object setValue(Object val) throws Exception{ + //must be called in transaction + return binding.set(val); } -public Binding pushThreadBinding(Object val) { - Binding ret = new Binding(val, getThreadBinding()); - setThreadBinding(ret); - tcount.incrementAndGet(); - return ret; -} +void pushThreadBinding(Object val) { -public void popThreadBinding() { - setThreadBinding(getThreadBinding().rest); - tcount.decrementAndGet(); } -private Binding getThreadBinding() { - if (tcount.get() != 0) - return (Binding) threadBindings.get().get(Thread.currentThread()); - return null; -} +public void popThreadBinding() { -private Binding getBinding() { - Binding b = getThreadBinding(); - if (b != null) - return b; - return binding; } -private void setThreadBinding(Binding b) { - Thread thread = Thread.currentThread(); - IPersistentMap tb; - IPersistentMap newtb; - do - { - tb = threadBindings.get(); - if (b == null) - newtb = tb.without(thread); - else - newtb = tb.assoc(thread, b); - } while (!threadBindings.compareAndSet(tb, newtb)); -} final public IFn fn() { - return (IFn) getValue(); + if(binding.isBound()) + return (IFn) binding.getCurrentVal(); + throw new IllegalStateException(this.toString() + " is unbound."); } public Object invoke() throws Exception { |