summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lisp/clojure.lisp46
-rw-r--r--src/lisp/test.lisp10
2 files changed, 52 insertions, 4 deletions
diff --git a/src/lisp/clojure.lisp b/src/lisp/clojure.lisp
index c39bffde..13386e0b 100644
--- a/src/lisp/clojure.lisp
+++ b/src/lisp/clojure.lisp
@@ -390,6 +390,7 @@
(|loop| (analyze-loop context form))
(|break| (analyze-break context form))
(|try| (analyze-try context form))
+ (|bind| (analyze-bind context form))
(t (analyze-invoke context op form))))
(defmacro emit-to-string (&body body)
@@ -417,7 +418,8 @@
(:set (emit-set context expr))
(:loop (emit-loop context expr))
(:break (emit-break context expr))
- (:try (emit-try context expr))))))
+ (:try (emit-try context expr))
+ (:bind(emit-bind context expr))))))
(defun emit-return (expr)
(format t "return ")
@@ -831,13 +833,51 @@
(dolist (e body)
(emit :statement e)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bind ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun analyze-bind (context form)
+ (let ((bindings (normalize-let-bindings (second form)))
+ (body (rest (rest form))))
+ (ccase context
+ ((:expression :fn)
+ (analyze :expression `((|fn*| (() ,form)))))
+ ((:statement :return)
+ (let* ((binding-inits
+ (mapcar (lambda (b)
+ (register-var-reference (first b))
+ (newobj :binding (newobj :type :global-binding :symbol (first b))
+ :init (analyze :expression (second b))))
+ bindings)))
+ (register-needs-tls)
+ (newobj :type :bind
+ :binding-inits binding-inits
+ :body (analyze-body context (macroexpand body))))))))
+
+(defun emit-bind (context expr)
+ (ccase context
+ ((:statement :return)
+ (let ((binding-inits (@ :binding-inits expr))
+ (body (@ :body expr)))
+ (format t "try {~%")
+ (dolist (bi binding-inits)
+ (format t "~A.pushDynamicBinding(__tld, " (var-member-name (@ :symbol (@ :binding bi))))
+ (emit :expression (@ :init bi))
+ (format t ");~%"))
+ (emit-body context body)
+ (format t "}~%finally {~%")
+ (dolist (bi binding-inits)
+ (format t "~A.popDynamicBinding(__tld);~%" (var-member-name (@ :symbol (@ :binding bi)))))
+ (format t "}~%")))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; block ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun emit-block (context expr)
(when (@ :body expr)
- (format t "{~%")
+ ;(format t "{~%")
(emit-body context (@ :body expr))
- (format t "}~%")))
+ ;(format t "}~%")
+ ))
(defun analyze-block (context form)
(cond
diff --git a/src/lisp/test.lisp b/src/lisp/test.lisp
index 16c43539..d724da70 100644
--- a/src/lisp/test.lisp
+++ b/src/lisp/test.lisp
@@ -103,4 +103,12 @@
(try
(foo x)
(fred ex)
- (bar x))) \ No newline at end of file
+ (bar x)))
+
+(defn fbind (a b c x)
+ (bind ((x a)
+ (y b))
+ c)
+ (bind ((x a)
+ (y b))
+ c)) \ No newline at end of file