diff options
author | Chouser <chouser@n01se.net> | 2008-09-17 00:04:04 +0000 |
---|---|---|
committer | Chouser <chouser@n01se.net> | 2008-09-17 00:04:04 +0000 |
commit | a67ffc6bf63f54f63d033763dd18341d5e15f156 (patch) | |
tree | 21e4d174df73c23c1af383ee03d9087ff9779772 | |
parent | c68f9aefb7d4b4f2240e196556f83f76e9fd4ef5 (diff) |
ClojureScript: Dynamic Vars now work: binding and set!
-rw-r--r-- | clojurescript/clj.js | 76 | ||||
-rw-r--r-- | clojurescript/t03.cljs | 14 | ||||
-rw-r--r-- | clojurescript/t03.html | 11 | ||||
-rw-r--r-- | clojurescript/tojs.clj | 40 |
4 files changed, 120 insertions, 21 deletions
diff --git a/clojurescript/clj.js b/clojurescript/clj.js index 988173b6..5d212003 100644 --- a/clojurescript/clj.js +++ b/clojurescript/clj.js @@ -1,8 +1,12 @@ clojure = { in_ns: function(s) { - var ns = s.substring(1); - if( ! window[ns] ) { - window[ns] = {}; + var nsparts = s.substring(1).split('.'); + var base = window; + for( var i = 0; i < nsparts.length; ++i ) { + if( ! base[nsparts[i]] ) { + base[nsparts[i]] = {}; + } + base = base[nsparts[i]]; } }, refer: function(s) {}, @@ -31,7 +35,21 @@ clojure = { return seq.rest(); }, second: function(x) { return clojure.first(clojure.rest(x)); }, - prn: print, + 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 = []; + for( var i = 0; i < arguments.length; i += 2 ) { + pairs.push( [ arguments[i], arguments[i + 1] ] ) + } + return clojure.lang.ArraySeq.create( pairs ); + }, count: function(x) { if( x === null ) return 0; if( x.count ) return x.count(); @@ -42,6 +60,11 @@ clojure = { resolveVar: function( sym, ctxns ) { return ctxns[ sym ] || clojure[ sym ] || window[ sym ]; }, + def: function( ns, name, init ) { + var v = new clojure.lang.Var( ns, name ); + ns["_var_" + name] = v; + v.push( init ); + }, ObjSeq: { create: function( obj ) { var pairs = []; @@ -55,7 +78,11 @@ clojure = { lang: { Numbers: { isPos: function(x) { return x > 0; }, + inc: function(x) { return x + 1; }, dec: function(x) { return x - 1; } + }, + Util: { + equal: function(x,y) { return x == y; } } } }; @@ -146,3 +173,44 @@ clojure.lang.LazyCons.prototype.withMeta = function(_meta) { clojure.lang.LazyCons.prototype.seq = function() { return this; }; + + +clojure.lang.Var = function( ns, name ) { + this.ns = ns; + this.name = name; + this.stack = []; +}; + +clojure.lang.Var.prototype.push = function( val ) { + this.stack.push( val ); + this.ns[ this.name ] = val; +}; + +clojure.lang.Var.prototype.pop = function() { + this.stack.pop(); + this.ns[ this.name ] = this.stack[ this.stack.length - 1 ]; +}; + +clojure.lang.Var.prototype.set = function( val ) { + this.stack.pop(); + this.push( val ); +}; + +clojure.lang.Var.stack = []; + +clojure.lang.Var.pushThreadBindings = function( m ) { + var vars=[], b; + for( var bs = m.seq(); bs; bs = bs.rest()) { + b = bs.first(); + vars.push( b[0] ); + b[0].push( b[1] ); + } + clojure.lang.Var.stack.push( vars ); +}; + +clojure.lang.Var.popThreadBindings = function() { + var vars = clojure.lang.Var.stack.pop(); + for( var i = 0; i < vars.length; ++i ) { + vars[i].pop(); + } +}; diff --git a/clojurescript/t03.cljs b/clojurescript/t03.cljs new file mode 100644 index 00000000..3937cfa7 --- /dev/null +++ b/clojurescript/t03.cljs @@ -0,0 +1,14 @@ +(ns net.n01se) + +(def x 5) +(def y 10) + +(defn bind-test [] + (when (= x 2) + (set! y 90)) + (binding [x (dec x) y (inc y)] + (when (pos? x) + (bind-test))) + (prn x y)) + +(bind-test) diff --git a/clojurescript/t03.html b/clojurescript/t03.html new file mode 100644 index 00000000..6c43090a --- /dev/null +++ b/clojurescript/t03.html @@ -0,0 +1,11 @@ +<html> + <body> + <textarea rows="24" cols="80" id="ta"></textarea> + <script type="text/javascript"> + var ta = document.getElementById( 'ta' ); + function print( x ) { ta.value += x + "\n"; } + </script> + <script type="text/javascript" src="clj.js"></script> + <script type="text/javascript" src="t03.js"></script> + </body> +</html> diff --git a/clojurescript/tojs.clj b/clojurescript/tojs.clj index b4715b2f..4addd141 100644 --- a/clojurescript/tojs.clj +++ b/clojurescript/tojs.clj @@ -16,13 +16,6 @@ (defmulti tojs (fn [e ctx] (class e))) -(defmethod tojs clojure.lang.Var [e ctx] - (let [{:keys [name ns]} ^e] - (str (Compiler/munge (str (.getName ns))) "." (Compiler/munge (str name))))) - -(defmethod tojs clojure.lang.Compiler$DefExpr [e ctx] - (str (tojs (.var e) ctx) "=" (tojs (.init e) ctx))) - (defn fnmethod [fm maxm ctx] (let [lm (into {} (for [[lb lb] (.locals fm)] [lb (str (.name lb) "_" (.idx lb))])) @@ -107,11 +100,34 @@ (defmethod tojs clojure.lang.Compiler$ConstantExpr [e ctx] (const-str (.v e))) + +(defn var-parts [e] + (let [{:keys [name ns]} ^(.var e)] + [(Compiler/munge (str (.getName ns))) + (Compiler/munge (str name))])) + (defmethod tojs clojure.lang.Compiler$UnresolvedVarExpr [e ctx] (vstr ["clojure.JS.resolveVar(\"" (Compiler/munge (name (.symbol e))) "\"," (Compiler/munge (name (.name *ns*))) ")"])) +(defmethod tojs clojure.lang.Compiler$VarExpr [e ctx] + (let [[vns vname] (var-parts e)] + (str vns "." vname))) + +(defmethod tojs clojure.lang.Compiler$TheVarExpr [e ctx] + (let [[vns vname] (var-parts e)] + (str vns "._var_" vname))) + +(defmethod tojs clojure.lang.Compiler$AssignExpr [e ctx] + (let [[vns vname] (var-parts (.target e))] + (str vns "._var_" vname ".set(" (tojs (.val e) ctx) ")"))) + +(defmethod tojs clojure.lang.Compiler$DefExpr [e ctx] + (let [[vns vname] (var-parts e)] + (str "clojure.JS.def(" vns ",\"" vname "\"," (tojs (.init e) ctx) ")"))) + + (defmethod tojs clojure.lang.Compiler$InvokeExpr [e ctx] (vstr [(tojs (.fexpr e) ctx) "(" @@ -130,13 +146,6 @@ (defmethod tojs clojure.lang.Compiler$StringExpr [e ctx] (const-str (.str e))) -(defmethod tojs clojure.lang.Compiler$VarExpr [e ctx] - (tojs (.var e) ctx)) - -(defmethod tojs clojure.lang.Compiler$TheVarExpr [e ctx] - ; XXX not really right - (tojs (.var e) ctx)) - (defmethod tojs clojure.lang.Compiler$KeywordExpr [e ctx] (const-str (.k e))) @@ -186,9 +195,6 @@ (defmethod tojs clojure.lang.Compiler$BooleanExpr [e ctx] (if (.val e) "true" "false")) -(defmethod tojs clojure.lang.Compiler$AssignExpr [e ctx] - (vstr ["(" (tojs (.target e) ctx) "=" (tojs (.val e) ctx) ")"])) - (defmethod tojs clojure.lang.Compiler$ThrowExpr [e ctx] (vstr ["(function(){throw " (tojs (.excExpr e) ctx) "})()"])) |