summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-06-29 16:03:25 +0000
committerRich Hickey <richhickey@gmail.com>2007-06-29 16:03:25 +0000
commit21cb093d49c39537d26c0f7735b9b2b2b7684b8f (patch)
tree48db7b94a8aac216b83a2eb850e5ee95e97a2062
parent58d22d11d8313d630a43da8bf716bf0212227505 (diff)
interim checkin
-rw-r--r--src/jvm/clojure/lang/Compiler.java62
-rw-r--r--src/jvm/clojure/lang/LispReader.java4
-rw-r--r--src/jvm/clojure/lang/RT.java35
-rw-r--r--src/jvm/clojure/lang/TRef.java10
-rw-r--r--src/jvm/clojure/lang/Transaction.java4
-rw-r--r--src/jvm/clojure/lang/Var.java76
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 {