diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-09-22 18:29:04 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-09-22 18:29:04 +0000 |
commit | 6b248387e7631748011afccb65c495b635806d45 (patch) | |
tree | aafeeb77c3290c5d366c69d5631a038675694bbd /src | |
parent | d43857f2e302f4307f2b8b201704b84b5286b567 (diff) |
refactoring, commented out test mains
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ArgVector.java | 97 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LockingTransaction.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/OldCompiler.java | 1998 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashMap.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentQueue.java | 17 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentTreeMap.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ThreadLocalData.java | 93 | ||||
-rw-r--r-- | src/jvm/clojure/lang/TransactionalHashMap.java | 4 |
13 files changed, 38 insertions, 2216 deletions
diff --git a/src/boot.clj b/src/boot.clj index 5210c76b..feb835f2 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -1,3 +1,11 @@ +; 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. + (def list (fn [& args] args)) (def cons (fn [x seq] (. RT (cons x seq)))) (def conj (fn [coll x] (. RT (conj coll x)))) diff --git a/src/jvm/clojure/lang/ArgVector.java b/src/jvm/clojure/lang/ArgVector.java deleted file mode 100644 index 7e18310c..00000000 --- a/src/jvm/clojure/lang/ArgVector.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * 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 Aug 19, 2007 */ - -package clojure.lang; - -import java.util.List; - -public class ArgVector extends Obj implements IPersistentVector, IPersistentList{ - -final PersistentVector impl; - -public static final ArgVector EMPTY = new ArgVector(PersistentVector.EMPTY); - -static public ArgVector create(ISeq items){ - return new ArgVector(PersistentVector.create(items)); -} - -static public ArgVector create(List items){ - return new ArgVector(PersistentVector.create(items)); -} - -static public ArgVector create(Object... items){ - return new ArgVector(PersistentVector.create(items)); -} - -private ArgVector(PersistentVector impl){ - this.impl = impl; -} - -private ArgVector(IPersistentMap meta, PersistentVector impl){ - super(meta); - this.impl = impl; -} - -public Obj withMeta(IPersistentMap meta){ - if(meta != this.meta()) - return new ArgVector(meta, impl); - return this; -} - -public int length(){ - return impl.length(); -} - -public Object nth(int i){ - return impl.nth(i); -} - -public IPersistentVector assocN(int i, Object val){ - return new ArgVector(meta(), impl.assocN(i, val)); -} - -public boolean contains(Object key){ - return impl.contains(key); -} - -public IMapEntry entryAt(Object key){ - return impl.entryAt(key); -} - -public Associative assoc(Object key, Object val){ - return new ArgVector(meta(), impl.assoc(key, val)); -} - -public Object valAt(Object key){ - return impl.valAt(key); -} - -public int count(){ - return impl.count(); -} - -public ISeq seq(){ - return impl.seq(); -} - -public IPersistentCollection cons(Object o){ - return new ArgVector(meta(), impl.cons(o)); -} - -public Object peek(){ - return impl.peek(); -} - -public IPersistentList pop(){ - return new ArgVector(meta(), impl.pop()); -} -} diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 9035da7a..5ec414f2 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -1845,9 +1845,9 @@ static class FnExpr implements Expr{ //derived from AFn/RestFn ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); // ClassWriter cw = new ClassWriter(0); - //ClassVisitor cv = cw; + ClassVisitor cv = cw; //ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out)); - ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out)); + //ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out)); cv.visit(V1_5, ACC_PUBLIC, internalName, null, isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFn", null); String source = (String) SOURCE.get(); String smap = "SMAP\n" + @@ -2681,13 +2681,15 @@ public static void main(String[] args){ { Var.pushThreadBindings( RT.map(LOADER, new DynamicClassLoader())); + w.write("> "); + w.flush(); Object r = LispReader.read(rdr, false, EOF, false); if(r == EOF) break; Object ret = eval(r); RT.print(ret, w); w.write('\n'); - w.flush(); + //w.flush(); } catch(Exception e) { diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index aba23a7c..9fb0db35 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -624,6 +624,7 @@ public static List readDelimitedList(char delim, PushbackReader r, boolean isRec return a;
}
+/*
public static void main(String[] args){
LineNumberingPushbackReader r = new LineNumberingPushbackReader(new InputStreamReader(System.in));
OutputStreamWriter w = new OutputStreamWriter(System.out);
@@ -646,7 +647,7 @@ public static void main(String[] args){ e.printStackTrace();
}
}
-
+ */
}
diff --git a/src/jvm/clojure/lang/LockingTransaction.java b/src/jvm/clojure/lang/LockingTransaction.java index 4ccdd8ab..84372f35 100644 --- a/src/jvm/clojure/lang/LockingTransaction.java +++ b/src/jvm/clojure/lang/LockingTransaction.java @@ -348,7 +348,7 @@ Object doCommute(Ref ref, IFn fn) throws Exception{ return ret; } - +/* //for test static CyclicBarrier barrier; static ArrayList<Ref> items; @@ -507,5 +507,5 @@ public static void main(String[] args){ ex.printStackTrace(); } } - +*/ } diff --git a/src/jvm/clojure/lang/OldCompiler.java b/src/jvm/clojure/lang/OldCompiler.java deleted file mode 100644 index 2ae5d2d0..00000000 --- a/src/jvm/clojure/lang/OldCompiler.java +++ /dev/null @@ -1,1998 +0,0 @@ -/** - * 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 Sep 3, 2006 */ - -package clojure.lang; - -import java.io.StringWriter; -import java.io.InputStreamReader; -import java.io.FileInputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -public class OldCompiler{ -//* -static Symbol DEF = Symbol.create("def"); -static Symbol FN = Symbol.create("fn"); -static Symbol DO = Symbol.create("do"); -static Symbol IF = Symbol.create("if"); -static Symbol OR = Symbol.create("or"); -static Symbol AND = Symbol.create("and"); -static Symbol LET = Symbol.create("let"); -static Symbol LET_STAR_ = Symbol.create("let*"); -static Symbol LETFN = Symbol.create("letfn"); -static Symbol NOT = Symbol.create("not"); -static Symbol NULL_QM_ = Symbol.create("null?"); - -static Symbol IMPORT = Symbol.create("import"); -static Symbol USE = Symbol.create("use"); -static Symbol _AMP_KEY = Symbol.create("&key"); -static Symbol _AMP_REST = Symbol.create("&rest"); - -static public Var _CRT_OUT = RT.OUT; -static public Var _CRT_MODULE = RT.CURRENT_MODULE; - -static NilExpr NIL_EXPR = new NilExpr(); - -//short-name-string->full-name-string -static public Var IMPORTS = Var.create(); - -//keyword->keywordexpr -static public Var KEYWORDS = Var.create(); - -//var->var -static public Var VARS = Var.create(); - -//symbol->localbinding -static public Var LOCAL_ENV = Var.create(); - - -//FnFrame -static public Var METHOD = Var.create(); - -//module->module -static public Var USES = Var.create(); - - -//ISeq FnExprs -static public Var FNS = Var.create(); - -static public IPersistentMap CHAR_MAP = - new PersistentArrayMap(new Object[]{'-', "_DASH_", - '.', "_DOT_", - ':', "_COLON_", - '+', "_PLUS_", - '>', "_GT_", - '<', "_LT_", - '=', "_EQ_", - '~', "_TILDE_", - '!', "_BANG_", - '@', "_CIRCA_", - '#', "_SHARP_", - '$', "_DOLLARSIGN_", - '%', "_PERCENT_", - '^', "_CARET_", - '&', "_AMPERSAND_", - '*', "_STAR_", - '{', "_LBRACE_", - '}', "_RBRACE_", - '[', "_LBRACK_", - ']', "_RBRACK_", - '/', "_SLASH_", - '\\', "_BSLASH_", - '?', "_QMARK_"}); - -private static final int MAX_POSITIONAL_ARITY = 20; - - -static String compile(String ns, String className, LineNumberingPushbackReader... files) throws Exception{ - StringWriter w = new StringWriter(); - try - { - Var.pushThreadBindings( - RT.map( - _CRT_OUT, w, - KEYWORDS, null, - VARS, null, - METHOD, null, - LOCAL_ENV, null, - FNS, PersistentVector.EMPTY)); - - format("/* Generated by Clojure */~%~%"); - format("package ~A;~%", ns); - format("import clojure.lang.*;~%~%"); - format("public class ~A{~%", className); - - PersistentVector forms = PersistentVector.EMPTY; - for(LineNumberingPushbackReader reader : files) - { - try - { - Var.pushThreadBindings( - RT.map( - IMPORTS, null, - USES, 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.get(); - 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(importMap, iclassName, pkg + "." + iclassName); - } - IMPORTS.set(importMap); - } - else if(op == USE) - { - //todo implement use - } - else - forms = forms.cons(analyze(C.STATEMENT, form)); - } - } - finally - { - Var.popThreadBindings(); - } - } - //declare static members for keywords, vars - for(ISeq keys = RT.seq(KEYWORDS.get()); keys != null; keys = keys.rest()) - { - KeywordExpr k = (KeywordExpr) ((IMapEntry) keys.first()).val(); - format("static Keyword ~A;~%", k.emitExpressionString()); - } - for(ISeq vars = RT.seq(VARS.get()); vars != null; vars = vars.rest()) - { - Var v = (Var) ((IMapEntry) vars.first()).val(); - format("static DynamicVar ~A;~%", munge(v.toString())); - } - - //todo declare static members for syms, quoted aggregates - - //emit nested static class/method declarations for nested fns - PersistentVector fns = (PersistentVector) FNS.get(); - 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.get()); 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.get()); 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 - { - Var.popThreadBindings(); - } - return w.toString(); -} - -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(); -} - -enum C{ - STATEMENT, EXPRESSION, RETURN, EVAL -} - -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(";~%"); - } - - 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 - { - Var.pushThreadBindings(RT.map(_CRT_OUT, w)); - emitExpression(); - return w.toString(); - } - finally - { - Var.popThreadBindings(); - } - } - - 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 !!! - throw new RuntimeException(e); - } - } -} - -static abstract class AHostExpr extends AnExpr{ - - public boolean isHostExpr(){ - return false; - } - - 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 boolean canEmitHostExpr(){ - return true; - } - -} - -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 - { - PersistentVector args = PersistentVector.EMPTY; - for(ISeq s = op instanceof InstanceMemberInvoker ? 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 StaticMemberInvoker) - return new InvokeStaticMethodExpr((StaticMemberInvoker) op, args); - else if(op instanceof InstanceMemberInvoker) - return analyzeInstanceInvoke((InstanceMemberInvoker) op, - analyze(C.EXPRESSION, macroexpand(RT.second(form))), - args); - - - Expr fexpr = (op instanceof Symbol) ? analyzeSymbol((Symbol) op, true) : analyze(C.EXPRESSION, op); - if(fexpr instanceof FnExpr) - ((FnExpr) fexpr).isCalledDirectly = true; - return new InvokeExpr(fexpr, args); - } -} - -private static Expr analyzeInstanceInvoke(InstanceMemberInvoker sym, Expr target, PersistentVector args) - throws Exception{ - Class targetClass = null; - if(sym.className != null) - targetClass = getTypeNamed(resolveHostClassname(sym.className)); - else if(target.getHostType() != null) - targetClass = target.getHostType(); - else //must make reflection-based call - return new InvokeUntypedInstanceMemberExpr(sym.memberName, target, args); - return new InvokeInstanceMemberExpr(targetClass, sym.memberName, target, args); -} - -static class InvokeExpr extends AnExpr{ - Expr fexpr; - PersistentVector args; - - public InvokeExpr(Expr fexpr, PersistentVector args){ - this.fexpr = fexpr; - this.args = args; - } - - public void emitExpression() throws Exception{ - FnExpr staticMethod = null; - ISeq argseq = RT.seq(args); - if(fexpr instanceof FnExpr && ((FnExpr) fexpr).willBeStaticMethod()) - staticMethod = (FnExpr) fexpr; - else if(fexpr instanceof LocalBindingExpr && ((LocalBindingExpr) fexpr).b.bindsToStaticFn()) - staticMethod = ((LocalBindingExpr) fexpr).b.letfn; - if(staticMethod != null) - { - ISeq closes = RT.keys(staticMethod.closes); - format("~A(~{~A~^, ~}", staticMethod.getName(), closes); - if(closes != null && argseq != null) - format(","); - format("~{~A~^, ~})", argseq); - } - else - { - format("((IFn)~A).invoke(~{~A~^, ~})", fexpr, argseq); - } - } -} - -/* -static class InvokeConstructorExpr extends AHostExpr{ - HostClassExpr fexpr; - PersistentVector args; - - public InvokeConstructorExpr(ClassSymbol fexpr, PersistentVector args) throws Exception{ - this.fexpr = new HostClassExpr(fexpr); - this.args = args; - } - - public Class getHostType() throws Exception{ - return fexpr.type; - } - - public void emitHostExpr() throws Exception{ - Constructor ctor = findSingleConstructor(fexpr.type, args); - - format("(new ~A(", fexpr.resolvedClassName); - if(ctor != null) - emitTypedArgs(ctor.getParameterTypes(), args, ctor.isVarArgs()); - else - emitHostArgs(args); - format("))"); - } -} -*/ - -static class InvokeStaticMethodExpr extends AHostExpr{ - final StaticMemberInvoker sym; - final String resolvedClassName; - final Class type; - PersistentVector args; - final Method method; - final Class returnType; - - public InvokeStaticMethodExpr(StaticMemberInvoker sym, PersistentVector args) throws Exception{ - this.sym = sym; - this.args = args; - this.resolvedClassName = resolveHostClassname(sym.className); - this.type = getTypeNamed(resolvedClassName); - Object sm = findSingleMethod(type, sym.memberName, args, true); - if(sm instanceof Method) - { - method = (Method) sm; - returnType = method.getReturnType(); - } - else if(sm instanceof Class) - { - method = null; - returnType = (Class) sm; - } - else - { - method = null; - returnType = null; - } - } - - public Class getHostType() throws Exception{ - return returnType; - } - - public void emitHostExpr() throws Exception{ - format("~A.~A(", resolvedClassName, sym.memberName); - if(method != null) - emitTypedArgs(method.getParameterTypes(), args, method.isVarArgs()); - else - emitHostArgs(args); - format(")"); - } -} - -static class InvokeUntypedInstanceMemberExpr extends AnExpr{ - final String name; - final Expr target; - PersistentVector args; - - public InvokeUntypedInstanceMemberExpr(String name, Expr target, PersistentVector args) throws Exception{ - this.name = name; - this.args = args; - this.target = target; - } - - public void emitExpression() throws Exception{ - format("Reflector.invokeInstanceMember(~S,~A~{,~A~})", name, target, RT.seq(args)); - } - -} - -static class InvokeInstanceMemberExpr extends AHostExpr{ - final String name; - final Expr target; - PersistentVector args; - final Class targetType; - final Field field; - final Method method; - final Class returnType; - - public InvokeInstanceMemberExpr(Class targetClass, String name, Expr target, PersistentVector args) - throws Exception{ - this.name = name; - this.args = args; - this.target = target; - this.targetType = targetClass; - field = Reflector.getField(targetClass, name, false); - if(field != null) - { - method = null; - returnType = field.getType(); - } - else - { - Object sm = findSingleMethod(targetClass, name, args, false); - if(sm instanceof Method) - { - method = (Method) sm; - returnType = method.getReturnType(); - } - else if(sm instanceof Class) - { - method = null; - returnType = (Class) sm; - } - else - { - method = null; - returnType = null; - } - } - } - - public Class getHostType() throws Exception{ - return returnType; - } - - public void emitHostExpr() throws Exception{ - if(target.canEmitHostExpr()) - target.emitHostExpr(); - else - emitConvert(targetType, target); - if(field != null) - { - format(".~A", name); - } - else - { - format(".~A(", name); - if(method != null) - emitTypedArgs(method.getParameterTypes(), args, method.isVarArgs()); - else - emitHostArgs(args); - format(")"); - } - } - -} - -static void emitHostArgs(PersistentVector args) throws Exception{ - for(int i = 0; i < args.count(); i++) - { - Expr arg = (Expr) args.nth(i); - if(arg.canEmitHostExpr()) - arg.emitHostExpr(); - else if(arg.getHostType() != null) - emitConvert(arg.getHostType(), arg); - else - arg.emitExpression(); - if(i < args.count() - 1) - format(","); - } - -} - -static void emitTypedArgs(Class[] parameterTypes, PersistentVector args, boolean isVariadic) throws Exception{ - for(int i = 0; i < (isVariadic ? parameterTypes.length - 1 : args.count()); i++) - { - Expr arg = (Expr) args.nth(i); - if(arg.canEmitHostExpr()) - arg.emitHostExpr(); - else - emitConvert(parameterTypes[i], arg); - if(i < args.count() - 1) - format(","); - } - - if(isVariadic) - { - Class vtype = parameterTypes[parameterTypes.length - 1].getComponentType(); - for(int i = parameterTypes.length - 1; i < args.count(); i++) - { - Expr arg = (Expr) args.nth(i); - if(arg.canEmitHostExpr()) - arg.emitHostExpr(); - else - emitConvert(vtype, arg); - if(i < args.count() - 1) - format(","); - } - } -} - -static void emitConvert(Class parameterType, Expr arg) throws Exception{ - if(parameterType == Object.class) - arg.emitExpression(); - else if(parameterType == boolean.class || parameterType == Boolean.class) - format("(~A!=null)", arg); - else if(parameterType == int.class || parameterType == Integer.class) - format("((Number)~A).intValue()", arg); - else if(parameterType == double.class || parameterType == Double.class) - format("((Number)~A).doubleValue()", arg); - else if(parameterType == float.class || parameterType == Float.class) - format("((Number)~A).floatValue()", arg); - else if(parameterType == long.class || parameterType == Long.class) - format("((Number)~A).longValue()", arg); - else if(parameterType == short.class || parameterType == Short.class) - format("((Number)~A).shortValue()", arg); - else if(parameterType == byte.class || parameterType == Byte.class) - format("((Number)~A).byteValue()", arg); - else - format("((~A)~A)", parameterType.getName(), arg); -} - -/* -static void emitCast(Class parameterType, Expr arg) throws Exception { - Class hostType = arg.getHostType(); - boolean needsCast = false; - //parameterType != Object.class && (hostType == null || !parameterType.isAssignableFrom(hostType)); - if (needsCast) - format("((~A)", parameterType.getName()); - arg.emitHostExpr(); - if (needsCast) - format(")"); -} -*/ - -/*returns null unless single ctor with matching arity, throws if no ctor can handle arity*/ - -public static Constructor findSingleConstructor(Class c, PersistentVector args) throws Exception{ - Constructor[] allctors = c.getConstructors(); - Constructor found = null; - for(int i = 0; i < allctors.length; i++) - { - Constructor ctor = allctors[i]; - if(ctor.getParameterTypes().length == args.count() - || (ctor.isVarArgs() && ctor.getParameterTypes().length <= args.count())) - { - if(found == null) - found = ctor; - else - return null; //more than one matching - } - } - //verify that at least one ctor can handle arity (requires variadic detection) - if(found == null) - throw new Exception("No constructor that can handle arity"); - return found; -} - -/*returns Method if single method with matching arity, - returns Class of return type if all methods with same arity have same return type - else returns null - throws if no method can handle arity*/ - -public static Object findSingleMethod(Class c, String methodName, PersistentVector args, boolean isStatic) - throws Exception{ - Method[] allmethods = c.getMethods(); - Method found = null; - int foundCount = 0; - boolean returnsMatch = true; - for(int i = 0; i < allmethods.length; i++) - { - Method method = allmethods[i]; - if(Modifier.isStatic(method.getModifiers()) == isStatic - && method.getName().equals(methodName) - && (method.getParameterTypes().length == args.count() - || (method.isVarArgs() && method.getParameterTypes().length <= args.count()))) - { - if(found == null) - { - found = method; - foundCount = 1; - } - else - { - ++foundCount; - if(method.getReturnType() != found.getReturnType()) - returnsMatch = false; - } - } - } - //verify that at least one method can handle arity (requires variadic detection) - if(foundCount == 0) - throw new Exception("No method that can handle arity"); - else if(foundCount == 1) - return found; - else if(returnsMatch) - return found.getReturnType(); - return null; -} - -private static Expr analyzeLet(C context, ISeq form) throws Exception{ - //(let (var val var2 val2 ...) body...) - ISeq bindings = (ISeq) RT.second(form); - //special case (let () expr) ==> expr - if(bindings == null && form.count() < 4) - return analyze(context, macroexpand(RT.third(form))); - ISeq body = RT.rest(RT.rest(form)); - - if(context == C.EXPRESSION) - { - //(let (a b) c) -> ((fn (a) c) b) - PersistentVector parms = PersistentVector.EMPTY; - PersistentVector args = PersistentVector.EMPTY; - for(ISeq bs = bindings; bs != null; bs = RT.rest(RT.rest(bs))) - { - parms = parms.cons(RT.first(bs)); - args = args.cons(RT.second(bs)); - } - return analyze(context, RT.cons(RT.listStar(FN, RT.seq(parms), body), RT.seq(args))); - } - - PersistentVector bindingInits = PersistentVector.EMPTY; - //analyze inits before adding bindings to env - for(ISeq bs = bindings; bs != null; bs = RT.rest(RT.rest(bs))) - { - LocalBinding lb = new LocalBinding(baseSymbol((Symbol) RT.first(bs))); - lb.typeHint = typeHint((Symbol) RT.first(bs)); - bindingInits = bindingInits.cons(new BindingInit(lb, analyze(C.EXPRESSION, RT.second(bs)))); - } - try - { - Var.pushThreadBindings(RT.map(LOCAL_ENV, LOCAL_ENV.get())); - for(int i = 0; i < bindingInits.count(); i++) - { - BindingInit bi = (BindingInit) bindingInits.nth(i); - if(bi.init instanceof FnExpr) - { - bi.binding.letfn = (FnExpr) bi.init; - ((FnExpr) bi.init).binding = bi.binding; - } - registerLocal(bi.binding); - } - return new LetExpr(bindingInits, analyzeBody(context, body)); - } - finally - { - Var.popThreadBindings(); - } - -} - -private static Expr analyzeLetFn(C context, ISeq form) throws Exception{ - //(letfn ((foo [what can occur after fn]) (bar [what can occur after fn])) body ...) - if(context == C.EXPRESSION) - return analyze(context, RT.list(RT.list(FN, null, form))); - try - { - Var.pushThreadBindings(RT.map(LOCAL_ENV, LOCAL_ENV.get())); - ISeq bindings = (ISeq) RT.second(form); - ISeq body = RT.rest(RT.rest(form)); - PersistentVector bindingPairs = PersistentVector.EMPTY; - //add all fn names to env before analyzing bodies - for(ISeq bs = bindings; bs != null; bs = RT.rest(bs)) - { - Object bform = RT.first(bs); - Symbol fsym = (Symbol) RT.first(bform); - LocalBinding lb = new LocalBinding(baseSymbol(fsym)); - lb.typeHint = typeHint(fsym); - registerLocal(lb); - bindingPairs = bindingPairs.cons(PersistentVector.create(lb, RT.cons(FN, RT.rest(bform)))); - } - - PersistentVector bindingInits = PersistentVector.EMPTY; - for(int i = 0; i < bindingPairs.count(); i++) - { - IPersistentVector bpair = (IPersistentVector) bindingPairs.nth(i); - LocalBinding lb = (LocalBinding) bpair.nth(0); - FnExpr fexpr = (FnExpr) analyze(C.EXPRESSION, bpair.nth(1)); - fexpr.binding = lb; - lb.letfn = fexpr; - bindingInits = bindingInits.cons(new BindingInit(lb, fexpr)); - } - return new LetExpr(bindingInits, analyzeBody(context, body)); - } - finally - { - Var.popThreadBindings(); - } - -} - -private static Expr analyzeLetStar(C context, ISeq form) throws Exception{ - //(let* (var val var2 val2 ...) body...) - ISeq bindings = (ISeq) RT.second(form); - //special case (let* () expr) ==> expr - if(bindings == null && form.count() < 4) - return analyze(context, macroexpand(RT.third(form))); - ISeq body = RT.rest(RT.rest(form)); - - if(context == C.EXPRESSION) - return analyze(context, RT.list(RT.list(FN, null, form))); - - try - { - Var.pushThreadBindings(RT.map(LOCAL_ENV, LOCAL_ENV.get())); - PersistentVector bindingInits = PersistentVector.EMPTY; - for(ISeq bs = bindings; bs != null; bs = RT.rest(RT.rest(bs))) - { - LocalBinding lb = new LocalBinding(baseSymbol((Symbol) RT.first(bs))); - lb.typeHint = typeHint((Symbol) RT.first(bs)); - BindingInit bi = new BindingInit(lb, analyze(C.EXPRESSION, RT.second(bs))); - bindingInits = bindingInits.cons(bi); - if(bi.init instanceof FnExpr) - { - bi.binding.letfn = (FnExpr) bi.init; - ((FnExpr) bi.init).binding = bi.binding; - } - //sequential enhancement of env - registerLocal(lb); - } - - return new LetExpr(bindingInits, analyzeBody(context, body)); - } - finally - { - Var.popThreadBindings(); - } - -} - -static class LetExpr extends AnExpr{ - PersistentVector bindingInits; - Expr body; - - public LetExpr(PersistentVector bindingInits, Expr body){ - this.bindingInits = bindingInits; - this.body = body; - } - - public void emitStatement() throws Exception{ - emitBindings(); - body.emitStatement(); - } - - private void emitBindings() throws Exception{ - for(int i = 0; i < bindingInits.count(); i++) - { - BindingInit bi = (BindingInit) bindingInits.nth(i); - if(!(bi.init instanceof FnExpr && ((FnExpr) bi.init).willBeStaticMethod())) - format("~A = ~A;~%", bi.binding.getExpr(), bi.init.emitExpressionString()); - } - } - - public void emitReturn() throws Exception{ - emitBindings(); - body.emitReturn(); - } - -} - -static class BindingInit{ - LocalBinding binding; - Expr init; - - public BindingInit(LocalBinding binding, Expr init){ - this.binding = binding; - this.init = init; - } -} - -private static Expr analyzeAnd(C context, ISeq form) throws Exception{ - //(and) (and x) (and x y ...) - //(or) (or X) (or x y ...) - if(RT.count(form) == 1) - return analyze(context, RT.T); - else if(RT.count(form) == 2) - return analyze(context, macroexpand(RT.second(form))); - - PersistentVector exprs = PersistentVector.EMPTY; - for(ISeq es = RT.rest(form); es != null; es = es.rest()) - exprs = exprs.cons(analyze(C.EXPRESSION, macroexpand(es.first()))); - return new AndExpr(exprs); -} - -static class AndExpr extends AnExpr{ - final PersistentVector exprs; - - public AndExpr(PersistentVector exprs){ - this.exprs = exprs; - } - - public void emitStatement() throws Exception{ - format("if("); - for(int i = 0; i < exprs.count(); i++) - { - format("~A != null", ((Expr) exprs.nth(i)).emitExpressionString()); - if(i < exprs.count() - 1) - format(" && "); - } - format(")~%;~%"); - } - - public void emitExpression() throws Exception{ - format("(("); - for(int i = 0; i < exprs.count(); i++) - { - if(i < exprs.count() - 1) - format("~A != null", ((Expr) exprs.nth(i)).emitExpressionString()); - if(i < exprs.count() - 2) - format(" && "); - if(i == exprs.count() - 1) - format(")?~A:null)", ((Expr) exprs.nth(i)).emitExpressionString()); - } - } -} - -private static Expr analyzeOr(C context, ISeq form) throws Exception{ - //(or) (or X) (or x y ...) - if(RT.count(form) == 1) - return NIL_EXPR; - else if(RT.count(form) == 2) - return analyze(context, macroexpand(RT.second(form))); - - LocalBinding tb = null; - if(context != C.STATEMENT) - { - //we'll need a temp var - tb = new LocalBinding(Symbol.create("OR_TEMP")); - registerLocal(tb); - } - - PersistentVector exprs = PersistentVector.EMPTY; - for(ISeq es = RT.rest(form); es != null; es = es.rest()) - exprs = exprs.cons(analyze(C.EXPRESSION, macroexpand(es.first()))); - return new OrExpr(exprs, tb); -} - -static class OrExpr extends AnExpr{ - final PersistentVector exprs; - final LocalBinding tb; - - public OrExpr(PersistentVector exprs, LocalBinding tb){ - this.exprs = exprs; - this.tb = tb; - } - - public void emitStatement() throws Exception{ - format("if("); - for(int i = 0; i < exprs.count(); i++) - { - format("~A != null", ((Expr) exprs.nth(i)).emitExpressionString()); - if(i < exprs.count() - 1) - format(" || "); - } - format(")~%;~%"); - } - - public void emitExpression() throws Exception{ - format("(("); - for(int i = 0; i < exprs.count(); i++) - { - format("(~A = ~A) != null", tb.getName(), ((Expr) exprs.nth(i)).emitExpressionString()); - if(i < exprs.count() - 1) - format(" || "); - } - format(")?~A:null)", tb.getName()); - } -} - -private static Expr analyzeNot(C context, ISeq form) throws Exception{ - //(not x) or (null? x) - //hmmm - will these be the same with host boolean arg? - return new NotExpr(analyze(C.EXPRESSION, macroexpand(RT.second(form)))); - -} - -private static Expr analyzeIf(C context, ISeq form) throws Exception{ - //(if test then) or (if test then else) - if(RT.second(form) == RT.T) //optimize macro-generated (if :t ...) forms - return analyze(context, macroexpand(RT.third(form))); - else if(RT.second(form) == null) - return analyze(context, macroexpand(RT.fourth(form))); - Expr testExpr = analyze(C.EXPRESSION, macroexpand(RT.second(form))); - String compare = "!="; - //lift tests that are not exprs by taking value as test and inverting compare - if(testExpr instanceof NotExpr) - { - testExpr = ((NotExpr) testExpr).expr; - compare = "=="; - } - return new IfExpr(testExpr, compare, analyze(context, macroexpand(RT.third(form))), - analyze(context, macroexpand(RT.fourth(form)))); -} - -private static Expr analyzeDo(C context, ISeq form) throws Exception{ - //(do ...) - //(do) == null - if(RT.rest(form) == null) - return NIL_EXPR; - else if(RT.rest(RT.rest(form)) == null) //(do x) == x - return analyze(context, macroexpand(RT.second(form))); - else if(context == C.EXPRESSION) - return analyze(context, RT.list(RT.cons(FN, RT.cons(null, RT.rest(form))))); - else - return analyzeBody(context, RT.rest(form)); - -} - -static class IfExpr extends AnExpr{ - final Expr testExpr; - final String compare; - final Expr thenExpr; - final Expr elseExpr; - - public IfExpr(Expr testExpr, String compare, Expr thenExpr, Expr elseExpr){ - this.testExpr = testExpr; - this.compare = compare; - this.thenExpr = thenExpr; - this.elseExpr = elseExpr; - } - - public void emitReturn() throws Exception{ - format("if(~A ~A null)~%", testExpr.emitExpressionString(), compare); - format("{~%"); - thenExpr.emitReturn(); - format("}~%"); - format("else~%"); - format("{~%"); - elseExpr.emitReturn(); - format("}~%"); - } - - public void emitStatement() throws Exception{ - format("if(~A ~A null)~%", testExpr.emitExpressionString(), compare); - format("{~%"); - thenExpr.emitStatement(); - format("}~%"); - if(!(elseExpr instanceof NilExpr)) - { - format("else~%"); - format("{~%"); - elseExpr.emitStatement(); - format("}~%"); - } - } - - public void emitExpression() throws Exception{ - format("(~A ~A null?", testExpr.emitExpressionString(), compare); - thenExpr.emitExpression(); - format(":"); - elseExpr.emitExpression(); - format(")"); - } -} - -private static Expr analyzeBody(C context, ISeq forms) throws Exception{ - PersistentVector exprs = PersistentVector.EMPTY; - for(; forms != null; forms = forms.rest()) - { - Expr e = (context == C.STATEMENT || RT.rest(forms) != null) ? - analyze(C.STATEMENT, macroexpand(forms.first())) - : - analyze(C.RETURN, macroexpand(forms.first())); - exprs = exprs.cons(e); - } - return new BodyExpr(exprs); -} - -static class BodyExpr extends AnExpr{ - PersistentVector exprs; - - public BodyExpr(PersistentVector exprs){ - this.exprs = exprs; - } - - public void emitStatement() throws Exception{ - if(exprs.count() == 0) - return; - for(int i = 0; i < exprs.count(); i++) - ((Expr) exprs.nth(i)).emitStatement(); - } - - public void emitReturn() throws Exception{ - if(exprs.count() == 0) - NIL_EXPR.emitReturn(); - else - { - for(int i = 0; i < exprs.count(); i++) - { - if(i < exprs.count() - 1) - ((Expr) exprs.nth(i)).emitStatement(); - else - ((Expr) exprs.nth(i)).emitReturn(); - } - } - } -} - -private static Expr analyzeFn(C context, ISeq form) throws Exception{ - //(fn (args) body) or (fn ((args) body) ((args2) body2) ...) - //turn former into latter - if(RT.second(form) == null || - !(RT.first(RT.second(form)) == null || RT.first(RT.second(form)) instanceof ISeq)) - form = RT.list(FN, RT.rest(form)); - - FnMethod[] methodArray = new FnMethod[MAX_POSITIONAL_ARITY + 1]; - FnMethod variadicMethod = null; - FnExpr fn = new FnExpr(); - for(ISeq s = RT.rest(form); s != null; s = RT.rest(s)) - { - FnMethod f = analyzeMethod(fn, (ISeq) RT.first(s)); - if(f.isVariadic()) - { - if(variadicMethod == null) - variadicMethod = f; - else - throw new Exception("Can't have more than 1 variadic overload"); - } - else if(methodArray[f.reqParms.count()] == null) - methodArray[f.reqParms.count()] = f; - else - throw new Exception("Can't have 2 overloads with same arity"); - } - if(variadicMethod != null) - { - for(int i = variadicMethod.reqParms.count() + 1; i <= MAX_POSITIONAL_ARITY; i++) - if(methodArray[i] != null) - throw new Exception("Can't have fixed arity function with more params than variadic function"); - } - - IPersistentCollection methods = null; - for(int i = 0; i < methodArray.length; i++) - if(methodArray[i] != null) - methods = RT.conj(methods, methodArray[i]); - if(variadicMethod != null) - methods = RT.conj(methods, variadicMethod); - - fn.methods = methods; - fn.variadicMethod = variadicMethod; - registerFn(fn); - return fn; -} - -static class FnExpr extends AnExpr{ - IPersistentCollection methods; - FnMethod variadicMethod; - LocalBinding binding; - String name = null; - boolean isCalledDirectly = false; - //localbinding->itself - IPersistentMap closes = null; - - String getName(){ - if(name == null) - { - if(binding != null) - name = "FN__" + binding.getName();//munge(binding.sym.name) + "__" + RT.nextID(); - else - name = "FN__" + RT.nextID(); - } - return name; - } - - public void emitExpression() throws Exception{ - format("(new ~A(", getName()); - for(ISeq s = RT.seq(closes); s != null; s = s.rest()) - { - LocalBinding b = (LocalBinding) ((IMapEntry) s.first()).key(); - format("~A", b.getName()); - if(s.rest() != null) - format(","); - } - format("))"); - } - - public void emitDeclaration() throws Exception{ - PersistentVector closesDecls = null; - if(closes != null) - { - closesDecls = PersistentVector.EMPTY; - for(ISeq s = RT.seq(closes); s != null; s = s.rest()) - { - LocalBinding b = (LocalBinding) ((IMapEntry) s.first()).key(); - if(!b.bindsToStaticFn()) - { - closesDecls = closesDecls.cons(b.typeDeclaration()); - closesDecls = closesDecls.cons(b.getName()); - } - } - } - if(!willBeStaticMethod()) - { - //emit class declaration - format("static public class ~A extends ~A{~%", - getName(), - variadicMethod != null ? "clojure.lang.RestFn" : "AFn"); - - if(closes != null) - { - //emit members and ctor if closure - format("~{~A ~A;~%~}", closesDecls); - format("public ~A (~{~A ~A~^, ~}){~%", getName(), closesDecls); - if(variadicMethod != null) //must call base ctor - format("super(~A);~%", variadicMethod.reqParms.count()); - for(ISeq s = RT.seq(closes); s != null; s = s.rest()) - { - LocalBinding b = (LocalBinding) ((IMapEntry) s.first()).key(); - if(!b.bindsToStaticFn()) - { - format("this.~A = ~A;~%", b.getName(), b.getName()); - if(s.rest() != null) - format(","); - } - } - format("}~%"); - } - else if(variadicMethod != null) //must create ctor in order to call base ctor - { - format("public ~A (){~%", getName()); - format("super(~A);~%", variadicMethod.reqParms.count()); - format("}~%"); - } - - } - else - { - format("static public Object ~A(~{~A ~A~^, ~}", - getName(), - closesDecls); - } - - for(ISeq methods = RT.seq(this.methods); methods != null; methods = methods.rest()) - { - //this will run once if static method - FnMethod m = (FnMethod) methods.first(); - if(!willBeStaticMethod()) - format("public Object ~A(", m.isVariadic() ? "doInvoke" : "invoke"); - for(ISeq reqs = RT.seq(m.reqParms); reqs != null; reqs = reqs.rest()) - { - LocalBindingExpr be = (LocalBindingExpr) reqs.first(); - format("Object ~A", be.b.getName()); - if(be.b.needsBox()) - format("__arg"); - if(reqs.rest() != null) - format(","); - } - if(m.isVariadic()) - { - if(m.reqParms.count() > 0) - format(","); - format("ISeq "); - if(m.restParm != null) - { - format("~A", m.restParm.b.getName()); - if(m.restParm.b.needsBox()) - format("__arg"); - } - else - format("__keys"); - } - format(") throws Exception{~%"); - - //emit declarations for any boxed args - for(ISeq reqs = RT.seq(m.reqParms); reqs != null; reqs = reqs.rest()) - { - LocalBindingExpr be = (LocalBindingExpr) reqs.first(); - if(be.b.needsBox()) - be.b.emitDeclaration(be.b.getName() + "__arg"); - } - //emit declaration for any boxed rest arg - if(m.restParm != null && m.restParm.b.needsBox()) - m.restParm.b.emitDeclaration(m.restParm.b.getName() + "__arg"); - //keys are locals, plucked out of rest arg - if(m.keyParms != null) - { - format("ISeq __valseq = null;~%"); - for(ISeq keys = RT.seq(m.keyParms); keys != null; keys = keys.rest()) - { - KeyParam key = (KeyParam) keys.first(); -// KeywordExpr kw = registerKeyword((Keyword) Symbol.intern(":" + key.bindingExpression.b.sym.name)); -// format("__valseq = RT.findKey(~A,__keys);~%", kw.emitExpressionString()); -// key.bindingExpression.b.emitDeclaration( -// (String) RT.format(null, "(__valseq!=null)?clojure.lang.RT.first(__valseq):~A" -// , key.init.emitExpressionString())); - } - } - - //local variables - for(ISeq locals = RT.seq(m.locals); locals != null; locals = locals.rest()) - { - LocalBinding b = (LocalBinding) ((IMapEntry) locals.first()).key(); - if(!b.isParam && !b.bindsToStaticFn()) - b.emitDeclaration("null"); - } - - m.body.emitReturn(); - //end of function - format("}~%"); - } - - //end of class - if(!willBeStaticMethod()) - format("}~%"); - } - - boolean willBeStaticMethod(){ - return variadicMethod == null - && methods.count() == 1 - && - ( - isCalledDirectly - || - (binding != null && !binding.isAssigned && !binding.valueTaken) - ); - } -} - -static class FnMethod{ - FnMethod parent = null; - //localbinding->localbinding - IPersistentMap locals = null; - //localbinding->localbinding - PersistentVector reqParms = PersistentVector.EMPTY; - PersistentVector keyParms = null; - LocalBindingExpr restParm = null; - Expr body = null; - FnExpr fn; - - public FnMethod(FnExpr fn, FnMethod parent){ - this.parent = parent; - this.fn = fn; - } - - boolean isVariadic(){ - return keyParms != null || restParm != null; - } -} - -enum PSTATE{ - REQ, REST, KEY, DONE -} - -private static FnMethod analyzeMethod(FnExpr fn, ISeq form) throws Exception{ - //((args) body) - ISeq parms = (ISeq) RT.first(form); - ISeq body = RT.rest(form); - try - { - FnMethod method = new FnMethod(fn, (FnMethod) METHOD.get()); - Var.pushThreadBindings( - RT.map( - METHOD, method, - LOCAL_ENV, LOCAL_ENV.get())); - PSTATE state = PSTATE.REQ; - for(ISeq ps = parms; ps != null; ps = ps.rest()) - { - Object p = ps.first(); - if(p == _AMP_REST) - { - if(state == PSTATE.REQ) - state = PSTATE.REST; - else - throw new Exception("Invalid parameter list"); - } - else if(p == _AMP_KEY) - { - if(state == PSTATE.REQ) - { - state = PSTATE.KEY; - method.keyParms = PersistentVector.EMPTY; - } - else - throw new Exception("Invalid parameter list"); - } - else - { - switch(state) - { - case REQ: - method.reqParms = method.reqParms.cons(createParamBinding((Symbol) p)); - break; - case REST: - method.restParm = createParamBinding((Symbol) p); - state = PSTATE.DONE; - break; - case KEY: - if(p instanceof ISeq) - method.keyParms = method.keyParms.cons( - new KeyParam(createParamBinding((Symbol) RT.first(p)), - analyze(C.EXPRESSION, RT.second(p)))); - else - method.keyParms = method.keyParms.cons( - new KeyParam(createParamBinding((Symbol) p))); - - break; - default: - throw new Exception("Unexpected parameter"); - } - } - } - if(method.reqParms.count() > MAX_POSITIONAL_ARITY) - throw new Exception("Sorry, can't specify more than " + MAX_POSITIONAL_ARITY + " params"); - method.body = analyze(C.RETURN, RT.cons(DO, body)); - return method; - } - finally - { - Var.popThreadBindings(); - } -} - - -static LocalBindingExpr createParamBinding(Symbol p) throws Exception{ - Symbol basep = baseSymbol(p); - LocalBinding b = new LocalBinding(basep); - b.isParam = true; - String typeHint = typeHint(p); - b.typeHint = typeHint; - registerLocal(b); - return new LocalBindingExpr(b, typeHint); -} - -private static Expr analyzeDef(C context, ISeq form) throws Exception{ - //(def x) or (def x initexpr) - if(form.count() > 3) - throw new Exception("Too many arguments to def"); - Symbol sym = (Symbol) RT.second(form); - Module module = (Module) _CRT_MODULE.get(); - Var var = null;//!module.intern(baseSymbol(sym)); - registerVar(var); - VarExpr ve = new VarExpr(var, typeHint(sym)); - Expr init = analyze(C.EXPRESSION, macroexpand(RT.third(form))); -//! if(init instanceof FnExpr) -// ((FnExpr) init).name = "FN__" + munge(var.name.toString()) + "__" + RT.nextID(); - - return new DefExpr(ve, init); -} - -static Symbol baseSymbol(Symbol sym){ - String base = baseName(sym); - - if(base == sym.name) //no typeHint - return sym; - - return Symbol.intern(null, 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, boolean inFnPosition) throws Exception{ -// if(sym instanceof Keyword) -// return registerKeyword((Keyword) sym); -// else if(sym instanceof ClassSymbol) -// return new HostClassExpr((ClassSymbol) sym); -// else if(sym instanceof StaticMemberInvoker) -// return new HostStaticFieldExpr((StaticMemberInvoker) sym); -// //todo have InstanceMemberSymbol yield accessor when expression -// else - { - String typeHint = typeHint(sym); - sym = baseSymbol(sym); - LocalBinding b = referenceLocal(sym); - if(b != null) - { - if(!inFnPosition) - b.valueTaken = true; - 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) throws Exception{ - Module module = (Module) _CRT_MODULE.get(); -// Var v = module.find(sym); -// if(v != null) -// return v; -// for(ISeq seq = RT.seq(USES.get()); seq != null; seq = RT.rest(seq)) -// { -// module = (Module) ((IMapEntry) RT.first(seq)).key(); -// v = module.find(sym); -// if(v != null && !v.exported) -// return v; -// } - return null; -} - -static Object macroexpand(Object x){ - return x; //placeholder -} - -private static KeywordExpr registerKeyword(Keyword keyword) throws Exception{ - IPersistentMap keywordsMap = (IPersistentMap) KEYWORDS.get(); - KeywordExpr ke = (KeywordExpr) RT.get(keywordsMap, keyword); -//! if(ke == null) -//! KEYWORDS.set(RT.assoc(keyword, ke = new KeywordExpr(keyword), keywordsMap)); - return ke; -} - -private static void registerVar(Var var) throws Exception{ - IPersistentMap varsMap = (IPersistentMap) VARS.get(); - if(RT.get(varsMap, var) == null) - VARS.set(RT.assoc(varsMap, var, var)); -} - -private static void registerFn(FnExpr fn) throws Exception{ - FNS.set(RT.conj((IPersistentCollection) FNS.get(), fn)); -} - -static void closeOver(LocalBinding b, FnMethod method){ - if(b != null && method != null && RT.get(method.locals, b) == null) - { - b.isClosed = true; - method.fn.closes = (IPersistentMap) RT.assoc(method.fn.closes, b, b); - closeOver(b, method.parent); - } -} - -static LocalBinding referenceLocal(Symbol sym) throws Exception{ - LocalBinding b = (LocalBinding) RT.get(LOCAL_ENV.get(), sym); - if(b != null) - { - closeOver(b, (FnMethod) METHOD.get()); - } - return b; -} - -private static void registerLocal(LocalBinding b) throws Exception{ - IPersistentMap localsMap = (IPersistentMap) LOCAL_ENV.get(); - //!LOCAL_ENV.setValue(RT.assoc(b.sym, b, localsMap)); - FnMethod method = (FnMethod) METHOD.get(); - method.locals = (IPersistentMap) RT.assoc(method.locals, b, b); -} -/* -(defun reference-var (sym) - (let ((b (first (member sym *var-env* :key (lambda (b) - (@ :symbol b)))))) - (labels - ((check-closed (b frame) - (when (and b frame - (not (member b (@ :local-bindings frame)))) ;closed over - (setf (@ :closed? b) t) - (pushnew b (@ :closes frame)) - (check-closed b (@ :parent frame))))) - (check-closed b *frame*)) - b)) - */ - -static String resolveHostClassname(String classname) throws Exception{ - if(classname.indexOf('.') != -1) //presume fully qualified if contains . - return classname; - if(isPrimitive(classname)) - return classname; - IPersistentMap importMap = (IPersistentMap) IMPORTS.get(); - String fullyQualifiedName = (String) RT.get(importMap, classname); - if(fullyQualifiedName == null) - throw new Exception("Can't resolve type name: " + classname); - return fullyQualifiedName; -} - -static boolean isPrimitive(String classname){ - return classname.equals("int") - || classname.equals("double") - || classname.equals("float") - || classname.equals("long") - || classname.equals("boolean") - || classname.equals("char") - || classname.equals("short") - || classname.equals("byte"); -} - -static Class getTypeNamed(String classname) throws ClassNotFoundException{ - if(classname.equals("int")) - return int.class; - if(classname.equals("double")) - return double.class; - if(classname.equals("float")) - return float.class; - if(classname.equals("long")) - return long.class; - if(classname.equals("boolean")) - return boolean.class; - if(classname.equals("char")) - return char.class; - if(classname.equals("short")) - return short.class; - if(classname.equals("byte")) - return byte.class; - return Class.forName(classname); -} - - -static class KeyParam{ - 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) throws Exception{ - this(b, NIL_EXPR); - } - - LocalBindingExpr bindingExpression; - Expr init; - KeywordExpr kw; -} - - -static class NilExpr extends AnExpr{ - public void emitExpression() throws Exception{ - format("null"); - } -} - -static class LiteralExpr extends AnExpr{ - final Object val; - - public LiteralExpr(Object val){ - this.val = val; - } - - public void emitExpression() throws Exception{ - format("~S", val); - } - - public Class getHostType() throws Exception{ - if(val instanceof DoubleNum) - return double.class; - if(val instanceof FixNum) - return int.class; - return val.getClass(); - } - - public boolean canEmitHostExpr(){ - return val instanceof FixNum || val instanceof String || val instanceof DoubleNum; - } - - public void emitHostExpr() throws Exception{ - if(val instanceof FixNum) - format("~A", ((FixNum) val).val); - else if(val instanceof String) - format("~S", val); - else if(val instanceof DoubleNum) - format("~A", ((DoubleNum) val).val); - else - super.emitHostExpr(); - } -} - -static class NotExpr extends AnExpr{ - final Expr expr; - - public NotExpr(Expr expr){ - this.expr = expr; - } - - public void emitStatement() throws Exception{ - //just execute expr for side effects - no negation - expr.emitStatement(); - } - - public void emitExpression() throws Exception{ - format("(("); - expr.emitExpression(); - format("==null)?RT.T:null)"); - } - -} - -static class CharExpr extends AnExpr{ - final Character val; - - public CharExpr(Character val){ - this.val = val; - } - - public void emitExpression() throws Exception{ - format("'~A'", val); - } - - public Class getHostType() throws Exception{ - return char.class; - } - - public boolean canEmitHostExpr(){ - return true; - } - - public void emitHostExpr() throws Exception{ - emitExpression(); - } -} - -/* -static class HostClassExpr extends AHostExpr{ - final ClassSymbol sym; - final String resolvedClassName; - final Class type; - - public HostClassExpr(ClassSymbol sym) throws Exception{ - this.sym = sym; - this.resolvedClassName = resolveHostClassname(sym.className); - this.type = getTypeNamed(resolvedClassName); - } - - public void emitHostExpr() throws Exception{ - format("~A.class", resolvedClassName); - } - - public Class getHostType() throws Exception{ - return type; - } - -} -*/ -static class HostStaticFieldExpr extends AHostExpr{ - final StaticMemberInvoker sym; - final String resolvedClassName; - final Class type; - final Class fieldType; - - public HostStaticFieldExpr(StaticMemberInvoker sym) throws Exception{ - this.sym = sym; - this.resolvedClassName = resolveHostClassname(sym.className); - this.type = getTypeNamed(resolvedClassName); - Field f = Reflector.getField(type, sym.memberName, true); - if(f == null) - throw new Exception(String.format("Can't find field %1$ in class %2$", - sym.memberName, resolvedClassName)); - fieldType = f.getType(); - } - - public void emitHostExpr() throws Exception{ - format("~A.~A", resolvedClassName, sym.memberName); - } - - public Class getHostType() throws Exception{ - return fieldType; - } - -} -/* -static class SymExpr extends AnExpr{ - Symbol sym; - String typeHint; - - public SymExpr(Symbol sym, String typeHint){ - this.sym = sym; - this.typeHint = typeHint; - } - - public void emitExpression() throws Exception{ - format("~A", munge(sym.name)); - } -} -*/ - -static class KeywordExpr extends AnExpr{ - final Symbol sym; - - public KeywordExpr(Symbol sym){ - this.sym = sym; - } - - public void emitExpression() throws Exception{ - format("~A", munge(sym.name)); - } -} - -static class LocalBinding{ - final Symbol sym; - boolean isClosed = false; - boolean isParam = false; - final int id = RT.nextID(); - String typeHint; - public boolean valueTaken = false; - boolean isAssigned = false; - FnExpr letfn = null; - - - public LocalBinding(Symbol sym){ - this.sym = sym; - } - - public String getName(){ - return munge(sym.name) + (isParam ? "" : ("__" + id)); - } - - public String toString(){ - return getName(); - } - - boolean needsBox(){ - return (isClosed && isAssigned) - || - letfn != null && isClosed && valueTaken; - } - - boolean bindsToStaticFn(){ - return letfn != null && letfn.willBeStaticMethod(); - } - - String typeDeclaration(){ - if(needsBox()) - return "clojure.lang.Box"; - return "Object"; - } - - String getExpr(){ - if(needsBox()) - return getName() + ".val"; - return getName(); - } - - void emitDeclaration(String init) throws Exception{ - format("~A ~A = ", typeDeclaration(), getName()); - if(needsBox()) - format("new clojure.lang.Box(~A);~%", init); - else - format("~A;~%", init); - } -} - -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 emitStatement() throws Exception{ - //nop - } - - public void emitExpression() throws Exception{ - format("~A", b.getExpr()); - } - - public Class getHostType() throws Exception{ - String th = typeHint; - if(th == null) - th = b.typeHint; - if(th == null) - return null; - return getTypeNamed(resolveHostClassname(th)); - } -} - -static class VarExpr extends AnExpr{ - final Var var; - final String typeHint; - - public VarExpr(Var var, String typeHint){ - this.var = var; - this.typeHint = typeHint; - } - - public String getName(){ - return munge(var.toString()); - } - - public void emitExpression() throws Exception{ - format("~A.get()", getName()); - } - - public Class getHostType() throws Exception{ - if(typeHint == null) - return null; - return getTypeNamed(resolveHostClassname(typeHint)); - } - - -} - -static class DefExpr extends AnExpr{ - final VarExpr var; - final Expr init; - - public DefExpr(VarExpr var, Expr init){ - this.var = var; - this.init = init; - } - - public void emitExpression() throws Exception{ - format("~A.bindRoot(~A)", var.getName(), init.emitExpressionString()); - } -} - -public static void main(String[] args) throws Exception{ - if(!(args.length >= 3)) - System.err.println("Usage: clojure.lang.Compiler package class file1 [file2 ...]"); - String pkg = args[0]; - String classname = args[1]; - LineNumberingPushbackReader[] rs = new LineNumberingPushbackReader[args.length - 2]; - String ret; - try - { - for(int i = 0; i < rs.length; i++) - { - rs[i] = new LineNumberingPushbackReader(new InputStreamReader(new FileInputStream(args[i + 2]))); - } - ret = compile(pkg, classname, rs); - System.out.print(ret); - } - finally - { - for(LineNumberingPushbackReader r : rs) - { - if(r != null) - r.close(); - } - } -} - -} -//*/ - - diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java index 5727f013..95c0399d 100644 --- a/src/jvm/clojure/lang/PersistentHashMap.java +++ b/src/jvm/clojure/lang/PersistentHashMap.java @@ -621,6 +621,7 @@ final static class HashCollisionNode implements INode{ } } +/* public static void main(String[] args){ try { @@ -705,5 +706,6 @@ public static void main(String[] args){ } } +*/ } diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java index 7a4f23e4..eb3507f9 100644 --- a/src/jvm/clojure/lang/PersistentQueue.java +++ b/src/jvm/clojure/lang/PersistentQueue.java @@ -144,6 +144,7 @@ static class Seq extends ASeq{ }
}
+/*
public static void main(String[] args){
if(args.length != 1)
{
@@ -155,7 +156,6 @@ public static void main(String[] args){ long startTime, estimatedTime;
- //*
Queue list = new LinkedList();
//Queue list = new ConcurrentLinkedQueue();
System.out.println("Queue");
@@ -174,9 +174,7 @@ public static void main(String[] args){ System.out.println("time: " + estimatedTime / 1000000);
System.out.println("peek: " + list.peek());
-//*/
-//*
PersistentQueue q = PersistentQueue.EMPTY;
System.out.println("PersistentQueue");
startTime = System.nanoTime();
@@ -197,19 +195,16 @@ public static void main(String[] args){ estimatedTime = System.nanoTime() - startTime;
System.out.println("time: " + estimatedTime / 1000000);
System.out.println("peek: " + q.peek());
- //*/
IPersistentList q2 = q;
for(int i = 0; i < 10; i++)
{
q2 = (IPersistentList) q2.cons(i);
}
-/*
- for(ISeq s = q.seq();s != null;s = s.rest())
- System.out.println("q: " + s.first().toString());
- for(ISeq s = q2.seq();s != null;s = s.rest())
- System.out.println("q2: " + s.first().toString());
-//*/
+// for(ISeq s = q.seq();s != null;s = s.rest())
+// System.out.println("q: " + s.first().toString());
+// for(ISeq s = q2.seq();s != null;s = s.rest())
+// System.out.println("q2: " + s.first().toString());
}
-
+*/
}
diff --git a/src/jvm/clojure/lang/PersistentTreeMap.java b/src/jvm/clojure/lang/PersistentTreeMap.java index d806c610..73dd2846 100644 --- a/src/jvm/clojure/lang/PersistentTreeMap.java +++ b/src/jvm/clojure/lang/PersistentTreeMap.java @@ -786,7 +786,7 @@ static class ValIterator implements Iterator{ throw new UnsupportedOperationException(); } } - +/* static public void main(String args[]){ if(args.length != 1) System.err.println("Usage: RBTree n"); @@ -907,4 +907,5 @@ static public void main(String args[]){ // System.out.println("_count = " + set._count + ", min: " + set.minKey() + ", max: " + set.maxKey() // + ", depth: " + set.depth()); } +*/ } diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java index 752b4c8b..328a0522 100644 --- a/src/jvm/clojure/lang/PersistentVector.java +++ b/src/jvm/clojure/lang/PersistentVector.java @@ -384,6 +384,7 @@ public Object valAt(Object key){ return null; } +/* static public void main(String[] args){ if(args.length != 3) { @@ -454,5 +455,5 @@ static public void main(String[] args){ System.out.println("Done: " + tv + ", " + tp); } - + */ } diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index ae46b0fb..98461733 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -638,12 +638,12 @@ static public void print(Object x, Writer w) throws Exception{ w.write(x.toString()); w.write('"'); } - else if(x instanceof ArgVector) - { - w.write('|'); - printInnerSeq(seq(x), w); - w.write('|'); - } +// else if(x instanceof ArgVector) +// { +// w.write('|'); +// printInnerSeq(seq(x), w); +// w.write('|'); +// } else if(x instanceof IPersistentMap) { w.write('{'); @@ -812,7 +812,7 @@ static public ISeq doFormat(Writer w, String s, ISeq args) throws Exception{ ///////////////////////////////// values ////////////////////////// static public Object setValues(Object... vals){ - ThreadLocalData.setValues(vals); + //ThreadLocalData.setValues(vals); if(vals.length > 0) return vals[0]; return null; diff --git a/src/jvm/clojure/lang/ThreadLocalData.java b/src/jvm/clojure/lang/ThreadLocalData.java deleted file mode 100644 index 09321301..00000000 --- a/src/jvm/clojure/lang/ThreadLocalData.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * 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 Mar 25, 2006 11:45:22 AM */ - -package clojure.lang; - -public class ThreadLocalData{ - -private static ThreadLocal<Object[]> values = new ThreadLocal<Object[]>(); - -static public Object[] getValues(){ - return values.get(); -} - -static public void setValues(Object[] vals){ - values.set(vals); -} - - -private static ThreadLocal<Integer> tltest = new ThreadLocal<Integer>(); -private static Integer test; -private static volatile int sum; -private static volatile Object fred; - -static public void main(String[] args){ - test = new Integer(17); - tltest.set(new Integer(17)); -// PersistentArrayIdentityMap testmap = PersistentArrayIdentityMap.EMPTY; -// testmap = (PersistentArrayIdentityMap) testmap.put(42, 42); -// testmap = (PersistentArrayIdentityMap) testmap.put(Thread.currentThread(), 17); - - IPersistentMap testmap = PersistentArrayMap.EMPTY; - testmap = testmap.assoc(Thread.currentThread(), 17); -// testmap = testmap.put(42, 42); -// testmap = testmap.put(43, 42); -// testmap = testmap.put(44, 42); -// testmap = testmap.put(45, 42); - - int n = Integer.parseInt(args[0]); - - long startTime = System.nanoTime(); - sum = 0; - for(int i = 0; i < n; i++) - { - sum += test.intValue(); - } - - long estimatedTime = System.nanoTime() - startTime; - System.out.println("sum = " + sum + ", time: " + estimatedTime / 1000000); - - startTime = System.nanoTime(); - sum = 0; - for(int i = 0; i < n; i++) - { - sum += tltest.get().intValue(); - } - - estimatedTime = System.nanoTime() - startTime; - System.out.println("sum = " + sum + ", time: " + estimatedTime / 1000000); - - startTime = System.nanoTime(); - sum = 0; - for(int i = 0; i < n; i++) - { - sum += ((Integer) testmap.valAt(Thread.currentThread())).intValue(); - } - - estimatedTime = System.nanoTime() - startTime; - System.out.println("sum = " + sum + ", time: " + estimatedTime / 1000000); - - startTime = System.nanoTime(); - sum = 0; - for(int i = 0; i < n; i++) - { - if(fred != null) - sum += ((Integer) testmap.valAt(Thread.currentThread())).intValue(); - else - sum += test.intValue(); - } - - estimatedTime = System.nanoTime() - startTime; - System.out.println("sum = " + sum + ", time: " + estimatedTime / 1000000); - -} -} diff --git a/src/jvm/clojure/lang/TransactionalHashMap.java b/src/jvm/clojure/lang/TransactionalHashMap.java index c8486947..f8689cbf 100644 --- a/src/jvm/clojure/lang/TransactionalHashMap.java +++ b/src/jvm/clojure/lang/TransactionalHashMap.java @@ -166,7 +166,7 @@ public Set<Entry<K, V>> entrySet(){ } }; } - +/* public static void main(String[] args){ try { @@ -250,5 +250,5 @@ public static void main(String[] args){ e.printStackTrace(); } } - +*/ } |