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 /clojurescript/clj.js | |
parent | b0d0dd38cc3cdf8673d16009621501f10a25e023 (diff) |
ClojureScript: Now support apply, lazy variadic args, minimal
StringBuilder and *out*. Use switch on arguments.length
Diffstat (limited to 'clojurescript/clj.js')
-rw-r--r-- | clojurescript/clj.js | 81 |
1 files changed, 71 insertions, 10 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; |