summaryrefslogtreecommitdiff
path: root/src/jvm/clojure
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-01-23 22:32:59 +0000
committerRich Hickey <richhickey@gmail.com>2008-01-23 22:32:59 +0000
commitdf498fe4972a46a89cf06248af1712bae5d4a83a (patch)
treef8d2f6fe4f5ce8f2f3f5ccb7013ff7c85ea13ec9 /src/jvm/clojure
parentdca114e71248ddd7a172e38ff6dc9956db09c6cf (diff)
interim checkin, do not use
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r--src/jvm/clojure/lang/Compiler.java20
-rw-r--r--src/jvm/clojure/lang/Namespace.java88
-rw-r--r--src/jvm/clojure/lang/RT.java38
-rw-r--r--src/jvm/clojure/lang/Repl.java2
-rw-r--r--src/jvm/clojure/lang/Var.java98
5 files changed, 170 insertions, 76 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 1b148571..e4027a2c 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -229,7 +229,7 @@ static Symbol resolveSymbol(Symbol sym){
if(var != null)
return var.sym;
- return Symbol.intern(currentNS().name, sym.name);
+ return Symbol.intern(currentNS().name.name, sym.name);
}
static class DefExpr implements Expr{
@@ -298,7 +298,7 @@ static class DefExpr implements Expr{
Var v = lookupVar(sym, true);
if(v == null)
throw new Exception("Can't refer to qualified var that doesn't exist");
- if(!v.sym.ns.equals(currentNS().name))
+ if(!v.ns.equals(currentNS()))
{
if(sym.ns == null)
throw new Exception("Name conflict, can't def " + sym + " because namespace: " + currentNS().name +
@@ -2302,7 +2302,7 @@ static class FnExpr implements Expr{
FnMethod enclosingMethod = (FnMethod) METHOD.get();
String basename = enclosingMethod != null ?
(enclosingMethod.fn.name + "$")
- : (munge(currentNS().name) + ".");
+ : (munge(currentNS().name.name) + ".");
fn.simpleName = (name != null ?
munge(name)
: ("fn__" + RT.nextID()));
@@ -3132,12 +3132,12 @@ static Var lookupVar(Symbol sym, boolean internNew) throws Exception{
IPersistentMap refers = (IPersistentMap) ((Var) RT.NS_REFERS.get()).get();
var = (Var) refers.valAt(sym);
if(var == null && sym.ns == null)
- var = Var.find(Symbol.intern(currentNS().name, sym.name));
+ var = Var.find(Symbol.intern(currentNS().name.name, sym.name));
if(var == null && internNew)
{
//introduce a new var in the current ns
- String ns = currentNS().name;
- var = Var.intern(Symbol.intern(ns, sym.name));
+ Namespace ns = currentNS();
+ var = Var.intern(ns,Symbol.create(sym.name));
}
}
if(var != null)
@@ -3153,8 +3153,8 @@ private static void registerVar(Var var) throws Exception{
VARS.set(RT.assoc(varsMap, var, var));
}
-static Symbol currentNS(){
- return (Symbol) RT.CURRENT_NS_SYM.get();
+static Namespace currentNS(){
+ return (Namespace) RT.CURRENT_NS.get();
}
static void closeOver(LocalBinding b, FnMethod method){
@@ -3222,7 +3222,7 @@ public static Object load(Reader rdr) throws Exception{
RT.map(LOADER, new DynamicClassLoader(),
RT.NS_REFERS, RT.NS_REFERS.get(),
RT.NS_IMPORTS, RT.NS_IMPORTS.get(),
- RT.CURRENT_NS_SYM, RT.CURRENT_NS_SYM.get()
+ RT.CURRENT_NS, RT.CURRENT_NS.get()
));
LineNumberingPushbackReader pushbackReader =
(rdr instanceof LineNumberingPushbackReader) ? (LineNumberingPushbackReader) rdr :
@@ -3260,7 +3260,7 @@ public static void main(String[] args){
Var.pushThreadBindings(
RT.map(RT.NS_REFERS, RT.NS_REFERS.get(),
RT.NS_IMPORTS, RT.NS_IMPORTS.get(),
- RT.CURRENT_NS_SYM, RT.CURRENT_NS_SYM.get(),
+ RT.CURRENT_NS, RT.CURRENT_NS.get(),
SOURCE, "REPL"
));
w.write("Clojure\n");
diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java
new file mode 100644
index 00000000..7ca6e8a7
--- /dev/null
+++ b/src/jvm/clojure/lang/Namespace.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ **/
+
+/* rich Jan 23, 2008 */
+
+package clojure.lang;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Namespace{
+final public Symbol name;
+final AtomicReference<IPersistentMap> mappings = new AtomicReference<IPersistentMap>(PersistentHashMap.EMPTY);
+
+final static ConcurrentHashMap<Symbol, Namespace> namespaces = new ConcurrentHashMap<Symbol, Namespace>();
+
+Namespace(Symbol name){
+ this.name = name;
+}
+
+public IPersistentMap getMappings(){
+ return mappings.get();
+}
+
+Var intern(Symbol sym) throws Exception{
+ IPersistentMap map = getMappings();
+ Object o;
+ Var v = null;
+ while((o = map.valAt(sym)) == null)
+ {
+ if(v == null)
+ v = new Var(this, sym);
+ map = getMappings();
+ IPersistentMap newMap = map.assoc(sym,v);
+ mappings.compareAndSet(map,newMap);
+ }
+ if(o instanceof Var && ((Var) o).ns == this)
+ return (Var) o;
+
+ throw new Exception(sym + " already refers to: " + o + " in namespace: " + name);
+}
+
+Var unintern(Var var){
+ return null;
+}
+
+public Class importClass(Symbol sym, Class c){
+ return null;
+
+}
+
+public Class unimport(Symbol sym){
+ return null;
+
+}
+
+
+public Var refer(Symbol sym, Var var){
+ return null;
+
+}
+
+public Var unrefer(Symbol sym){
+ return null;
+
+}
+
+public static Namespace findOrCreate(Symbol name){
+ Namespace ns = namespaces.get(name);
+ if(ns != null)
+ return ns;
+ Namespace newns = new Namespace(name);
+ ns = namespaces.putIfAbsent(name,newns);
+ return ns == null?newns:ns;
+}
+
+
+public Var findVar(Symbol symbol){
+ return null; //To change body of created methods use File | Settings | File Templates.
+}
+}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index f02d98be..03f9ed43 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -13,7 +13,6 @@
package clojure.lang;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.Map;
import java.io.*;
import java.lang.reflect.Array;
@@ -21,10 +20,12 @@ public class RT{
static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null, "t"));
static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t"));
+static final Namespace CLOJURE_NS = Namespace.findOrCreate(Symbol.create("clojure"));
+static final Namespace USER_NS = Namespace.findOrCreate(Symbol.create("user"));
final static public Var OUT =
- Var.intern(Symbol.create("clojure", "*out*"), new OutputStreamWriter(System.out));
+ Var.intern(CLOJURE_NS,Symbol.create("clojure", "*out*"), new OutputStreamWriter(System.out));
final static public Var IN =
- Var.intern(Symbol.create("clojure", "*in*"),
+ Var.intern(CLOJURE_NS,Symbol.create("clojure", "*in*"),
new LineNumberingPushbackReader(new InputStreamReader(System.in)));
final static Keyword TAG_KEY = Keyword.intern("clojure", "tag");
final static Keyword AGENT_KEY = Keyword.intern("clojure", "agent");
@@ -34,11 +35,12 @@ final static Keyword AGENT_KEY = Keyword.intern("clojure", "agent");
final static Symbol LOAD_FILE = Symbol.create("clojure", "load-file");
final static Symbol IN_NAMESPACE = Symbol.create("clojure", "in-namespace");
final static Symbol EXPORTS = Symbol.create("clojure", "*exports*");
-final static Var EXPORTS_VAR = Var.intern(EXPORTS, PersistentHashMap.EMPTY);
+final static Var EXPORTS_VAR = Var.intern(CLOJURE_NS,EXPORTS, PersistentHashMap.EMPTY);
final static Symbol EQL_REF = Symbol.create("clojure", "eql-ref?");
//symbol
-final static Var CURRENT_NS_SYM = Var.intern(Symbol.create("clojure", "*current-namespace*"), Symbol.create("clojure"));
+final static Var CURRENT_NS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*current-namespace*"),
+ CLOJURE_NS);
//simple-symbol->fully-qualified-class-name-string
final static IPersistentMap DEFAULT_IMPORTS = map(
// Symbol.create("RT"), "clojure.lang.RT",
@@ -116,18 +118,18 @@ Symbol.create("Exception"), "java.lang.Exception"
);
-final static Var PRINT_META = Var.intern(Symbol.create("clojure", "*print-meta*"), F);
-final static Var PRINT_READABLY = Var.intern(Symbol.create("clojure", "*print-readably*"), T);
-final static Var WARN_ON_REFLECTION = Var.intern(Symbol.create("clojure", "*warn-on-reflection*"), F);
+final static Var PRINT_META = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*print-meta*"), F);
+final static Var PRINT_READABLY = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*print-readably*"), T);
+final static Var WARN_ON_REFLECTION = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*warn-on-reflection*"), F);
-final static Var IMPORTS = Var.intern(Symbol.create("clojure", "*imports*"), DEFAULT_IMPORTS);
+final static Var IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*imports*"), DEFAULT_IMPORTS);
final static IFn inNamespace = new AFn(){
public Object invoke(Object arg1) throws Exception{
Symbol ns = (Symbol) arg1;
- CURRENT_NS_SYM.set(ns);
- Var refers = Var.intern(Symbol.intern(ns.name, "*refers*"));
+ CURRENT_NS.set(Namespace.findOrCreate(ns));
+ Var refers = Var.intern(null,Symbol.intern(ns.name, "*refers*"));
- Var imports = Var.intern(Symbol.intern(ns.name, "*imports*"), DEFAULT_IMPORTS, false);
+ Var imports = Var.intern(null,Symbol.intern(ns.name, "*imports*"), DEFAULT_IMPORTS, false);
NS_REFERS.set(refers);
NS_IMPORTS.set(imports);
if(!refers.isBound())
@@ -140,16 +142,16 @@ final static IFn inNamespace = new AFn(){
};
//simple-symbol->var
final static Var REFERS =
- Var.intern(Symbol.create("clojure", "*refers*"),
+ Var.intern(CLOJURE_NS,Symbol.create("clojure", "*refers*"),
map(
- IN_NAMESPACE, Var.intern(IN_NAMESPACE, inNamespace),
- LOAD_FILE, Var.intern(LOAD_FILE,
+ IN_NAMESPACE, Var.intern(CLOJURE_NS,IN_NAMESPACE, inNamespace),
+ LOAD_FILE, Var.intern(CLOJURE_NS,LOAD_FILE,
new AFn(){
public Object invoke(Object arg1) throws Exception{
return Compiler.loadFile((String) arg1);
}
}),
- EQL_REF, Var.intern(EQL_REF,
+ EQL_REF, Var.intern(CLOJURE_NS,EQL_REF,
new AFn(){
public Object invoke(Object arg1, Object arg2)
throws Exception{
@@ -158,8 +160,8 @@ final static Var REFERS =
})
));
-static Var NS_IMPORTS = Var.intern(Symbol.create("clojure", "*ns-imports*"), IMPORTS);
-static Var NS_REFERS = Var.intern(Symbol.create("clojure", "*ns-refers*"), REFERS);
+static Var NS_IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*ns-imports*"), IMPORTS);
+static Var NS_REFERS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*ns-refers*"), REFERS);
static public final Object[] EMPTY_ARRAY = new Object[]{};
//static public final Character[] chars;
static AtomicInteger id = new AtomicInteger(1);
diff --git a/src/jvm/clojure/lang/Repl.java b/src/jvm/clojure/lang/Repl.java
index d5caefdc..65026bef 100644
--- a/src/jvm/clojure/lang/Repl.java
+++ b/src/jvm/clojure/lang/Repl.java
@@ -38,7 +38,7 @@ public static void main(String[] args){
Var.pushThreadBindings(
RT.map(RT.NS_REFERS, RT.NS_REFERS.get(),
RT.NS_IMPORTS, RT.NS_IMPORTS.get(),
- RT.CURRENT_NS_SYM, RT.CURRENT_NS_SYM.get(),
+ RT.CURRENT_NS, RT.CURRENT_NS.get(),
RT.WARN_ON_REFLECTION, RT.WARN_ON_REFLECTION.get(),
Compiler.SOURCE, "REPL"
));
diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java
index c905460f..95f6527f 100644
--- a/src/jvm/clojure/lang/Var.java
+++ b/src/jvm/clojure/lang/Var.java
@@ -47,6 +47,7 @@ static ThreadLocal<Frame> dvals = new ThreadLocal<Frame>(){
volatile Object root;
transient final AtomicInteger count;
final public Symbol sym;
+final public Namespace ns;
boolean macroFlag = false;
Symbol tag;
@@ -55,24 +56,25 @@ static ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>> namespaces =
//static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>();
-public static Var intern(Symbol sym, Object root){
- return intern(sym, root, true);
+public static Var intern(Namespace ns, Symbol sym, Object root) throws Exception{
+ return intern(ns, sym, root, true);
}
-public static Var intern(Symbol sym, Object root, boolean replaceRoot){
- ConcurrentHashMap<Symbol, Var> table = getns(sym);
- Var dvout = table.get(sym);
- boolean present = dvout != null;
-
- if(!present)
- {
- Var dvin = new Var(sym, root);
- dvout = table.putIfAbsent(sym, dvin);
- present = dvout != null; //might have snuck in
- if(!present)
- dvout = dvin;
- }
- if(present && (!dvout.hasRoot() || replaceRoot))
+public static Var intern(Namespace ns, Symbol sym, Object root, boolean replaceRoot) throws Exception{
+// ConcurrentHashMap<Symbol, Var> table = getns(sym);
+// Var dvout = table.get(sym);
+// boolean present = dvout != null;
+//
+// if(!present)
+// {
+// Var dvin = new Var(ns, sym, root);
+// dvout = table.putIfAbsent(sym, dvin);
+// present = dvout != null; //might have snuck in
+// if(!present)
+// dvout = dvin;
+// }
+ Var dvout = ns.intern(sym);
+ if(!dvout.hasRoot() || replaceRoot)
dvout.bindRoot(root);
return dvout;
}
@@ -82,55 +84,57 @@ public String toString(){
return "#<Var: " + (sym != null ? sym.toString() : "--unnamed--") + ">";
}
-public static Var intern(Symbol sym){
- ConcurrentHashMap<Symbol, Var> table = getns(sym);
- Var dvout = table.get(sym);
- if(dvout != null)
- return dvout;
-
- Var dvin = table.putIfAbsent(sym, dvout = new Var(sym));
- if(dvin != null)
- return dvin;
- return dvout;
+public static Var intern(Namespace ns, Symbol sym) throws Exception{
+ return ns.intern(sym);
+// ConcurrentHashMap<Symbol, Var> table = getns(sym);
+// Var dvout = table.get(sym);
+// if(dvout != null)
+// return dvout;
+//
+// Var dvin = table.putIfAbsent(sym, dvout = new Var(ns, sym));
+// if(dvin != null)
+// return dvin;
+// return dvout;
}
-public static void unintern(Symbol sym){
- getns(sym).remove(sym);
-}
+//public static void unintern(Symbol nsQualifiedSym){
+// Namespace.findOrCreate(Symbol.create(nsQualifiedSym.ns).unintern(nsQualifiedSym);
+//}
-public static Var find(Symbol sym){
- return getns(sym).get(sym);
+public static Var find(Symbol nsQualifiedSym){
+ return Namespace.findOrCreate(Symbol.create(nsQualifiedSym.ns)).findVar(Symbol.create(nsQualifiedSym.name));
}
-static ConcurrentHashMap<Symbol, Var> getns(Symbol sym){
- String name = sym.ns;
- if(name == null)
- throw new IllegalArgumentException("Var names must have namespace");
- ConcurrentHashMap<Symbol, Var> ns = namespaces.get(name);
- if(ns != null)
- return ns;
- ConcurrentHashMap<Symbol, Var> newns = new ConcurrentHashMap<Symbol, Var>();
- ns = namespaces.putIfAbsent(name,newns);
- return ns == null?newns:ns;
-}
+//static ConcurrentHashMap<Symbol, Var> getns(Symbol sym){
+// String name = sym.ns;
+// if(name == null)
+// throw new IllegalArgumentException("Var names must have namespace");
+// ConcurrentHashMap<Symbol, Var> ns = namespaces.get(name);
+// if(ns != null)
+// return ns;
+// ConcurrentHashMap<Symbol, Var> newns = new ConcurrentHashMap<Symbol, Var>();
+// ns = namespaces.putIfAbsent(name,newns);
+// return ns == null?newns:ns;
+//}
public static Var create(){
- return new Var(null);
+ return new Var(null,null);
}
public static Var create(Object root){
- return new Var(null, root);
+ return new Var(null, null, root);
}
-private Var(Symbol sym){
+Var(Namespace ns, Symbol sym){
+ this.ns = ns;
this.sym = sym;
this.count = new AtomicInteger();
this.root = dvals; //use dvals as magic not-bound value
}
-private Var(Symbol sym, Object root){
- this(sym);
+Var(Namespace ns, Symbol sym, Object root){
+ this(ns,sym);
this.root = root;
}