aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2008-09-17 00:04:04 +0000
committerChouser <chouser@n01se.net>2008-09-17 00:04:04 +0000
commita67ffc6bf63f54f63d033763dd18341d5e15f156 (patch)
tree21e4d174df73c23c1af383ee03d9087ff9779772
parentc68f9aefb7d4b4f2240e196556f83f76e9fd4ef5 (diff)
ClojureScript: Dynamic Vars now work: binding and set!
-rw-r--r--clojurescript/clj.js76
-rw-r--r--clojurescript/t03.cljs14
-rw-r--r--clojurescript/t03.html11
-rw-r--r--clojurescript/tojs.clj40
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) "})()"]))