summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-09-26 20:24:16 +0000
committerRich Hickey <richhickey@gmail.com>2006-09-26 20:24:16 +0000
commit2212ddd3122b6f0799b4ed73e77aeeea7c19c34c (patch)
treee27e56585826a7717e3310410cf1f15df4970beb
parentbbabe65cbbbba066e2df174d7b7bea9b5739b8a5 (diff)
interim checkin
-rw-r--r--src/cli/runtime/Module.cs9
-rw-r--r--src/cli/runtime/RT.cs7
-rw-r--r--src/cli/runtime/Var.cs3
-rw-r--r--src/jvm/clojure/lang/Compiler.java154
-rw-r--r--src/jvm/clojure/lang/Module.java6
-rw-r--r--src/jvm/clojure/lang/RT.java5
-rw-r--r--src/jvm/clojure/lang/Var.java1
7 files changed, 157 insertions, 28 deletions
diff --git a/src/cli/runtime/Module.cs b/src/cli/runtime/Module.cs
index e2c091fe..3e396783 100644
--- a/src/cli/runtime/Module.cs
+++ b/src/cli/runtime/Module.cs
@@ -52,7 +52,14 @@ static public Module findOrCreate(String name)
return ns;
}
}
-
+
+public Var find(Symbol sym){
+ lock(vars)
+ {
+ return (Var) vars[sym];
+ }
+}
+
static public Var intern(String ns, String name)
{
return findOrCreate(ns).intern(Symbol.intern(name));
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs
index bb0c3886..7a932f78 100644
--- a/src/cli/runtime/RT.cs
+++ b/src/cli/runtime/RT.cs
@@ -13,6 +13,7 @@
using System;
using System.Collections;
using System.IO;
+using System.Threading;
namespace clojure.lang
{
@@ -27,6 +28,12 @@ public class RT
static public readonly Object[] chars;
+ static int id = 1;
+ static public int nextID()
+ {
+ return Interlocked.Increment(ref id);
+ }
+
static RT(){
chars = new Object[256];
for(int i=0;i<chars.Length;i++)
diff --git a/src/cli/runtime/Var.cs b/src/cli/runtime/Var.cs
index 626c4f48..d2fae255 100644
--- a/src/cli/runtime/Var.cs
+++ b/src/cli/runtime/Var.cs
@@ -15,7 +15,8 @@ namespace clojure.lang
{
public class Var : AFn
{
-public readonly Symbol name; public Module module; public Binding binding; IPersistentMap threadBindings = PersistentArrayMap.EMPTY; int tcount = 0; internal Var(Symbol sym, Module ns) { if(sym.GetType() != typeof(Symbol)) throw new ArgumentException("Only simple symbols can be var names"); this.module = ns; this.name = sym; } override public String ToString() { if(module == null) return "#:" + name; return module.name + ":" + name; } public Var bind(Object val) { lock(this){ if(binding == null)
+public readonly Symbol name; public Module module; public Binding binding;
+public bool hidden = false; IPersistentMap threadBindings = PersistentArrayMap.EMPTY; int tcount = 0; internal Var(Symbol sym, Module ns) { if(sym.GetType() != typeof(Symbol)) throw new ArgumentException("Only simple symbols can be var names"); this.module = ns; this.name = sym; } override public String ToString() { if(module == null) return "#:" + name; return module.name + ":" + name; } public Var bind(Object val) { lock(this){ if(binding == null)
binding = new Binding(val); else binding.val = val;
return this; } } public Object getValue() {
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 5b6cdaa6..c7fc1cff 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -12,7 +12,6 @@
package clojure.lang;
-import java.io.Writer;
import java.io.StringWriter;
public class Compiler{
@@ -26,10 +25,14 @@ static NilExpr NIL_EXPR = new NilExpr();
static public Var IMPORTS = Module.intern("clojure", "^compiler-imports");
//keyword->keywordexpr
static public Var KEYWORDS = Module.intern("clojure", "^compiler-keywords");
-//var->varexpr
+//var->var
static public Var VARS = Module.intern("clojure", "^compiler-vars");
-//symbol->localbindingexpr
-static public Var LOCALS = Module.intern("clojure", "^compiler-locals");
+//symbol->localbinding
+static public Var LOCAL_ENV = Module.intern("clojure", "^compiler-local-env");
+//FnFrame
+static public Var FRAME = Module.intern("clojure", "^compiler-frame");
+//module->module
+static public Var USES = Module.intern("clojure", "^compiler-uses");
static public IPersistentMap CHAR_MAP =
new PersistentArrayMap('-', "_HY_",
@@ -129,7 +132,7 @@ private static void convert(Object form) throws Exception{
Expr e = analyze(C.STATEMENT, form);
}
-private static Expr analyze(C context, Object form){
+private static Expr analyze(C context, Object form) throws Exception {
if(form == null)
return NIL_EXPR;
else if(form instanceof Symbol)
@@ -144,7 +147,7 @@ private static Expr analyze(C context, Object form){
throw new UnsupportedOperationException();
}
-private static Expr analyzeSeq(C context, ISeq form) {
+private static Expr analyzeSeq(C context, ISeq form) throws Exception {
Object op = RT.first(form);
if(op == DEF)
return analyzeDef(context, form);
@@ -152,15 +155,41 @@ private static Expr analyzeSeq(C context, ISeq form) {
throw new UnsupportedOperationException();
}
-private static Expr analyzeDef(C context, ISeq form) {
+private static Expr analyzeDef(C context, ISeq form) throws Exception {
//(def x) or (def x initexpr)
- Symbol name = (Symbol) RT.nth(1, form);
+ Symbol sym = (Symbol) RT.nth(1, form);
Module module = (Module) MODULE.getValue();
- Var var = module.intern(name);
+ Var var = module.intern(baseSymbol(sym));
+ registerVar(var);
+ VarExpr ve = new VarExpr(var, typeHint(sym));
Expr init = analyze(C.EXPRESSION, macroexpand(RT.nth(2, form)));
+ return new DefExpr(ve, init);
}
-private static Expr analyzeSymbol(Symbol sym){
+static Symbol baseSymbol(Symbol sym) {
+ String base = baseName(sym);
+
+ if(base == sym.name) //no typeHint
+ return sym;
+
+ return Symbol.intern(base);
+}
+
+static String baseName(Symbol sym){
+ int slash = sym.name.indexOf('/');
+ if(slash > 0)
+ return sym.name.substring(0, slash);
+ return sym.name;
+}
+
+static String typeHint(Symbol sym){
+ int slash = sym.name.indexOf('/');
+ if(slash > 0)
+ return sym.name.substring(slash + 1);
+ return null;
+}
+
+private static Expr analyzeSymbol(Symbol sym) throws Exception {
if(sym instanceof Keyword)
return registerKeyword((Keyword)sym);
else if(sym instanceof HostSymbol)
@@ -174,21 +203,63 @@ private static Expr analyzeSymbol(Symbol sym){
typeHint = sym.name.substring(slash + 1);
sym = Symbol.intern(sym.name.substring(0, slash));
}
- return new SymExpr(sym, typeHint);
+ LocalBinding b = referenceLocal(sym);
+ if(b != null)
+ return new LocalBindingExpr(b, typeHint);
+ Var v = lookupVar(sym);
+ if(v != null)
+ return new VarExpr(v, typeHint);
+ throw new Exception("Unable to resolve symbol: " + sym.name + " in this context");
}
}
+static Var lookupVar(Symbol sym){
+ Module module = (Module) MODULE.getValue();
+ Var v = module.find(sym);
+ if(v != null)
+ return v;
+ for(ISeq seq = RT.seq(USES.getValue());seq != null;seq = RT.rest(seq))
+ {
+ module = (Module) ((MapEntry)RT.first(seq)).key();
+ v = module.find(sym);
+ if(v != null && !v.hidden)
+ return v;
+ }
+ return null;
+}
+
static Object macroexpand(Object x){
return x; //placeholder
}
-private static Expr registerKeyword(Keyword keyword) {
+private static KeywordExpr registerKeyword(Keyword keyword) {
IPersistentMap keywordsMap = (IPersistentMap) KEYWORDS.getValue();
KeywordExpr ke = (KeywordExpr) RT.get(keyword,keywordsMap);
if(ke == null)
KEYWORDS.setValue(RT.assoc(keyword, ke = new KeywordExpr(keyword),keywordsMap));
return ke;
}
+
+private static void registerVar(Var var) {
+ IPersistentMap varsMap = (IPersistentMap) VARS.getValue();
+ if(RT.get(var,varsMap) == null)
+ VARS.setValue(RT.assoc(var, var, varsMap));
+}
+
+static void closeOver(LocalBinding b,FnFrame frame){
+ if(b != null && frame != null && RT.get(b,frame.locals) == null)
+ {
+ b.closed = true;
+ frame.closes = (IPersistentMap)RT.assoc(b, b, frame.closes);
+ closeOver(b,frame.parent);
+ }
+}
+
+static LocalBinding referenceLocal(Symbol sym) {
+ LocalBinding b = (LocalBinding) RT.get(sym, LOCAL_ENV.getValue());
+ closeOver(b,(FnFrame) FRAME.getValue());
+ return b;
+}
/*
(defun reference-var (sym)
(let ((b (first (member sym *var-env* :key (lambda (b)
@@ -214,6 +285,13 @@ static String resolveHostClassname(String classname) throws Exception {
return fullyQualifiedName;
}
+static class FnFrame{
+ FnFrame parent = null;
+ IPersistentMap locals = null;
+ IPersistentMap closes = null;
+
+}
+
static class NilExpr extends AnExpr{
public void emitExpression() throws Exception{
format("null");
@@ -221,7 +299,7 @@ static class NilExpr extends AnExpr{
}
static class LiteralExpr extends AnExpr{
- Object val;
+ final Object val;
public LiteralExpr(Object val){
this.val = val;
@@ -233,7 +311,7 @@ static class LiteralExpr extends AnExpr{
}
static class CharExpr extends AnExpr{
- Character val;
+ final Character val;
public CharExpr(Character val){
this.val = val;
@@ -246,7 +324,7 @@ static class CharExpr extends AnExpr{
static class HostExpr extends AnExpr{
- HostSymbol sym;
+ final HostSymbol sym;
public HostExpr(HostSymbol sym){
this.sym = sym;
@@ -257,7 +335,7 @@ static class HostExpr extends AnExpr{
format("%A.class", resolveHostClassname(((ClassSymbol) sym).className));
}
}
-
+/*
static class SymExpr extends AnExpr{
Symbol sym;
String typeHint;
@@ -271,9 +349,9 @@ static class SymExpr extends AnExpr{
format("%A", munge(sym.name));
}
}
-
+*/
static class KeywordExpr extends AnExpr{
- Symbol sym;
+ final Symbol sym;
public KeywordExpr(Symbol sym){
this.sym = sym;
@@ -284,25 +362,49 @@ static class KeywordExpr extends AnExpr{
}
}
-static class LocalBindingExpr extends AnExpr{
- Symbol sym;
- String typeHint;
+static class LocalBinding{
+ final Symbol sym;
+ boolean closed = false;
+ final int id = RT.nextID();
- public LocalBindingExpr(Symbol sym, String typeHint){
+ public LocalBinding(Symbol sym) {
this.sym = sym;
+ }
+}
+
+static class LocalBindingExpr extends AnExpr{
+ final LocalBinding b;
+ final String typeHint;
+
+ public LocalBindingExpr(LocalBinding b, String typeHint){
+ this.b = b;
this.typeHint = typeHint;
}
public void emitExpression() throws Exception{
- format("%A", munge(sym.name));
+ format("%A", munge(b.sym.name));
}
}
static class VarExpr extends AnExpr{
- VarExpr var;
- Expr init;
+ final Var var;
+ final String typeHint;
+
+ public VarExpr(Var var, String typeHint){
+ this.var = var;
+ this.typeHint = typeHint;
+ }
+
+ public void emitExpression() throws Exception{
+ format("%A", munge(var.toString()));
+ }
+}
+
+static class DefExpr extends AnExpr{
+ final VarExpr var;
+ final Expr init;
- public VarExpr(VarExpr var, Expr init){
+ public DefExpr(VarExpr var, Expr init){
this.var = var;
this.init = init;
}
diff --git a/src/jvm/clojure/lang/Module.java b/src/jvm/clojure/lang/Module.java
index 80ae6f58..3f839e8d 100644
--- a/src/jvm/clojure/lang/Module.java
+++ b/src/jvm/clojure/lang/Module.java
@@ -55,6 +55,12 @@ static public Var intern(String ns,String name)
return findOrCreate(ns).intern(Symbol.intern(name));
}
+public Var find(Symbol sym){
+ synchronized(vars)
+ {
+ return (Var) vars.get(sym);
+ }
+}
public Var intern(Symbol sym)
{
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index be94d654..faacff57 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -13,6 +13,7 @@
package clojure.lang;
import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicInteger;
import java.io.*;
public class RT{
@@ -21,6 +22,7 @@ public class RT{
static public Var OUT = Module.intern("clojure","^out");
static public final Object[] EMPTY_ARRAY = new Object[]{};
static public final Character[] chars;
+ static AtomicInteger id = new AtomicInteger(1);
static {
chars = new Character[256];
@@ -28,6 +30,9 @@ public class RT{
chars[i] = new Character((char)i);
}
+ static public int nextID(){
+ return id.getAndIncrement();
+ }
static public boolean equal(Object k1,Object k2){
return k1 == k2 ||
diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java
index 7576fbb1..8fa87cb7 100644
--- a/src/jvm/clojure/lang/Var.java
+++ b/src/jvm/clojure/lang/Var.java
@@ -21,6 +21,7 @@ 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);