aboutsummaryrefslogtreecommitdiff
path: root/clojurescript/clj.js
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2008-09-21 03:09:01 +0000
committerChouser <chouser@n01se.net>2008-09-21 03:09:01 +0000
commite71a98675ced585d9253e0dd7a8b1452ae3e6165 (patch)
tree1c949c993eb614a20a5f2bb2c376318997034efd /clojurescript/clj.js
parent20d1ba5d710e1f9c86887484092154101f0017c7 (diff)
ClojureScript: Added: RT.conj, ASeq, Cons, EmptyList, PersistentList.
boot.js now loads in Rhino and browsers.
Diffstat (limited to 'clojurescript/clj.js')
-rw-r--r--clojurescript/clj.js273
1 files changed, 207 insertions, 66 deletions
diff --git a/clojurescript/clj.js b/clojurescript/clj.js
index 2dc33c94..3d372d58 100644
--- a/clojurescript/clj.js
+++ b/clojurescript/clj.js
@@ -9,10 +9,12 @@ function clojure_Namespace( m ) {
clojure_merge( this, m || {} );
};
+clojure_global = this;
+
clojure = new clojure_Namespace({
in_ns: function(s) {
var nsparts = s.substring(1).split('.');
- var base = window;
+ var base = clojure.JS.global;
for( var i = 0; i < nsparts.length; ++i ) {
if( ! base[nsparts[i]] ) {
base[nsparts[i]] = new clojure.lang.Namespace();
@@ -89,13 +91,6 @@ clojure = new clojure_Namespace({
instance_QMARK_: function( c, o ) {
return o !== null && o.constructor == c;
},
- prn: function() {
- var args = [];
- for( var i = 0; i < arguments.length; ++i ) {
- args.push( arguments[ i ] );
- }
- print( args.join(" ") );
- },
hash_map: function() {
// This just makes a seq for now
var pairs = [];
@@ -115,17 +110,21 @@ clojure = new clojure_Namespace({
if( x.length != undefined ) return x.length;
throw ("count not supported on: " + (typeof x) + " " + x.constructor);
},
+ import_: function() {
+ // do nothing
+ },
identical_QMARK_: function( a, b ) {
return a === b;
},
JS: {
merge: clojure_merge,
+ global: clojure_global,
variatic: function( f ) {
f.isVariatic = true;
return f;
},
resolveVar: function( sym, ctxns ) {
- return ctxns[ sym ] || clojure[ sym ] || window[ sym ];
+ return ctxns[ sym ] || clojure[ sym ] || clojure.JS.global[ sym ];
},
def: function( ns, name, init ) {
var v = new clojure.lang.Var( ns, name );
@@ -142,6 +141,15 @@ clojure = new clojure_Namespace({
lit_list: function( a ) {
return new clojure.lang.ArraySeq( null, a, 0 );
},
+ defclass: function( pkg, classname, opts ) {
+ var cls = pkg[ classname ] = opts.init || function() {};
+ cls.classname = classname;
+ if( opts.extend ) { cls.prototype = new opts.extend[0]; }
+ cls.constructor = cls;
+ if( opts.statics ) { clojure.JS.merge( cls, opts.statics ); }
+ if( opts.methods ) { clojure.JS.merge( cls.prototype, opts.methods ); }
+ return cls;
+ },
ObjSeq: {
create: function( obj ) {
var pairs = [];
@@ -161,59 +169,110 @@ clojure = new clojure_Namespace({
Util: {
equal: function(x,y) { return x == y; }
},
+ RT: {
+ conj: function( coll, x ) {
+ var y = clojure.seq( coll );
+ if( y === null )
+ return new clojure.lang.PersistentList( null, x );
+ return y.cons( x );
+ },
+ print: function( o, w ) {
+ if( o !== null )
+ w.write( "" + o );
+ }
+ },
IReduce: {}
}
});
-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 ) {
- if( a && a.length ) {
- return new clojure.lang.ArraySeq( null, a, 0 );
- }
- else {
- return null;
+clojure.JS.defclass( clojure.lang, "ASeq", {
+ methods: {
+ equals: function( obj ) {
+ var ms = obj.seq();
+ for( var s = this.seq(); s !== null; s = s.rest(), ms = ms.rest() ) {
+ if( ms === null || !clojure.lang.Util.equal( s.first(), ms.first() ))
+ return false;
+ }
+ if( ms !== null )
+ return false;
+ return true;
+ },
+ hashCode: function() { throw "not yet implemented"; },
+ count: function() {
+ var i = 1;
+ for( var s = this.rest(); s; s = s.rest() )
+ i += 1;
+ return i;
+ },
+ seq: function(){ return this; },
+ cons: function(o){ return new clojure.lang.Cons( null, o, this ); },
+ toArray: function(){ return clojure.lang.RT.seqToArray( this.seq() ); },
+ containsAll: function(c){ throw "not yet implemented"; },
+ size: function(){ return this.count(); },
+ isEmpty: function(){ return this.count() == 0; },
+ contains: function(c){ throw "not yet implemented"; }
}
-};
-
-clojure.lang.ArraySeq.prototype.first = function() {
- return this.a[this.i];
-};
-
-clojure.lang.ArraySeq.prototype.rest = function() {
- 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.len - this.i;
-};
-
-clojure.lang.ArraySeq.prototype.index = function() {
- return this.i;
-};
-
-clojure.lang.ArraySeq.prototype.withMeta = function( _meta ) {
- 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.len; ++x ) {
- ret = fn( ret, this.a[x] );
+clojure.JS.defclass( clojure.lang, "Cons", {
+ extend: [clojure.lang.ASeq],
+ init: function( _meta, _first, _rest ) {
+ this._meta = _meta;
+ this._first = _first;
+ this._rest = _rest;
+ },
+ methods: {
+ first: function(){ return this._first; },
+ rest: function(){ return this._rest; },
+ count: function(){ return 1 + clojure.count( this._rest ); },
+ seq: function(){ return this; },
+ withMeta: function(_meta){
+ return new clojure.lang.Cons( _meta, this._first, this._rest );
+ }
}
- return ret;
-};
+});
-clojure.lang.ArraySeq.prototype.seq = function() {
- return this;
-};
+clojure.JS.defclass( clojure.lang, "ArraySeq", {
+ extend: [clojure.lang.ASeq],
+ init: function( _meta, a, i, len ) {
+ this._meta = _meta;
+ this.a = a;
+ this.i = i;
+ this.len = (len === undefined) ? a.length : len;
+ },
+ statics: {
+ create: function( a ) {
+ if( a && a.length ) {
+ return new clojure.lang.ArraySeq( null, a, 0 );
+ }
+ else {
+ return null;
+ }
+ }
+ },
+ methods: {
+ first: function() { return this.a[this.i]; },
+ rest: function() {
+ if( this.i + 1 < this.len )
+ return new clojure.lang.ArraySeq(
+ this._meta, this.a, this.i + 1, this.len);
+ return null;
+ },
+ count: function() { return this.len - this.i; },
+ index: function() { return this.i; },
+ withMeta: function( _meta ) {
+ return new clojure.lang.ArraySeq( _meta, this.array, this.i, this.len );
+ },
+ reduce: function( fn, start ) {
+ var ret = (start === undefined) ? this.a[0] : fn(start, this.a[0]);
+ for( var x = this.i + 1; x < this.len; ++x ) {
+ ret = fn( ret, this.a[x] );
+ }
+ return ret;
+ },
+ seq: function() { return this; }
+ }
+});
clojure.lang.LazyCons = function(f,_first,_rest) {
@@ -253,7 +312,6 @@ clojure.lang.LazyCons.prototype.seq = function() {
return this;
};
-
clojure.lang.Var = function( ns, name ) {
this.ns = ns;
this.name = name;
@@ -302,29 +360,111 @@ clojure.lang.Var.popThreadBindings = function() {
}
};
-clojure.lang.PersistentList = { creator: function() {
- var real = clojure.lang.PersistentList.creator;
- if( real == arguments.callee ) {
- throw "Not yet implemented: clojure.lang.PersistentList.creator";
+
+
+clojure.JS.defclass( clojure.lang, "EmptyList", {
+ //extend: [clojure.lang.IPersistentList],
+ init: function( _meta ) { this._meta = _meta; },
+ methods: {
+ cons: function(o) {
+ return new clojure.lang.PersistentList( this.meta(), o );
+ },
+ empty: function() { return this; },
+ withMeta: function(m) {
+ if( m != this.meta() )
+ return new clojure.lang.EmptyList( m );
+ return this;
+ },
+ peek: function() { return null; },
+ pop: function() { throw "Can't pop empty list"; },
+ count: function() { return 0; },
+ seq: function() { return null; },
+ size: function() { return 0; },
+ isEmpty: function() { return true; },
+ contains: function() { return false; },
+ toArray: function() { return clojure.lang.RT.EMPTY_ARRAY; },
+ containsAll: function( coll ) { return coll.isEmpty(); }
}
- return real.apply( arguments );
-}};
+});
+
+clojure.JS.defclass( clojure.lang, "PersistentList", {
+ init: function( _meta, _first, _rest, _count ) {
+ this._meta = _meta || null;
+ this._first = _first;
+ this._rest = _rest || null;
+ this._count = _count || 1;
+ },
+ statics: {
+ creator: function() {
+ var real = clojure.lang.PersistentList.creator;
+ if( real == arguments.callee ) {
+ throw "Not yet implemented: clojure.lang.PersistentList.creator";
+ }
+ return real.apply( arguments );
+ },
+ EMPTY: new clojure.lang.EmptyList(null)
+ },
+ methods: {
+ first: function(){ return this._first; },
+ rest: function(){
+ if( this._count == 1 )
+ return null;
+ return this._rest;
+ },
+ peek: function(){ return this.first; },
+ pop: function(){
+ if( this._rest === null )
+ return this.empty();
+ return this._rest;
+ },
+ count: function(){ return this._count; },
+ cons: function(o){
+ return new clojure.lang.PersistentList(
+ this._meta, o, this, this._count + 1 );
+ },
+ empty: function(){
+ return clojure.lang.PersistentList.EMPTY.withMeta( this._meta );
+ },
+ withMeta: function( _meta ){
+ if( _meta != this._meta )
+ return new clojure.lang.PersistentList(
+ this._meta, this._first, this._rest, this._count );
+ return this;
+ },
+ reduce: function( f, start ){
+ var ret = (start === undefined) ? this.first() : f( start, this.first() );
+ for( var s = this.rest(); s !== null; s = s.rest() )
+ ret = f( ret, s.first() );
+ return ret;
+ }
+ }
+});
+
clojure.lang.Namespace = clojure_Namespace;
clojure.lang.Namespace.find = function( s ) {
- return window[ s.substring(1) ];
+ return clojure.JS.global[ s.substring(1) ];
};
clojure.lang.Namespace.prototype.getMappings = function() {
return this;
};
-clojure._STAR_out_STAR_ = {
- append: function(x) {
- document.getElementById( 'ta' ).value += x;
+(function() {
+ var buf = [];
+ function write(s) {
+ var parts = s.split(/\n/);
+ if( parts.length == 1 ) {
+ buf.push(s);
+ }
+ else {
+ print( buf.join('') + parts.splice(0, parts.length - 1).join('\n') );
+ buf = [ parts[parts.length - 1] ];
+ }
}
-}
+ clojure._STAR_out_STAR_ = { append: write, write: write };
+})();
java = { lang: {} };
java.lang.StringBuilder = function( x ) {
@@ -337,3 +477,4 @@ clojure.JS.merge( java.lang.StringBuilder.prototype, {
delete clojure_merge;
delete clojure_Namespace;
+delete clojure_global;