aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2008-09-20 04:03:32 +0000
committerChouser <chouser@n01se.net>2008-09-20 04:03:32 +0000
commit20d1ba5d710e1f9c86887484092154101f0017c7 (patch)
tree756144b8fa1ce70b1d8fe5d06c9683b0ac015751
parentb0d0dd38cc3cdf8673d16009621501f10a25e023 (diff)
ClojureScript: Now support apply, lazy variadic args, minimal
StringBuilder and *out*. Use switch on arguments.length
-rw-r--r--clojurescript/clj.js81
-rw-r--r--clojurescript/clojurescript-compiler.patch569
-rw-r--r--clojurescript/tojs.clj44
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]