diff options
author | Chouser <chouser@n01se.net> | 2008-09-20 04:03:32 +0000 |
---|---|---|
committer | Chouser <chouser@n01se.net> | 2008-09-20 04:03:32 +0000 |
commit | 20d1ba5d710e1f9c86887484092154101f0017c7 (patch) | |
tree | 756144b8fa1ce70b1d8fe5d06c9683b0ac015751 | |
parent | b0d0dd38cc3cdf8673d16009621501f10a25e023 (diff) |
ClojureScript: Now support apply, lazy variadic args, minimal
StringBuilder and *out*. Use switch on arguments.length
-rw-r--r-- | clojurescript/clj.js | 81 | ||||
-rw-r--r-- | clojurescript/clojurescript-compiler.patch | 569 | ||||
-rw-r--r-- | clojurescript/tojs.clj | 44 |
3 files changed, 97 insertions, 597 deletions
diff --git a/clojurescript/clj.js b/clojurescript/clj.js index 553f342d..2dc33c94 100644 --- a/clojurescript/clj.js +++ b/clojurescript/clj.js @@ -33,7 +33,45 @@ clojure = new clojure_Namespace({ throw ("Don't know how to create ISeq from: " + (typeof coll) + " " + coll.constructor.name); }, - apply: function( f, args ) { + apply: function( f ) { + if( f.isVariatic ) { + // lazy + var i, args = []; + var eagercount = Math.min( f.arity, arguments.length - 2 ); + for( i = 0; i < eagercount; ++i ) { + args.push( arguments[ i + 1 ] ); + } + if( eagercount == f.arity ) { + if( arguments.length - eagercount < 3 ) { + args.push( clojure.seq( arguments[ arguments.length - 1 ] ) ); + } + else { + args.push( clojure.concat( + new clojure.lang.ArraySeq( + null, arguments, eagercount + 1, arguments.length - 1 ), + arguments[ arguments.length - 1 ] ) ); + } + } + else { + var s = clojure.seq( arguments[ arguments.length - 1 ] ); + for( ; s && args.length < f.arity; s = s.rest() ) { + args.push( s.first() ); + } + args.push( s ); + } + return f.apply( clojure.JS.variatic_sentinel, args ); + } + else { + // non-lazy + var args = []; + for( var i = 1; i < arguments.length - 1; ++i ) { + args.push( arguments[ i ] ); + } + for( var s = arguments[ arguments.length - 1]; s; s = s.rest()) { + args.push( s.first() ); + } + return f.apply( null, args ); + } }, first: function(x) { if( x.first ) return x.first(); @@ -82,6 +120,10 @@ clojure = new clojure_Namespace({ }, JS: { merge: clojure_merge, + variatic: function( f ) { + f.isVariatic = true; + return f; + }, resolveVar: function( sym, ctxns ) { return ctxns[ sym ] || clojure[ sym ] || window[ sym ]; }, @@ -91,11 +133,14 @@ clojure = new clojure_Namespace({ v.push( init ); return v; }, - rest_args: function( args, i ) { - return clojure.lang.ArraySeq.create( null, args, i ); + variatic_sentinel: {}, + rest_args: function( varflag, args, i ) { + if( varflag === clojure.JS.variatic_sentinel ) + return args[ args.length - 1 ]; + return new clojure.lang.ArraySeq( null, args, i ); }, lit_list: function( a ) { - return clojure.lang.ArraySeq.create( null, a, 0 ); + return new clojure.lang.ArraySeq( null, a, 0 ); }, ObjSeq: { create: function( obj ) { @@ -120,10 +165,11 @@ clojure = new clojure_Namespace({ } }); -clojure.lang.ArraySeq = function( _meta, a, i ) { +clojure.lang.ArraySeq = function( _meta, a, i, len ) { this._meta = _meta; this.a = a; this.i = i; + this.len = (len === undefined) ? a.length : len; }; clojure.lang.ArraySeq.create = function( a ) { @@ -140,13 +186,13 @@ clojure.lang.ArraySeq.prototype.first = function() { }; clojure.lang.ArraySeq.prototype.rest = function() { - if( this.i + 1 < this.a.length ) - return new clojure.lang.ArraySeq( this._meta, this.a, this.i + 1 ); + if( this.i + 1 < this.len ) + return new clojure.lang.ArraySeq( this._meta, this.a, this.i + 1, this.len); return null; }; clojure.lang.ArraySeq.prototype.count = function() { - return this.a.length - this.i; + return this.len - this.i; }; clojure.lang.ArraySeq.prototype.index = function() { @@ -154,12 +200,12 @@ clojure.lang.ArraySeq.prototype.index = function() { }; clojure.lang.ArraySeq.prototype.withMeta = function( _meta ) { - return new clojure.lang.ArraySeq( _meta, this.array, this.i ); + return new clojure.lang.ArraySeq( _meta, this.array, this.i, this.len ); }; clojure.lang.ArraySeq.prototype.reduce = function( fn, start ) { var ret = (start === undefined) ? this.a[0] : fn(start, this.a[0]); - for( var x = this.i + 1; x < this.a.length; ++x ) { + for( var x = this.i + 1; x < this.len; ++x ) { ret = fn( ret, this.a[x] ); } return ret; @@ -274,5 +320,20 @@ clojure.lang.Namespace.prototype.getMappings = function() { return this; }; +clojure._STAR_out_STAR_ = { + append: function(x) { + document.getElementById( 'ta' ).value += x; + } +} + +java = { lang: {} }; +java.lang.StringBuilder = function( x ) { + this.a = [ x ]; +}; +clojure.JS.merge( java.lang.StringBuilder.prototype, { + append: function( x ) { this.a.push( x ); return this; }, + toString: function() { return this.a.join(''); } +}); + delete clojure_merge; delete clojure_Namespace; diff --git a/clojurescript/clojurescript-compiler.patch b/clojurescript/clojurescript-compiler.patch deleted file mode 100644 index 709abdae..00000000 --- a/clojurescript/clojurescript-compiler.patch +++ /dev/null @@ -1,569 +0,0 @@ -diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java -index a44aa2e..aae4cc9 100644 ---- a/src/jvm/clojure/lang/Compiler.java -+++ b/src/jvm/clojure/lang/Compiler.java -@@ -195,7 +195,7 @@ static final public Var RET_LOCAL_NUM = Var.create(); - //DynamicClassLoader - static final public Var LOADER = Var.create(); - --enum C{ -+public enum C{ - STATEMENT, //value ignored - EXPRESSION, //value required - RETURN, //tail position relative to enclosing recur frame -@@ -212,7 +212,7 @@ interface Expr{ - Class getJavaClass() throws Exception; - } - --static abstract class UntypedExpr implements Expr{ -+public static abstract class UntypedExpr implements Expr{ - - public Class getJavaClass(){ - throw new IllegalArgumentException("Has no Java class"); -@@ -257,12 +257,12 @@ static Symbol resolveSymbol(Symbol sym){ - } - - static class DefExpr implements Expr{ -- final Var var; -- final Expr init; -- final Expr meta; -- final boolean initProvided; -- final String source; -- final int line; -+ public final Var var; -+ public final Expr init; -+ public final Expr meta; -+ public final boolean initProvided; -+ public final String source; -+ public final int line; - final static Method bindRootMethod = Method.getMethod("void bindRoot(Object)"); - final static Method setTagMethod = Method.getMethod("void setTag(clojure.lang.Symbol)"); - final static Method setMetaMethod = Method.getMethod("void setMeta(clojure.lang.IPersistentMap)"); -@@ -361,10 +361,9 @@ static class DefExpr implements Expr{ - } - } - --static class AssignExpr implements Expr{ -- final AssignableExpr target; -- final Expr val; -- -+public static class AssignExpr implements Expr{ -+ public final AssignableExpr target; -+ public final Expr val; - - public AssignExpr(AssignableExpr target, Expr val){ - this.target = target; -@@ -400,9 +399,9 @@ static class AssignExpr implements Expr{ - } - } - --static class VarExpr implements Expr, AssignableExpr{ -- final Var var; -- final Object tag; -+public static class VarExpr implements Expr, AssignableExpr{ -+ public final Var var; -+ public final Object tag; - final static Method getMethod = Method.getMethod("Object get()"); - final static Method setMethod = Method.getMethod("Object set(Object)"); - -@@ -446,8 +445,8 @@ static class VarExpr implements Expr, AssignableExpr{ - } - } - --static class TheVarExpr implements Expr{ -- final Var var; -+public static class TheVarExpr implements Expr{ -+ public final Var var; - - public TheVarExpr(Var var){ - this.var = var; -@@ -482,8 +481,8 @@ static class TheVarExpr implements Expr{ - } - } - --static class KeywordExpr implements Expr{ -- final Keyword k; -+public static class KeywordExpr implements Expr{ -+ public final Keyword k; - - public KeywordExpr(Keyword k){ - this.k = k; -@@ -509,7 +508,7 @@ static class KeywordExpr implements Expr{ - } - } - --static abstract class LiteralExpr implements Expr{ -+public static abstract class LiteralExpr implements Expr{ - abstract Object val(); - - public Object eval(){ -@@ -830,11 +829,11 @@ static abstract class FieldExpr extends HostExpr{ - } - - static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ -- final Expr target; -- final Class targetClass; -- final java.lang.reflect.Field field; -- final String fieldName; -- final int line; -+ public final Expr target; -+ public final Class targetClass; -+ public final java.lang.reflect.Field field; -+ public final String fieldName; -+ public final int line; - final static Method invokeNoArgInstanceMember = Method.getMethod("Object invokeNoArgInstanceMember(Object,String)"); - final static Method setInstanceFieldMethod = Method.getMethod("Object setInstanceField(Object,String,Object)"); - -@@ -930,9 +929,9 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ - - static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ - //final String className; -- final String fieldName; -- final Class c; -- final java.lang.reflect.Field field; -+ public final String fieldName; -+ public final Class c; -+ public final java.lang.reflect.Field field; - final static Method getStaticFieldMethod = Method.getMethod("Object getStaticField(String,String)"); - final static Method setStaticFieldMethod = Method.getMethod("Object setStaticField(String,String,Object)"); - final int line; -@@ -1054,12 +1053,12 @@ static abstract class MethodExpr extends HostExpr{ - } - - static class InstanceMethodExpr extends MethodExpr{ -- final Expr target; -- final String methodName; -- final IPersistentVector args; -- final String source; -- final int line; -- final java.lang.reflect.Method method; -+ public final Expr target; -+ public final String methodName; -+ public final IPersistentVector args; -+ public final String source; -+ public final int line; -+ public final java.lang.reflect.Method method; - - final static Method invokeInstanceMethodMethod = - Method.getMethod("Object invokeInstanceMethod(Object,String,Object[])"); -@@ -1205,12 +1204,12 @@ static class InstanceMethodExpr extends MethodExpr{ - - static class StaticMethodExpr extends MethodExpr{ - //final String className; -- final Class c; -- final String methodName; -- final IPersistentVector args; -- final String source; -- final int line; -- final java.lang.reflect.Method method; -+ public final Class c; -+ public final String methodName; -+ public final IPersistentVector args; -+ public final String source; -+ public final int line; -+ public final java.lang.reflect.Method method; - final static Method invokeStaticMethodMethod = - Method.getMethod("Object invokeStaticMethod(String,String,Object[])"); - -@@ -1326,12 +1325,36 @@ static class StaticMethodExpr extends MethodExpr{ - } - } - -+static class UnresolvedVarExpr implements Expr{ -+ public final Symbol symbol; -+ -+ public UnresolvedVarExpr(Symbol symbol) { -+ this.symbol = symbol; -+ } -+ -+ public boolean hasJavaClass(){ -+ return false; -+ } -+ -+ public Class getJavaClass() throws Exception{ -+ throw new IllegalArgumentException( -+ "UnresolvedVarExpr has no Java class"); -+ } -+ -+ public void emit(C context, FnExpr fn, GeneratorAdapter gen){ -+ } -+ -+ public Object eval() throws Exception{ -+ throw new IllegalArgumentException( -+ "UnresolvedVarExpr cannot be evalled"); -+ } -+} - - static class ConstantExpr extends LiteralExpr{ - //stuff quoted vals in classloader at compile time, pull out at runtime - //this won't work for static compilation... -- final Object v; -- final int id; -+ public final Object v; -+ public final int id; - - public ConstantExpr(Object v){ - this.v = v; -@@ -1415,7 +1438,7 @@ static class NilExpr extends LiteralExpr{ - final static NilExpr NIL_EXPR = new NilExpr(); - - static class BooleanExpr extends LiteralExpr{ -- final boolean val; -+ public final boolean val; - - - public BooleanExpr(boolean val){ -@@ -1450,7 +1473,7 @@ final static BooleanExpr TRUE_EXPR = new BooleanExpr(true); - final static BooleanExpr FALSE_EXPR = new BooleanExpr(false); - - static class StringExpr extends LiteralExpr{ -- final String str; -+ public final String str; - - public StringExpr(String str){ - this.str = str; -@@ -1621,18 +1644,18 @@ static class MonitorExitExpr extends UntypedExpr{ - - } - --static class TryExpr implements Expr{ -- final Expr tryExpr; -- final Expr finallyExpr; -- final PersistentVector catchExprs; -- final int retLocal; -- final int finallyLocal; -+public static class TryExpr implements Expr{ -+ public final Expr tryExpr; -+ public final Expr finallyExpr; -+ public final PersistentVector catchExprs; -+ public final int retLocal; -+ public final int finallyLocal; - -- static class CatchClause{ -+ public static class CatchClause{ - //final String className; -- final Class c; -- final LocalBinding lb; -- final Expr handler; -+ public final Class c; -+ public final LocalBinding lb; -+ public final Expr handler; - Label label; - Label endLabel; - -@@ -1874,7 +1897,7 @@ static class TryExpr implements Expr{ - //} - - static class ThrowExpr extends UntypedExpr{ -- final Expr excExpr; -+ public final Expr excExpr; - - public ThrowExpr(Expr excExpr){ - this.excExpr = excExpr; -@@ -2001,10 +2024,10 @@ static int getMatchingParams(String methodName, ArrayList<Class[]> paramlists, I - return matchIdx; - } - --static class NewExpr implements Expr{ -- final IPersistentVector args; -- final Constructor ctor; -- final Class c; -+public static class NewExpr implements Expr{ -+ public final IPersistentVector args; -+ public final Constructor ctor; -+ public final Class c; - final static Method invokeConstructorMethod = - Method.getMethod("Object invokeConstructor(Class,Object[])"); - final static Method forNameMethod = Method.getMethod("Class classForName(String)"); -@@ -2216,9 +2239,9 @@ static class NewExpr implements Expr{ - // } - //} - --static class MetaExpr implements Expr{ -- final Expr expr; -- final MapExpr meta; -+public static class MetaExpr implements Expr{ -+ public final Expr expr; -+ public final MapExpr meta; - final static Type IOBJ_TYPE = Type.getType(IObj.class); - final static Method withMetaMethod = Method.getMethod("clojure.lang.IObj withMeta(clojure.lang.IPersistentMap)"); - -@@ -2253,11 +2276,11 @@ static class MetaExpr implements Expr{ - } - } - --static class IfExpr implements Expr{ -- final Expr testExpr; -- final Expr thenExpr; -- final Expr elseExpr; -- final int line; -+public static class IfExpr implements Expr{ -+ public final Expr testExpr; -+ public final Expr thenExpr; -+ public final Expr elseExpr; -+ public final int line; - - - public IfExpr(int line, Expr testExpr, Expr thenExpr, Expr elseExpr){ -@@ -2382,8 +2405,8 @@ static public String munge(String name){ - return sb.toString(); - } - --static class EmptyExpr implements Expr{ -- final Object coll; -+public static class EmptyExpr implements Expr{ -+ public final Object coll; - final static Type HASHMAP_TYPE = Type.getType(PersistentHashMap.class); - final static Type HASHSET_TYPE = Type.getType(PersistentHashSet.class); - final static Type VECTOR_TYPE = Type.getType(PersistentVector.class); -@@ -2434,8 +2457,8 @@ static class EmptyExpr implements Expr{ - } - } - --static class ListExpr implements Expr{ -- final IPersistentVector args; -+public static class ListExpr implements Expr{ -+ public final IPersistentVector args; - final static Method arrayToListMethod = Method.getMethod("clojure.lang.ISeq arrayToList(Object[])"); - - -@@ -2467,8 +2490,8 @@ static class ListExpr implements Expr{ - - } - --static class MapExpr implements Expr{ -- final IPersistentVector keyvals; -+public static class MapExpr implements Expr{ -+ public final IPersistentVector keyvals; - final static Method mapMethod = Method.getMethod("clojure.lang.IPersistentMap map(Object[])"); - - -@@ -2516,8 +2539,8 @@ static class MapExpr implements Expr{ - } - } - --static class SetExpr implements Expr{ -- final IPersistentVector keys; -+public static class SetExpr implements Expr{ -+ public final IPersistentVector keys; - final static Method setMethod = Method.getMethod("clojure.lang.IPersistentSet set(Object[])"); - - -@@ -2564,8 +2587,8 @@ static class SetExpr implements Expr{ - } - } - --static class VectorExpr implements Expr{ -- final IPersistentVector args; -+public static class VectorExpr implements Expr{ -+ public final IPersistentVector args; - final static Method vectorMethod = Method.getMethod("clojure.lang.IPersistentVector vector(Object[])"); - - -@@ -2610,11 +2633,11 @@ static class VectorExpr implements Expr{ - } - - static class InvokeExpr implements Expr{ -- final Expr fexpr; -- final Object tag; -- final IPersistentVector args; -- final int line; -- final String source; -+ public final Expr fexpr; -+ public final Object tag; -+ public final IPersistentVector args; -+ public final int line; -+ public final String source; - - public InvokeExpr(String source, int line, Symbol tag, Expr fexpr, IPersistentVector args){ - this.source = source; -@@ -2746,7 +2769,7 @@ static public class FnExpr implements Expr{ - String internalName; - String thisName; - Type fntype; -- final Object tag; -+ public final Object tag; - //localbinding->itself - IPersistentMap closes = PersistentHashMap.EMPTY; - //Keyword->KeywordExpr -@@ -2756,6 +2779,20 @@ static public class FnExpr implements Expr{ - int line; - PersistentVector constants; - int constantsID; -+ public final IPersistentCollection methods() { return methods;} -+ public final FnMethod variadicMethod() { return variadicMethod;} -+ public final String name() { return name;} -+ public final String simpleName() { return simpleName;} -+ public final String internalName() { return internalName;} -+ public final String thisName() { return thisName;} -+ public final Type fntype() { return fntype;} -+ public final IPersistentMap closes() { return closes;} -+ public final IPersistentMap keywords() { return keywords;} -+ public final IPersistentMap vars() { return vars;} -+ public final Class compiledClass() { return compiledClass;} -+ public final int line() { return line;} -+ public final PersistentVector constants() { return constants;} -+ public final int constantsID() { return constantsID;} - - final static Method kwintern = Method.getMethod("clojure.lang.Keyword intern(String, String)"); - final static Method symcreate = Method.getMethod("clojure.lang.Symbol create(String)"); -@@ -3192,10 +3229,10 @@ enum PSTATE{ - } - - --static class FnMethod{ -+public static class FnMethod{ - //when closures are defined inside other closures, - //the closed over locals need to be propagated to the enclosing fn -- final FnMethod parent; -+ public final FnMethod parent; - //localbinding->localbinding - IPersistentMap locals = null; - //localbinding->localbinding -@@ -3207,6 +3244,14 @@ static class FnMethod{ - int maxLocal = 0; - int line; - PersistentHashSet localsUsedInCatchFinally = PersistentHashSet.EMPTY; -+ public final IPersistentMap locals() { return locals;} -+ public final PersistentVector reqParms() { return reqParms;} -+ public final LocalBinding restParm() { return restParm;} -+ public final Expr body() { return body;} -+ public final FnExpr fn() { return fn;} -+ public final PersistentVector argLocals() { return argLocals;} -+ public final int maxLocal() { return maxLocal;} -+ public final int line() { return line;} - - public FnMethod(FnExpr fn, FnMethod parent){ - this.parent = parent; -@@ -3346,12 +3391,12 @@ static class FnMethod{ - } - } - --static class LocalBinding{ -- final Symbol sym; -- final Symbol tag; -- final Expr init; -- final int idx; -- final String name; -+public static class LocalBinding{ -+ public final Symbol sym; -+ public final Symbol tag; -+ public final Expr init; -+ public final int idx; -+ public final String name; - - public LocalBinding(int num, Symbol sym, Symbol tag, Expr init) throws Exception{ - if(maybePrimitiveType(init) != null && tag != null) -@@ -3382,9 +3427,9 @@ static class LocalBinding{ - } - } - --static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{ -- final LocalBinding b; -- final Symbol tag; -+public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{ -+ public final LocalBinding b; -+ public final Symbol tag; - - public LocalBindingExpr(LocalBinding b, Symbol tag) throws Exception{ - if(b.getPrimitiveType() != null && tag != null) -@@ -3419,8 +3464,9 @@ static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{ - - } - --static class BodyExpr implements Expr{ -+public static class BodyExpr implements Expr{ - PersistentVector exprs; -+ public final PersistentVector exprs() { return exprs;} - - public BodyExpr(PersistentVector exprs){ - this.exprs = exprs; -@@ -3480,9 +3526,11 @@ static class BodyExpr implements Expr{ - } - } - --static class BindingInit{ -+public static class BindingInit{ - LocalBinding binding; - Expr init; -+ public final LocalBinding binding() { return binding;} -+ public final Expr init() { return init;} - - public BindingInit(LocalBinding binding, Expr init){ - this.binding = binding; -@@ -3490,10 +3538,10 @@ static class BindingInit{ - } - } - --static class LetExpr implements Expr{ -- final PersistentVector bindingInits; -- final Expr body; -- final boolean isLoop; -+public static class LetExpr implements Expr{ -+ public final PersistentVector bindingInits; -+ public final Expr body; -+ public final boolean isLoop; - - public LetExpr(PersistentVector bindingInits, Expr body, boolean isLoop){ - this.bindingInits = bindingInits; -@@ -3616,9 +3664,9 @@ static class LetExpr implements Expr{ - } - } - --static class RecurExpr implements Expr{ -- final IPersistentVector args; -- final IPersistentVector loopLocals; -+public static class RecurExpr implements Expr{ -+ public final IPersistentVector args; -+ public final IPersistentVector loopLocals; - - public RecurExpr(IPersistentVector loopLocals, IPersistentVector args){ - this.loopLocals = loopLocals; -@@ -3720,7 +3768,7 @@ private static int getAndIncLocalNum(){ - return num; - } - --private static Expr analyze(C context, Object form) throws Exception{ -+public static Expr analyze(C context, Object form) throws Exception{ - return analyze(context, form, null); - } - -@@ -4021,6 +4069,8 @@ private static Expr analyzeSymbol(Symbol sym) throws Exception{ - } - else if(o instanceof Class) - return new ConstantExpr(o); -+ else if(o instanceof Symbol) -+ return new UnresolvedVarExpr((Symbol) o); - - throw new Exception("Unable to resolve symbol: " + sym + " in this context"); - -@@ -4074,7 +4124,16 @@ static public Object resolveIn(Namespace n, Symbol sym) throws Exception{ - { - Object o = n.getMapping(sym); - if(o == null) -- throw new Exception("Unable to resolve symbol: " + sym + " in this context"); -+ { -+ if( RT.booleanCast(RT.ALLOW_UNRESOLVED_VARS.get())) -+ { -+ return sym; -+ } -+ else -+ { -+ throw new Exception("Unable to resolve symbol: " + sym + " in this context"); -+ } -+ } - return o; - } - } -diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java -index 2ce55e4..06379eb 100644 ---- a/src/jvm/clojure/lang/RT.java -+++ b/src/jvm/clojure/lang/RT.java -@@ -198,6 +198,7 @@ final static Var FLUSH_ON_NEWLINE = Var.intern(CLOJURE_NS, Symbol.create("*flush - final static Var PRINT_META = Var.intern(CLOJURE_NS, Symbol.create("*print-meta*"), F); - final static Var PRINT_READABLY = Var.intern(CLOJURE_NS, Symbol.create("*print-readably*"), T); - final static Var WARN_ON_REFLECTION = Var.intern(CLOJURE_NS, Symbol.create("*warn-on-reflection*"), F); -+final static Var ALLOW_UNRESOLVED_VARS = Var.intern(CLOJURE_NS, Symbol.create("*allow-unresolved-vars*"), F); - - final static Var IN_NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("in-ns"), F); - final static Var NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("ns"), F); diff --git a/clojurescript/tojs.clj b/clojurescript/tojs.clj index fa8f4fde..4159a9ea 100644 --- a/clojurescript/tojs.clj +++ b/clojurescript/tojs.clj @@ -29,14 +29,13 @@ *has-recur*]) inits (concat (when has-recur ["_cnt" "_rtn"]) - (vals (reduce dissoc lm (cons thisfn (when (= fm maxm) - (.reqParms fm))))) + (vals (reduce dissoc lm (cons thisfn (.reqParms fm)))) (when (:fnname ctx) [(str (lm thisfn) "=arguments.callee")]) (when (not= fm maxm) - (for [lb (.reqParms fm)] + (for [lb (.reqParms fm) :when (not= (.name lb) (.name (nth (.reqParms maxm) (dec (.idx lb)))))] [(lm lb) "=arguments[" (dec (.idx lb)) "]"])) (when-let lb (.restParm fm) - [(str (lm lb) "=clojure.JS.rest_args(arguments," + [(str (lm lb) "=clojure.JS.rest_args(this,arguments," (count (.reqParms fm)) ")")]))] (.reqParms maxm) (vstr [(when (seq inits) @@ -56,21 +55,23 @@ last val)) manym (< 1 (count (.methods e))) newctx (assoc ctx :fnname (.thisName e))] - (vstr ["(function" + (vstr [(when (.variadicMethod e) + "clojure.JS.variatic") + "(function" (when *debug-fn-names* [" __" (.replaceAll (.name e) "[\\W_]+" "_")]) "(" (vec (interpose "," (for [lb (.reqParms maxm)] [(.name lb) "_" (.idx lb)]))) - "){\n" - (vec (for [fm (.methods e) :when (not= fm (.variadicMethod e))] - (if manym - ["if(arguments.length==" (count (.reqParms fm)) "){\n" - (fnmethod fm maxm newctx) "}\n"] - (fnmethod fm maxm newctx)))) - (when (.variadicMethod e) - [(fnmethod (.variadicMethod e) maxm newctx) "\n"]) - "})"]))) + "){" + (when manym + ["switch(arguments.length){" + (vec (for [fm (.methods e) :when (not= fm maxm)] + ["\ncase " (count (.reqParms fm)) ":" + (fnmethod fm maxm newctx)])) + "}"]) + "\n" + (fnmethod maxm maxm newctx) "})"]))) (defmethod tojs clojure.lang.Compiler$BodyExpr [e ctx] (apply str (interpose ",\n" (map #(tojs % ctx) (.exprs e))))) @@ -230,18 +231,25 @@ "}"]) "})()"])) -(def skip-defs '#{seq instance? assoc floats doubles ints longs - global-hierarchy apply}) + +(def skip-set '#{seq instance? assoc floats doubles ints longs + global-hierarchy apply refer first rest}) + +(defn skip-defs [expr] + (let [m ^(.var expr)] + (or (:macro m) (skip-set (:name m))))) (defn formtojs [f] (binding [*allow-unresolved-vars* true] (let [expr (Compiler/analyze Compiler$C/STATEMENT `((fn [] ~f))) mainexpr (-> expr .fexpr .methods first .body .exprs first)] + ;(when (instance? clojure.lang.Compiler$InvokeExpr mainexpr) (prn :invoke f)) (when-not (or (and (instance? clojure.lang.Compiler$DefExpr mainexpr) - (skip-defs (:name ^(.var mainexpr)))) + (skip-defs mainexpr)) + (instance? clojure.lang.Compiler$InstanceMethodExpr mainexpr) (and (instance? clojure.lang.Compiler$BodyExpr mainexpr) (instance? clojure.lang.Compiler$DefExpr (first (.exprs mainexpr))) - (skip-defs (:name ^(.var (first (.exprs mainexpr))))))) + (skip-defs (first (.exprs mainexpr))))) (str (tojs expr {:localmap {}}) ";"))))) (defn filetojs [filename] |