diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 25 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Namespace.java | 25 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 87 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 56 |
4 files changed, 86 insertions, 107 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index e4027a2c..506acdeb 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -3124,20 +3124,27 @@ static Var lookupVar(Symbol sym, boolean internNew) throws Exception{ //note - ns-qualified vars must already exist if(sym.ns != null) { - var = Var.find(sym); + Namespace ns = Namespace.find(Symbol.create(sym.ns)); + if(ns == null) + throw new Exception("No such namespace: " + sym.ns); + var = ns.findInternedVar(sym); } else { - //is it an alias? - 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.name, sym.name)); - if(var == null && internNew) + //is it mapped? + Object o = currentNS().getMapping(sym); + if(o == null) { //introduce a new var in the current ns - Namespace ns = currentNS(); - var = Var.intern(ns,Symbol.create(sym.name)); + var = currentNS().intern(Symbol.create(sym.name)); + } + else if(o instanceof Var) + { + var = (Var) o; + } + else + { + throw new Exception("Expecting var, " + sym + " is mapped to " + o.getClass()); } } if(var != null) diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java index 7ca6e8a7..0cc5936b 100644 --- a/src/jvm/clojure/lang/Namespace.java +++ b/src/jvm/clojure/lang/Namespace.java @@ -17,19 +17,24 @@ import java.util.concurrent.atomic.AtomicReference; public class Namespace{ final public Symbol name; -final AtomicReference<IPersistentMap> mappings = new AtomicReference<IPersistentMap>(PersistentHashMap.EMPTY); +final AtomicReference<IPersistentMap> mappings = new AtomicReference<IPersistentMap>(); final static ConcurrentHashMap<Symbol, Namespace> namespaces = new ConcurrentHashMap<Symbol, Namespace>(); Namespace(Symbol name){ this.name = name; + mappings.set(RT.DEFAULT_IMPORTS); } public IPersistentMap getMappings(){ return mappings.get(); } -Var intern(Symbol sym) throws Exception{ +Var intern(Symbol sym){ + if(sym.ns != null) + { + throw new IllegalArgumentException("Can't intern namespace-qualified symbol"); + } IPersistentMap map = getMappings(); Object o; Var v = null; @@ -44,7 +49,7 @@ Var intern(Symbol sym) throws Exception{ if(o instanceof Var && ((Var) o).ns == this) return (Var) o; - throw new Exception(sym + " already refers to: " + o + " in namespace: " + name); + throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name); } Var unintern(Var var){ @@ -81,8 +86,18 @@ public static Namespace findOrCreate(Symbol name){ return ns == null?newns:ns; } +public static Namespace find(Symbol name){ + return namespaces.get(name); +} -public Var findVar(Symbol symbol){ - return null; //To change body of created methods use File | Settings | File Templates. +public Object getMapping(Symbol name){ + return mappings.get().valAt(name); +} + +public Var findInternedVar(Symbol symbol){ + Object o = mappings.get().valAt(symbol); + if(o != null && o instanceof Var && ((Var)o).ns == this) + return (Var) o; + return null; } } diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 03f9ed43..f0e13f78 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -20,28 +20,8 @@ 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(CLOJURE_NS,Symbol.create("clojure", "*out*"), new OutputStreamWriter(System.out)); -final static public Var 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"); -//final static public Var CURRENT_MODULE = Var.intern(Symbol.create("clojure", "current-module"), -// Module.findOrCreateModule("clojure/user")); -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(CLOJURE_NS,EXPORTS, PersistentHashMap.EMPTY); -final static Symbol EQL_REF = Symbol.create("clojure", "eql-ref?"); - -//symbol -final static Var CURRENT_NS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*current-namespace*"), - CLOJURE_NS); -//simple-symbol->fully-qualified-class-name-string +//simple-symbol->class final static IPersistentMap DEFAULT_IMPORTS = map( // Symbol.create("RT"), "clojure.lang.RT", // Symbol.create("Num"), "clojure.lang.Num", @@ -57,7 +37,7 @@ final static IPersistentMap DEFAULT_IMPORTS = map( // Symbol.create("IPersistentMap"), "clojure.lang.IPersistentMap", // Symbol.create("IPersistentList"), "clojure.lang.IPersistentList", // Symbol.create("IPersistentVector"), "clojure.lang.IPersistentVector", -Symbol.create("Boolean"), "java.lang.Boolean", +Symbol.create("Boolean"), Boolean.class, Symbol.create("Byte"), "java.lang.Byte", Symbol.create("Character"), "java.lang.Character", Symbol.create("Class"), "java.lang.Class", @@ -118,31 +98,54 @@ Symbol.create("Exception"), "java.lang.Exception" ); -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); +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(CLOJURE_NS,Symbol.create("*out*"), new OutputStreamWriter(System.out)); +final static public Var IN = + Var.intern(CLOJURE_NS,Symbol.create("*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"); +//final static public Var CURRENT_MODULE = Var.intern(Symbol.create("clojure", "current-module"), +// Module.findOrCreateModule("clojure/user")); + +final static Symbol LOAD_FILE = Symbol.create("load-file"); +final static Symbol IN_NAMESPACE = Symbol.create("in-namespace"); +final static Symbol EXPORTS = Symbol.create("*exports*"); +final static Var EXPORTS_VAR = Var.intern(CLOJURE_NS,EXPORTS, PersistentHashMap.EMPTY); +final static Symbol EQL_REF = Symbol.create("eql-ref?"); + +//symbol +final static Var CURRENT_NS = Var.intern(CLOJURE_NS,Symbol.create("*current-namespace*"), + CLOJURE_NS); + +final static Var PRINT_META = Var.intern(CLOJURE_NS,Symbol.create("*print-meta*"), F); +final static Var PRINT_READABLY = Var.intern(CLOJURE_NS,Symbol.create("*print-readably*"), T); +final static Var WARN_ON_REFLECTION = Var.intern(CLOJURE_NS,Symbol.create("*warn-on-reflection*"), F); -final static Var IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("clojure", "*imports*"), DEFAULT_IMPORTS); +final static Var IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("*imports*"), DEFAULT_IMPORTS); final static IFn inNamespace = new AFn(){ public Object invoke(Object arg1) throws Exception{ - Symbol ns = (Symbol) arg1; - CURRENT_NS.set(Namespace.findOrCreate(ns)); - Var refers = Var.intern(null,Symbol.intern(ns.name, "*refers*")); - - Var imports = Var.intern(null,Symbol.intern(ns.name, "*imports*"), DEFAULT_IMPORTS, false); - NS_REFERS.set(refers); - NS_IMPORTS.set(imports); - if(!refers.isBound()) - { - refers.bindRoot(PersistentHashMap.EMPTY); - Compiler.eval(list(Symbol.create("clojure", "refer"), EXPORTS)); - } - return RT.T; + Symbol nsname = (Symbol) arg1; + Namespace ns = Namespace.findOrCreate(nsname); + CURRENT_NS.set(ns); +// Var refers = Var.intern(null,Symbol.intern(nsname.name, "*refers*")); +// +// Var imports = Var.intern(null,Symbol.intern(nsname.name, "*imports*"), DEFAULT_IMPORTS, false); +// NS_REFERS.set(refers); +// NS_IMPORTS.set(imports); +// if(!refers.isBound()) +// { +// refers.bindRoot(PersistentHashMap.EMPTY); +// Compiler.eval(list(Symbol.create("clojure", "refer"), EXPORTS)); +// } + return ns; } }; //simple-symbol->var final static Var REFERS = - Var.intern(CLOJURE_NS,Symbol.create("clojure", "*refers*"), + Var.intern(CLOJURE_NS,Symbol.create("*refers*"), map( IN_NAMESPACE, Var.intern(CLOJURE_NS,IN_NAMESPACE, inNamespace), LOAD_FILE, Var.intern(CLOJURE_NS,LOAD_FILE, @@ -160,8 +163,8 @@ final static Var 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 Var NS_IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("*ns-imports*"), IMPORTS); +static Var NS_REFERS = Var.intern(CLOJURE_NS,Symbol.create("*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/Var.java b/src/jvm/clojure/lang/Var.java index 95f6527f..828c45ab 100644 --- a/src/jvm/clojure/lang/Var.java +++ b/src/jvm/clojure/lang/Var.java @@ -51,28 +51,11 @@ final public Namespace ns; boolean macroFlag = false; Symbol tag; -static ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>> namespaces = - new ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>>(); - -//static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>(); - -public static Var intern(Namespace ns, Symbol sym, Object root) throws Exception{ +public static Var intern(Namespace ns, Symbol sym, Object root){ return intern(ns, sym, root, true); } -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; -// } +public static Var intern(Namespace ns, Symbol sym, Object root, boolean replaceRoot){ Var dvout = ns.intern(sym); if(!dvout.hasRoot() || replaceRoot) dvout.bindRoot(root); @@ -81,41 +64,12 @@ public static Var intern(Namespace ns, Symbol sym, Object root, boolean replaceR public String toString(){ - return "#<Var: " + (sym != null ? sym.toString() : "--unnamed--") + ">"; + return "#<Var: " + (ns!=null?(ns.name + "/"):"") + (sym != null ? sym.toString() : "--unnamed--") + ">"; } -public static Var intern(Namespace ns, Symbol sym) throws Exception{ +public static Var intern(Namespace ns, Symbol sym){ 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 nsQualifiedSym){ -// Namespace.findOrCreate(Symbol.create(nsQualifiedSym.ns).unintern(nsQualifiedSym); -//} - -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; -//} +} public static Var create(){ |