summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-07-02 18:41:27 +0000
committerRich Hickey <richhickey@gmail.com>2007-07-02 18:41:27 +0000
commitc8f2340902b1c3efd66dec3071f93b82eb5632e4 (patch)
treebe135451dc3fc14bee7e0b30026bc566829c0f54 /src
parente4bbdb0c9af57495d16c8b4f97248c0137030da9 (diff)
interim checkin
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/APersistentArray.java167
-rw-r--r--src/jvm/clojure/lang/APersistentMap.java143
-rw-r--r--src/jvm/clojure/lang/Associative.java6
-rw-r--r--src/jvm/clojure/lang/Compiler.java3347
-rw-r--r--src/jvm/clojure/lang/Iter.java6
-rw-r--r--src/jvm/clojure/lang/Keyword.java102
-rw-r--r--src/jvm/clojure/lang/MapEntry.java133
-rw-r--r--src/jvm/clojure/lang/Module.java39
-rw-r--r--src/jvm/clojure/lang/PersistentArrayMap.java374
-rw-r--r--src/jvm/clojure/lang/PersistentHashMap.java8
-rw-r--r--src/jvm/clojure/lang/PersistentHashtableMap.java391
-rw-r--r--src/jvm/clojure/lang/PersistentTreeMap.java354
-rw-r--r--src/jvm/clojure/lang/RT.java1025
-rw-r--r--src/jvm/clojure/lang/TRef.java32
-rw-r--r--src/jvm/clojure/lang/ThreadLocalData.java32
-rw-r--r--src/jvm/clojure/lang/Transaction.java8
-rw-r--r--src/jvm/clojure/lang/Var.java206
17 files changed, 3187 insertions, 3186 deletions
diff --git a/src/jvm/clojure/lang/APersistentArray.java b/src/jvm/clojure/lang/APersistentArray.java
index ae2e6602..e479255a 100644
--- a/src/jvm/clojure/lang/APersistentArray.java
+++ b/src/jvm/clojure/lang/APersistentArray.java
@@ -10,106 +10,107 @@
package clojure.lang;
-public abstract class APersistentArray extends Obj implements IPersistentArray, Cloneable {
+public abstract class APersistentArray extends Obj implements IPersistentArray, Cloneable{
int _hash = -1;
-public IPersistentCollection cons(Object o) {
- PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10);
- ret = ret.cons(o);
- ret._meta = _meta;
- return ret;
+public IPersistentCollection cons(Object o){
+ PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10);
+ ret = ret.cons(o);
+ ret._meta = _meta;
+ return ret;
}
-public Obj withMeta(IPersistentMap meta) {
- if(_meta == meta)
- return this;
- try{
- Obj ret = (Obj) clone();
- ret._meta = meta;
- return ret;
- }
- catch(CloneNotSupportedException ignore)
- {
- return null;
- }
+public Obj withMeta(IPersistentMap meta){
+ if(_meta == meta)
+ return this;
+ try
+ {
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
-public boolean equals(Object obj) {
- if(obj instanceof IPersistentArray)
- {
- IPersistentArray ma = (IPersistentArray) obj;
- if(ma.count() != count() || ma.hashCode() != hashCode())
- return false;
- for(int i=0;i<count();i++)
- {
- if(!RT.equal(nth(i),ma.nth(i)))
- return false;
- }
- }
- else
- {
- if(!(obj instanceof Sequential))
- return false;
- ISeq ms = ((IPersistentCollection)obj).seq();
- for(int i=0;i<count();i++, ms = ms.rest())
- {
- if(ms == null || !RT.equal(nth(i),ms.first()))
- return false;
- }
- if(ms.rest() != null)
- return false;
- }
+public boolean equals(Object obj){
+ if(obj instanceof IPersistentArray)
+ {
+ IPersistentArray ma = (IPersistentArray) obj;
+ if(ma.count() != count() || ma.hashCode() != hashCode())
+ return false;
+ for(int i = 0; i < count(); i++)
+ {
+ if(!RT.equal(nth(i), ma.nth(i)))
+ return false;
+ }
+ }
+ else
+ {
+ if(!(obj instanceof Sequential))
+ return false;
+ ISeq ms = ((IPersistentCollection) obj).seq();
+ for(int i = 0; i < count(); i++, ms = ms.rest())
+ {
+ if(ms == null || !RT.equal(nth(i), ms.first()))
+ return false;
+ }
+ if(ms.rest() != null)
+ return false;
+ }
- return true;
+ return true;
}
-public int hashCode() {
- if(_hash == -1)
- {
- int hash = 0;
- for(int i=0;i<count();i++)
- {
- hash = RT.hashCombine(hash, RT.hash(nth(i)));
- }
- this._hash = hash;
- }
- return _hash;
+public int hashCode(){
+ if(_hash == -1)
+ {
+ int hash = 0;
+ for(int i = 0; i < count(); i++)
+ {
+ hash = RT.hashCombine(hash, RT.hash(nth(i)));
+ }
+ this._hash = hash;
+ }
+ return _hash;
}
-public boolean contains(Object key) {
- if(!(key instanceof Number))
- return false;
- int i = ((Number)key).intValue();
- return i >= 0 && i < count();
+public boolean contains(Object key){
+ if(!(key instanceof Number))
+ return false;
+ int i = ((Number) key).intValue();
+ return i >= 0 && i < count();
}
-public IMapEntry find(Object key) {
- if(key instanceof Number)
- {
- int i = ((Number)key).intValue();
- if(i >= 0 && i < count())
- return new MapEntry(key,nth(i));
- }
- return null;
+public IMapEntry entryAt(Object key){
+ if(key instanceof Number)
+ {
+ int i = ((Number) key).intValue();
+ if(i >= 0 && i < count())
+ return new MapEntry(key, nth(i));
+ }
+ return null;
}
-public Associative assoc(Object key, Object val) {
- if(key instanceof Number)
- {
- int i = ((Number)key).intValue();
- return (Associative) assocN(i,val);
- }
- throw new IllegalAccessError("Key must be integer");
+public Associative assoc(Object key, Object val){
+ if(key instanceof Number)
+ {
+ int i = ((Number) key).intValue();
+ return (Associative) assocN(i, val);
+ }
+ throw new IllegalAccessError("Key must be integer");
}
-public Object get(Object key) {
- if(key instanceof Number)
- {
- int i = ((Number)key).intValue();
- if(i >= 0 && i < count())
- return nth(i);
- }
- return null;
+public Object valAt(Object key){
+ if(key instanceof Number)
+ {
+ int i = ((Number) key).intValue();
+ if(i >= 0 && i < count())
+ return nth(i);
+ }
+ return null;
}
}
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java
index 4b5805fd..bde64c2d 100644
--- a/src/jvm/clojure/lang/APersistentMap.java
+++ b/src/jvm/clojure/lang/APersistentMap.java
@@ -13,101 +13,102 @@ package clojure.lang;
public abstract class APersistentMap extends Obj implements IPersistentMap, Cloneable{
int _hash = -1;
-public Obj withMeta(IPersistentMap meta) {
- if(_meta == meta)
- return this;
- try{
- Obj ret = (Obj) clone();
- ret._meta = meta;
- return ret;
- }
- catch(CloneNotSupportedException ignore)
- {
- return null;
- }
+public Obj withMeta(IPersistentMap meta){
+ if(_meta == meta)
+ return this;
+ try
+ {
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
-public IPersistentCollection cons(Object o) {
- IMapEntry e = (IMapEntry)o;
- return assoc(e.key(), e.val());
+public IPersistentCollection cons(Object o){
+ IMapEntry e = (IMapEntry) o;
+ return assoc(e.key(), e.val());
}
-public boolean equals(Object obj) {
- if(!(obj instanceof IPersistentMap))
- return false;
- IPersistentMap m = (IPersistentMap)obj;
+public boolean equals(Object obj){
+ if(!(obj instanceof IPersistentMap))
+ return false;
+ IPersistentMap m = (IPersistentMap) obj;
- if(m.count() != count() || m.hashCode() != hashCode())
- return false;
+ if(m.count() != count() || m.hashCode() != hashCode())
+ return false;
- for(ISeq s = seq();s!=null;s = s.rest())
- {
- IMapEntry e = (IMapEntry) s.first();
- IMapEntry me = m.find(e.key());
+ for(ISeq s = seq(); s != null; s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ IMapEntry me = m.entryAt(e.key());
- if(me == null || !RT.equal(e.val(),me.val()))
- return false;
- }
+ if(me == null || !RT.equal(e.val(), me.val()))
+ return false;
+ }
- return true;
+ return true;
}
-public int hashCode() {
- if(_hash == -1)
- {
- int hash = count();
- for(ISeq s = seq();s!=null;s = s.rest())
- {
- IMapEntry e = (IMapEntry) s.first();
- hash ^= RT.hashCombine(RT.hash(e.key()), RT.hash(e.val()));
- }
- this._hash = hash;
- }
- return _hash;
+public int hashCode(){
+ if(_hash == -1)
+ {
+ int hash = count();
+ for(ISeq s = seq(); s != null; s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ hash ^= RT.hashCombine(RT.hash(e.key()), RT.hash(e.val()));
+ }
+ this._hash = hash;
+ }
+ return _hash;
}
static public class KeySeq extends ASeq{
- ISeq seq;
+ ISeq seq;
- static public KeySeq create(ISeq seq){
- if(seq == null)
- return null;
- return new KeySeq(seq);
- }
+ static public KeySeq create(ISeq seq){
+ if(seq == null)
+ return null;
+ return new KeySeq(seq);
+ }
- private KeySeq(ISeq seq) {
- this.seq = seq;
- }
+ private KeySeq(ISeq seq){
+ this.seq = seq;
+ }
- public Object first() {
- return ((IMapEntry)seq.first()).key();
- }
+ public Object first(){
+ return ((IMapEntry) seq.first()).key();
+ }
- public ISeq rest() {
- return create(seq.rest());
- }
+ public ISeq rest(){
+ return create(seq.rest());
+ }
}
static public class ValSeq extends ASeq{
- ISeq seq;
+ ISeq seq;
- static public ValSeq create(ISeq seq){
- if(seq == null)
- return null;
- return new ValSeq(seq);
- }
+ static public ValSeq create(ISeq seq){
+ if(seq == null)
+ return null;
+ return new ValSeq(seq);
+ }
- private ValSeq(ISeq seq) {
- this.seq = seq;
- }
+ private ValSeq(ISeq seq){
+ this.seq = seq;
+ }
- public Object first() {
- return ((IMapEntry)seq.first()).val();
- }
+ public Object first(){
+ return ((IMapEntry) seq.first()).val();
+ }
- public ISeq rest() {
- return create(seq.rest());
- }
+ public ISeq rest(){
+ return create(seq.rest());
+ }
}
}
diff --git a/src/jvm/clojure/lang/Associative.java b/src/jvm/clojure/lang/Associative.java
index eea67e59..1de849d0 100644
--- a/src/jvm/clojure/lang/Associative.java
+++ b/src/jvm/clojure/lang/Associative.java
@@ -9,12 +9,12 @@ package clojure.lang;
* the terms of this license.
* You must not remove this notice, or any other, from this software.
*/
-public interface Associative extends IPersistentCollection {
+public interface Associative extends IPersistentCollection{
boolean contains(Object key);
-IMapEntry find(Object key);
+IMapEntry entryAt(Object key);
Associative assoc(Object key, Object val);
-Object get(Object key);
+Object valAt(Object key);
}
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 63bb0500..9317bcc6 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -20,7 +20,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-public class Compiler {
+public class Compiler{
//*
static Symbol DEF = Symbol.intern("def");
static Symbol FN = Symbol.intern("fn");
@@ -86,617 +86,618 @@ static public Var USES;
static public Var FNS;
static public IPersistentMap CHAR_MAP =
- new PersistentArrayMap('-', "_DSH_",
- '.', "_DOT_",
- ':', "_CLN_",
- '+', "_PLS_",
- '>', "_GT_",
- '<', "_LT_",
- '=', "_EQ_",
- '~', "_TLD_",
- '!', "_EXC_",
- '@', "_AT_",
- '#', "_SHP_",
- '$', "_DS_",
- '%', "_PCT_",
- '^', "_CRT_",
- '&', "_AMP_",
- '*', "_STAR_",
- '{', "_LBC_",
- '}', "_RBC_",
- '[', "_LBK_",
- ']', "_RBK_",
- '/', "_FSL_",
- '\\', "_BSL_",
- '?', "_QM_");
+ new PersistentArrayMap('-', "_DSH_",
+ '.', "_DOT_",
+ ':', "_CLN_",
+ '+', "_PLS_",
+ '>', "_GT_",
+ '<', "_LT_",
+ '=', "_EQ_",
+ '~', "_TLD_",
+ '!', "_EXC_",
+ '@', "_AT_",
+ '#', "_SHP_",
+ '$', "_DS_",
+ '%', "_PCT_",
+ '^', "_CRT_",
+ '&', "_AMP_",
+ '*', "_STAR_",
+ '{', "_LBC_",
+ '}', "_RBC_",
+ '[', "_LBK_",
+ ']', "_RBK_",
+ '/', "_FSL_",
+ '\\', "_BSL_",
+ '?', "_QM_");
private static final int MAX_POSITIONAL_ARITY = 20;
-static String compile(String ns, String className, LineNumberingPushbackReader... files) throws Exception {
- StringWriter w = new StringWriter();
- try
- {
- _CRT_OUT.pushThreadBinding(w);
- KEYWORDS.pushThreadBinding(null);
- VARS.pushThreadBinding(null);
- METHOD.pushThreadBinding(null);
- LOCAL_ENV.pushThreadBinding(null);
- FNS.pushThreadBinding(new PersistentArrayList(4));
-
- format("/* Generated by Clojure */~%~%");
- format("package ~A;~%", ns);
- format("import clojure.lang.*;~%~%");
- format("public class ~A{~%", className);
-
- PersistentArrayList forms = new PersistentArrayList(20);
- for (LineNumberingPushbackReader reader : files)
- {
- try
- {
- IMPORTS.pushThreadBinding(null);
- USES.pushThreadBinding(null);
-
- Object eof = new Object();
- Object form = null;
-
- while ((form = LispReader.read(reader, false, eof, false)) != eof)
- {
- form = macroexpand(form);
- if (!(form instanceof ISeq))
- throw new Exception("No atoms allowed at top level");
- Object op = RT.first(form);
-
- //enact import and use at compile-time
- if (op == IMPORT)
- {
- //(import org.package ThisClass ThatClass ...)
- //makes entries in IMPORTS for:
- //"ThisClass"->"org.package.ThisClass"
- //"ThatClass"->"org.package.ThatClass"
- IPersistentMap importMap = (IPersistentMap) IMPORTS.getValue();
- String pkg = RT.second(form).toString();
- for (ISeq classes = RT.rest(RT.rest(form)); classes != null; classes = classes.rest())
- {
- String iclassName = classes.first().toString();
- importMap = (IPersistentMap) RT.assoc(iclassName, pkg + "." + iclassName, importMap);
- }
- IMPORTS.setValue(importMap);
- }
- else if (op == USE)
- {
- //todo implement use
- }
- else
- forms = forms.cons(analyze(C.STATEMENT, form));
- }
- }
- finally
- {
- IMPORTS.popThreadBinding();
- USES.popThreadBinding();
- }
- }
- //declare static members for keywords, vars
- for (ISeq keys = RT.seq(KEYWORDS.getValue()); keys != null; keys = keys.rest())
- {
- KeywordExpr k = (KeywordExpr) ((IMapEntry) keys.first()).val();
- format("static Keyword ~A;~%", k.emitExpressionString());
- }
- for (ISeq vars = RT.seq(VARS.getValue()); vars != null; vars = vars.rest())
- {
- Var v = (Var) ((IMapEntry) vars.first()).val();
- format("static Var ~A;~%", munge(v.toString()));
- }
-
- //todo declare static members for syms, quoted aggregates
-
- //emit nested static class/method declarations for nested fns
- PersistentArrayList fns = (PersistentArrayList) FNS.getValue();
- for (int f = 0; f < fns.count(); f++)
- {
- FnExpr fn = (FnExpr) fns.nth(f);
- fn.emitDeclaration();
- }
-
- //define the load function
- format("public void load() throws Exception{~%");
- //init the keywords and vars
- for (ISeq keys = RT.seq(KEYWORDS.getValue()); keys != null; keys = keys.rest())
- {
- KeywordExpr k = (KeywordExpr) ((IMapEntry) keys.first()).val();
- format("~A = (Keyword)Symbol.intern(~S);~%", k.emitExpressionString(), k.sym.name);
- }
- for (ISeq vars = RT.seq(VARS.getValue()); vars != null; vars = vars.rest())
- {
- Var v = (Var) ((IMapEntry) vars.first()).val();
- format("~A = Module.intern(~S,~S);~%", munge(v.toString()), v.module.name, v.name.name);
- }
- //todo init syms and quoted aggregates
- //emit the top level forms
- for (int i = 0; i < forms.count(); i++)
- {
- Expr e = (Expr) forms.nth(i);
- e.emitStatement();
- }
- //close load function
- format("}~%");
-
- //close class def
- format("}~%");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- _CRT_OUT.popThreadBinding();
- KEYWORDS.popThreadBinding();
- VARS.popThreadBinding();
- METHOD.popThreadBinding();
- LOCAL_ENV.popThreadBinding();
- FNS.popThreadBinding();
- }
- return w.toString();
-}
-
-static String munge(String name) {
- StringBuilder sb = new StringBuilder();
- for (char c : name.toCharArray())
- {
- String sub = (String) CHAR_MAP.get(c);
- if (sub != null)
- sb.append(sub);
- else
- sb.append(c);
- }
- return sb.toString();
-}
-
-enum C {
- STATEMENT,EXPRESSION,RETURN,FN}
-
-interface Expr {
-
- void emitReturn() throws Exception;
-
- void emitStatement() throws Exception;
-
- void emitExpression() throws Exception;
-
- String emitExpressionString() throws Exception;
-
- // may return null if clojure expression with no type hint, or host expression with unknown type
- //cannot be used to distinguish host expr vs not
- Class getHostType() throws Exception;
-
- boolean canEmitHostExpr();
-
- void emitHostExpr() throws Exception;
-
-}
-
-static void format(String str, Object... args) throws Exception {
- RT.format(RT.T, str, args);
-}
-
-static class AnExpr implements Expr {
-
- public void emitReturn() throws Exception {
- format("return ");
- emitExpression();
- format(";~%");
- }
+static String compile(String ns, String className, LineNumberingPushbackReader... files) throws Exception{
+ StringWriter w = new StringWriter();
+ try
+ {
+ _CRT_OUT.pushThreadBinding(w);
+ KEYWORDS.pushThreadBinding(null);
+ VARS.pushThreadBinding(null);
+ METHOD.pushThreadBinding(null);
+ LOCAL_ENV.pushThreadBinding(null);
+ FNS.pushThreadBinding(new PersistentArrayList(4));
+
+ format("/* Generated by Clojure */~%~%");
+ format("package ~A;~%", ns);
+ format("import clojure.lang.*;~%~%");
+ format("public class ~A{~%", className);
+
+ PersistentArrayList forms = new PersistentArrayList(20);
+ for(LineNumberingPushbackReader reader : files)
+ {
+ try
+ {
+ IMPORTS.pushThreadBinding(null);
+ USES.pushThreadBinding(null);
+
+ Object eof = new Object();
+ Object form = null;
+
+ while((form = LispReader.read(reader, false, eof, false)) != eof)
+ {
+ form = macroexpand(form);
+ if(!(form instanceof ISeq))
+ throw new Exception("No atoms allowed at top level");
+ Object op = RT.first(form);
+
+ //enact import and use at compile-time
+ if(op == IMPORT)
+ {
+ //(import org.package ThisClass ThatClass ...)
+ //makes entries in IMPORTS for:
+ //"ThisClass"->"org.package.ThisClass"
+ //"ThatClass"->"org.package.ThatClass"
+ IPersistentMap importMap = (IPersistentMap) IMPORTS.getValue();
+ String pkg = RT.second(form).toString();
+ for(ISeq classes = RT.rest(RT.rest(form)); classes != null; classes = classes.rest())
+ {
+ String iclassName = classes.first().toString();
+ importMap = (IPersistentMap) RT.assoc(iclassName, pkg + "." + iclassName, importMap);
+ }
+ IMPORTS.setValue(importMap);
+ }
+ else if(op == USE)
+ {
+ //todo implement use
+ }
+ else
+ forms = forms.cons(analyze(C.STATEMENT, form));
+ }
+ }
+ finally
+ {
+ IMPORTS.popThreadBinding();
+ USES.popThreadBinding();
+ }
+ }
+ //declare static members for keywords, vars
+ for(ISeq keys = RT.seq(KEYWORDS.getValue()); keys != null; keys = keys.rest())
+ {
+ KeywordExpr k = (KeywordExpr) ((IMapEntry) keys.first()).val();
+ format("static Keyword ~A;~%", k.emitExpressionString());
+ }
+ for(ISeq vars = RT.seq(VARS.getValue()); vars != null; vars = vars.rest())
+ {
+ Var v = (Var) ((IMapEntry) vars.first()).val();
+ format("static Var ~A;~%", munge(v.toString()));
+ }
+
+ //todo declare static members for syms, quoted aggregates
+
+ //emit nested static class/method declarations for nested fns
+ PersistentArrayList fns = (PersistentArrayList) FNS.getValue();
+ for(int f = 0; f < fns.count(); f++)
+ {
+ FnExpr fn = (FnExpr) fns.nth(f);
+ fn.emitDeclaration();
+ }
+
+ //define the load function
+ format("public void load() throws Exception{~%");
+ //init the keywords and vars
+ for(ISeq keys = RT.seq(KEYWORDS.getValue()); keys != null; keys = keys.rest())
+ {
+ KeywordExpr k = (KeywordExpr) ((IMapEntry) keys.first()).val();
+ format("~A = (Keyword)Symbol.intern(~S);~%", k.emitExpressionString(), k.sym.name);
+ }
+ for(ISeq vars = RT.seq(VARS.getValue()); vars != null; vars = vars.rest())
+ {
+ Var v = (Var) ((IMapEntry) vars.first()).val();
+ format("~A = Module.intern(~S,~S);~%", munge(v.toString()), v.module.name, v.name.name);
+ }
+ //todo init syms and quoted aggregates
+ //emit the top level forms
+ for(int i = 0; i < forms.count(); i++)
+ {
+ Expr e = (Expr) forms.nth(i);
+ e.emitStatement();
+ }
+ //close load function
+ format("}~%");
+
+ //close class def
+ format("}~%");
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ _CRT_OUT.popThreadBinding();
+ KEYWORDS.popThreadBinding();
+ VARS.popThreadBinding();
+ METHOD.popThreadBinding();
+ LOCAL_ENV.popThreadBinding();
+ FNS.popThreadBinding();
+ }
+ return w.toString();
+}
- public void emitStatement() throws Exception {
- emitExpression();
- format(";~%");
- }
+static String munge(String name){
+ StringBuilder sb = new StringBuilder();
+ for(char c : name.toCharArray())
+ {
+ String sub = (String) CHAR_MAP.valAt(c);
+ if(sub != null)
+ sb.append(sub);
+ else
+ sb.append(c);
+ }
+ return sb.toString();
+}
- public void emitExpression() throws Exception {
- throw new UnsupportedOperationException();
- }
+enum C{
+ STATEMENT, EXPRESSION, RETURN, FN
+}
- public String emitExpressionString() throws Exception {
- StringWriter w = new StringWriter();
- try
- {
- _CRT_OUT.pushThreadBinding(w);
- emitExpression();
- return w.toString();
- }
- finally
- {
- _CRT_OUT.popThreadBinding();
- }
- }
+interface Expr{
- public Class getHostType() throws Exception {
- return null;
- }
+ void emitReturn() throws Exception;
- public boolean canEmitHostExpr() {
- return false;
- }
+ void emitStatement() throws Exception;
- public void emitHostExpr() throws Exception {
- throw new Exception("Can't emit as host expr");
- }
+ void emitExpression() throws Exception;
+ String emitExpressionString() throws Exception;
+
+ // may return null if clojure expression with no type hint, or host expression with unknown type
+ //cannot be used to distinguish host expr vs not
+ Class getHostType() throws Exception;
+
+ boolean canEmitHostExpr();
+
+ void emitHostExpr() throws Exception;
- public String toString() {
- try
- {
- return emitExpressionString();
- }
- catch (Exception e)
- {
- //declared exceptions are an incredibly bad idea !!!
- e.printStackTrace();
- return e.toString();
- }
- }
}
-static abstract class AHostExpr extends AnExpr {
+static void format(String str, Object... args) throws Exception{
+ RT.format(RT.T, str, args);
+}
- public boolean isHostExpr() {
- return false;
- }
+static class AnExpr implements Expr{
- public void emitExpression() throws Exception {
- Class hostType = getHostType();
- boolean needsBox = hostType == null
- || hostType.isPrimitive()
- || hostType == Boolean.class;
- if (needsBox)
- format("RT.box(");
- emitHostExpr();
- if (needsBox)
- format(")");
- }
+ public void emitReturn() throws Exception{
+ format("return ");
+ emitExpression();
+ format(";~%");
+ }
- public boolean canEmitHostExpr() {
- return true;
- }
+ public void emitStatement() throws Exception{
+ emitExpression();
+ format(";~%");
+ }
+ public void emitExpression() throws Exception{
+ throw new UnsupportedOperationException();
+ }
+
+ public String emitExpressionString() throws Exception{
+ StringWriter w = new StringWriter();
+ try
+ {
+ _CRT_OUT.pushThreadBinding(w);
+ emitExpression();
+ return w.toString();
+ }
+ finally
+ {
+ _CRT_OUT.popThreadBinding();
+ }
+ }
+
+ public Class getHostType() throws Exception{
+ return null;
+ }
+
+ public boolean canEmitHostExpr(){
+ return false;
+ }
+
+ public void emitHostExpr() throws Exception{
+ throw new Exception("Can't emit as host expr");
+ }
+
+
+ public String toString(){
+ try
+ {
+ return emitExpressionString();
+ }
+ catch(Exception e)
+ {
+ //declared exceptions are an incredibly bad idea !!!
+ e.printStackTrace();
+ return e.toString();
+ }
+ }
}
-public static void processForm(Object form) throws Exception {
- if (RT.first(form) == DEF)
- {
- convert(form);
- }
- else
- throw new UnsupportedOperationException();
-}
-
-private static void convert(Object form) throws Exception {
- Expr e = analyze(C.STATEMENT, form);
-}
-
-private static Expr analyze(C context, Object form) throws Exception {
- if (form == null)
- return NIL_EXPR;
- else if (form instanceof Symbol)
- return analyzeSymbol((Symbol) form, false);
- else if (form instanceof ISeq)
- return analyzeSeq(context, (ISeq) form);
- else if (form instanceof Num || form instanceof String)
- return new LiteralExpr(form);
- else if (form instanceof Character)
- return new CharExpr((Character) form);
- else
- throw new UnsupportedOperationException();
-}
-
-private static Expr analyzeSeq(C context, ISeq form) throws Exception {
- Object op = RT.first(form);
- if (op == DEF)
- return analyzeDef(context, form);
- else if (op == FN)
- return analyzeFn(context, form);
- else if (op == DO)
- return analyzeDo(context, form);
- else if (op == IF)
- return analyzeIf(context, form);
- else if (op == OR)
- return analyzeOr(context, form);
- else if (op == AND)
- return analyzeAnd(context, form);
- else if (op == LET)
- return analyzeLet(context, form);
- else if (op == LET_STAR_)
- return analyzeLetStar(context, form);
- else if (op == LETFN)
- return analyzeLetFn(context, form);
- else if (op == NOT || op == NULL_QM_)
- return analyzeNot(context, form);
- else
- {
- PersistentArrayList args = new PersistentArrayList(4);
- for (ISeq s = op instanceof InstanceMemberSymbol ? RT.rrest(form) : RT.rest(form); s != null; s = s.rest())
- args = args.cons(analyze(C.EXPRESSION, macroexpand(s.first())));
-
- if (op instanceof ClassSymbol)
- return new InvokeConstructorExpr((ClassSymbol) op, args);
- else if (op instanceof StaticMemberSymbol)
- return new InvokeStaticMethodExpr((StaticMemberSymbol) op, args);
- else if (op instanceof InstanceMemberSymbol)
- return analyzeInstanceInvoke((InstanceMemberSymbol) op,
- analyze(C.EXPRESSION, macroexpand(RT.second(form))),
- args);
-
-