aboutsummaryrefslogtreecommitdiff
path: root/clojurescript/clj.js
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2008-10-02 21:47:27 +0000
committerChouser <chouser@n01se.net>2008-10-02 21:47:27 +0000
commitfcbdeb6e5b07994b5880f5706d05ae5a619b5456 (patch)
treef66f08edb5c2cb9d247e641d12a9ac6ddef6fd86 /clojurescript/clj.js
parent0f0bf269cbacac400c61351fa64def768d87bc91 (diff)
ClojureScript: stop shadowing java classes, clean up mock-java type system. prn print-method now works for several types.
Diffstat (limited to 'clojurescript/clj.js')
-rw-r--r--clojurescript/clj.js143
1 files changed, 97 insertions, 46 deletions
diff --git a/clojurescript/clj.js b/clojurescript/clj.js
index 1dcc067c..7e889db6 100644
--- a/clojurescript/clj.js
+++ b/clojurescript/clj.js
@@ -1,3 +1,13 @@
+// Copyright (c) Chris Houser, Sep 2008. 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.
+
+// Runtime support for code generated by tojs.clj
+
clojure = {
JS: {
global: this,
@@ -6,13 +16,20 @@ clojure = {
t[ i ] = s[ i ];
}
return t;
- }
+ },
+ Class: {}
},
lang: {
Namespace: function( m ) { clojure.JS.merge( this, m || {} ); }
}
};
+if( ! clojure.JS.global["java"] ) {
+ java = { lang: { String: {}, Character: {}, Class: {} },
+ math: { BigDecimal: {} },
+ util: { regex: { Pattern: {} } } };
+}
+
clojure = new clojure.lang.Namespace({
in_ns: function(s) {
var nsparts = s.substring(1).split('.');
@@ -30,9 +47,9 @@ clojure = new clojure.lang.Namespace({
else if( coll.seq ) return coll.seq();
//else if( coll.constructor === String )
// return clojure.lang.StringSeq.create(coll);
- else if( typeof coll.length == typeof 0 )
+ else if( typeof coll.length == clojure.JS.numberType )
return clojure.lang.ArraySeq.create(coll);
- else if( typeof coll === typeof {} )
+ else if( typeof coll === clojure.JS.objectType )
return clojure.JS.ObjSeq.create(coll);
throw ("Don't know how to create ISeq from: " +
(typeof coll) + " " + coll.constructor.name);
@@ -94,10 +111,14 @@ clojure = new clojure.lang.Namespace({
instance_QMARK_: function( c, o ) {
return clojure.JS.instanceq( c, o );
},
+ class_QMARK_: function(o) { return clojure.JS.instanceq(clojure.JS.Class,o);},
+ number_QMARK_: function(o) { return clojure.JS.instanceq( Number, o ); },
+ string_QMARK_: function(o) { return clojure.JS.instanceq( String, o ); },
+ integer_QMARK_: function(o) { return parseInt( o ) === o; },
find: function(coll, key) {
if( coll == null )
return null;
- else if( clojure.JS.instanceq( java.util.Map, coll ) ) {
+ else if( coll.containsKey ) {
if( coll.containsKey( key ) )
return new clojure.lang.MapEntry( key, coll.get( key ) );
return null;
@@ -105,23 +126,35 @@ clojure = new clojure.lang.Namespace({
return coll.entryAt( key );
},
get: function(coll, key, notFound ) {
+ var usenull = notFound === undefined;
if( coll === null )
- return null;
+ return usenull ? null : notFound;
if( coll.valAt )
return coll.valAt( key, notFound );
- if( coll.containsKey ) {
- if( notFound === undefined || coll.containsKey( key ) )
- return coll.get( key );
- return notFound;
- }
- if( coll.contains ) {
- if( notFound === undefined || coll.contains( key ) )
- return coll.get( key );
+ if( coll.containsKey )
+ return (usenull || coll.containsKey( key )) ? coll.get( key ) : notFound;
+ if( coll.contains )
+ return (usenull || coll.contains( key )) ? coll.get( key ) : notFound;
+ return (usenull || key in coll) ? coll[ key ] : notFound;
+ },
+ nth: function(coll, n, notFound) {
+ var usenull = notFound === undefined;
+ if( coll === null )
+ return usenull ? null : notFound;
+ if( coll.nth )
+ return usenull || n < coll.count() ? coll.nth(n) : notFound;
+ if( coll.get )
+ return usenull || n < coll.size() ? coll.get(n) : notFound;
+ if( coll.seq ) {
+ for( var seq = coll.seq(), i = 0; i <= n && seq; seq = seq.rest() ) {
+ if( i == n )
+ return seq.first();
+ }
+ if( usenull )
+ throw "IndexOutOfBoundsException";
return notFound;
}
- if( notFound === undefined || key in coll )
- return coll[ key ];
- return notFound;
+ return usenull || n < coll.length ? coll[n] : notFound;
},
contains_QMARK_: function(coll, key) {
if( coll === null )
@@ -157,6 +190,8 @@ clojure = new clojure.lang.Namespace({
class_: function(o) {
if( o === null )
return null;
+ if( typeof o === clojure.JS.functionType && ! ("constructor" in o) )
+ return "" + o; // a Java class?
return o.constructor || typeof o;
},
import_: function() {
@@ -174,6 +209,11 @@ clojure = new clojure.lang.Namespace({
JS: {
merge: clojure.JS.merge,
global: clojure.JS.global,
+ Class: clojure.JS.Class,
+ objectType: typeof {},
+ functionType: typeof function(){},
+ stringType: typeof "",
+ numberType: typeof 0,
variadic: function( arity, f ) {
f.arity = arity;
f.isVariadic = true;
@@ -202,11 +242,11 @@ clojure = new clojure.lang.Namespace({
},
implement: function( cls, name, extend, implement ) {
cls.classname = name;
+ cls.extend = extend;
+ cls.implement = implement;
cls.classset = {};
- cls.hashCode = function() { return clojure.lang.Util.hash( name ); };
- cls.getSuperclass = function() { return extend || null; };
- cls.getInterfaces = function() { return implement || null; };
cls.classset[ name ] = true;
+ clojure.JS.merge( cls, clojure.JS.classmethods );
if( implement ) {
for( var i = 0; i < implement.length; ++i ) {
if( ! implement[ i ] )
@@ -233,8 +273,10 @@ clojure = new clojure.lang.Namespace({
return cls;
},
instanceq: function( c, o ){
- if( o === null || o.getClass === null )
+ if( o === null )
return false;
+ if( typeof o === clojure.JS.functionType && ! ("constructor" in o) )
+ return false; // a Java class?
if( o.constructor === c )
return true;
if( ! o.constructor.classset )
@@ -248,6 +290,13 @@ clojure = new clojure.lang.Namespace({
}
return rtn;
},
+ classmethods: {
+ constructor: clojure.JS.Class,
+ hashCode: function() { return clojure.lang.Util.hash( this.classname ); },
+ isAssignableFrom: function(base) { return base.classset[this.classname];},
+ getSuperclass: function() { return this.extend || null; },
+ getInterfaces: function() { return this.implement || null; }
+ },
ObjSeq: {
create: function( obj ) {
var pairs = [];
@@ -272,25 +321,33 @@ clojure = new clojure.lang.Namespace({
hash: function(o){
if( o === null )
return 0;
- if( typeof o == typeof "" ) {
- var ret = 0;
+ if( typeof o == clojure.JS.stringType ) {
+ var ret = 0; // lousy hand-made string hash
for( var i = 0; i < o.length; ++i ) {
ret ^= o.charCodeAt(i) << ((i % 4) * 8);
}
return ret;
}
- if( o == String )
- return clojure.lang.Util.hash("stringtype");
- if( o == Number )
- return clojure.lang.Util.hash("numbertype");
- if( o == RegExp )
- return clojure.lang.Util.hash("regexptype");
- if( o == Object )
- return clojure.lang.Util.hash("objecttype");
+ if( typeof o == clojure.JS.numberType ) {
+ return o & 0xffffffff;
+ }
+ switch( o ) {
+ case String: return 0x7A837A70;
+ case Number: return 0x7A837A71;
+ case RegExp: return 0x7A837A72;
+ case Object: return 0x7A837A73;
+ case Function: return 0x7A837A74;
+ case java.lang.String:
+ case java.lang.Character:
+ case java.lang.Class:
+ case java.math.BigDecimal:
+ case java.util.regex.Pattern:
+ return 0x7A830001;
+ }
return o.hashCode();
},
equal: function(x,y) { return x == y; },
- isInteger: function(x) { return typeof x == typeof 0; }
+ isInteger: function(x) { return typeof x == clojure.JS.numberType; }
},
RT: {
EMPTY_ARRAY: [],
@@ -318,15 +375,9 @@ clojure = new clojure.lang.Namespace({
}
});
-java = { util: { regex: {} }, lang: {}, math: {} };
-clojure.JS.definterface( java.util, "Map" );
-clojure.JS.definterface( java.util, "Collection" );
-clojure.JS.definterface( java.util.regex, "Pattern" );
-clojure.JS.definterface( java.lang, "Character" );
-clojure.JS.definterface( java.lang, "Class" );
-clojure.JS.definterface( java.math, "BigDecimal", [Number] );
-clojure.JS.definterface( java.math, "BigInteger", [Number] );
-clojure.JS.defclass( java.lang, "StringBuilder", {
+clojure.JS.definterface( clojure.JS, "Collection" );
+
+clojure.JS.defclass( clojure.JS, "StringBuilder", {
init: function( x ) { this.a = [ x ]; },
methods: {
append: function( x ) { this.a.push( x ); return this; },
@@ -334,7 +385,7 @@ clojure.JS.defclass( java.lang, "StringBuilder", {
}
});
-clojure.JS.defclass( java.lang, "String", {
+clojure.JS.defclass( clojure.JS, "String", {
init: function(s) {
this.s = s;
this.length = s.length;
@@ -609,7 +660,7 @@ clojure.JS.definterface( clojure.lang, "IPersistentList",
clojure.JS.defclass( clojure.lang, "EmptyList", {
extend: clojure.lang.Obj,
- implement: [clojure.lang.IPersistentList, java.util.Collection],
+ implement: [clojure.lang.IPersistentList, clojure.JS.Collection],
init: function( _meta ) { this._meta = _meta; },
methods: {
cons: function(o) {
@@ -652,7 +703,7 @@ clojure.JS.defclass( clojure.lang, "AMapEntry", {
hashCode: function(){ throw "not implemented yet"; },
toString: function(){
return this.key() + " " + this.val();
- var sw = new java.io.StringWriter();
+ var sw = new clojure.JS.StringWriter();
clojure.lang.RT.print( this, sw );
return sw.toString();
},
@@ -1078,7 +1129,7 @@ clojure.JS.definterface( clojure.lang, "IPersistentMap",
clojure.JS.defclass( clojure.lang, "APersistentMap", {
extend: clojure.lang.AFn,
- implement: [clojure.lang.IPersistentMap, java.util.Collection],
+ implement: [clojure.lang.IPersistentMap, clojure.JS.Collection],
init: function(_meta) {
this._meta = _meta;
this._hash = -1;
@@ -1152,7 +1203,7 @@ clojure.JS.defclass( clojure.lang.APersistentMap, "KeySeq", {
create: function(seq){
if(seq === null)
return null;
- return new clojure.lang.APersistentMap.KeySeq(seq);
+ return new clojure.lang.APersistentMap.KeySeq(null,seq);
}
},
methods: {
@@ -1726,7 +1777,7 @@ clojure.print_method = new clojure.lang.MultiFn(
clojure.keyword("","default"));
clojure.print_method.addMethod( String, function(s,w) {
- return clojure.print_method.apply( null, [new java.lang.String(s), w] );
+ return clojure.print_method.apply( null, [new clojure.JS.String(s), w] );
});
clojure.JS.def(clojure,"_STAR_print_readably_STAR_",true);