diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-04-30 18:20:36 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-04-30 18:20:36 +0000 |
commit | 96db6cebb28b28f30fdc9b7232a8172a18f52ace (patch) | |
tree | f4ef8f97a7f2823730889b74f026987c8184c521 /src | |
parent | b5d91b20e71866ed881e2d8fa2f8164162b0a4e8 (diff) |
added letfn
Diffstat (limited to 'src')
-rw-r--r-- | src/lisp/clojure.lisp | 34 | ||||
-rw-r--r-- | src/lisp/test.lisp | 6 |
2 files changed, 38 insertions, 2 deletions
diff --git a/src/lisp/clojure.lisp b/src/lisp/clojure.lisp index c8645dbb..a2b0f7ea 100644 --- a/src/lisp/clojure.lisp +++ b/src/lisp/clojure.lisp @@ -14,7 +14,7 @@ "in-module" "defn*" "def" "defn" "fn" "if" "and" "or" "not" - "block" "let" "let*")) + "block" "let" "let*" "letfn")) (in-package "clojure") @@ -334,6 +334,7 @@ (|or| (analyze-or context form)) (|set| (analyze-set context form)) (|let| (analyze-let context form)) + (|letfn| (analyze-letfn context form)) (|let*| (analyze-let* context form)) (|loop| (analyze-loop context form)) (|try| (analyze-try context form)) @@ -502,6 +503,35 @@ :binding-inits binding-inits :body (analyze-body context body))))))) +(defun analyze-letfn (context form) + (cond + ((eql context :expression) + (analyze :expression `((|fn*| (() ,form))))) + (t + (let* ((*var-env* *var-env*) + (binding-exprs + ;adding all bindings to env first, mark as assigned to allow for recursion and mutual reference + (mapcar (lambda (b) + (destructuring-bind (name params &rest body) b + (let ((binding (newobj :type :binding :symbol name + ;:assigned? t + ))) + (register-local-binding binding) + ;(register-nested-fn-binding binding) + (add-to-var-env binding) + ;don't analyze lambdas yet + (list binding `(|fn*| (,params ,@body)))))) + (second form)))) + (newobj :type :let + :binding-inits (mapcar (lambda (be) + (let ((binding (first be)) + (fn (analyze :expression (second be)))) + (setf (@ :fn binding) fn) + (setf (@ :binding fn) binding) + (newobj :binding binding :init fn))) + binding-exprs) + :body (analyze-body context (rest (rest form)))))))) + (defun emit-let (context expr) (let ((binding-inits (@ :binding-inits expr)) (body (@ :body expr))) @@ -800,7 +830,7 @@ (setf (@ :id b) (get-next-id)) (unless (or (@ :anonymous-lambda? b) (will-be-static-method b)) - (emit-binding-declaration b)))) + (emit-binding-declaration b "null")))) ;body (emit :return (@ :body m)) diff --git a/src/lisp/test.lisp b/src/lisp/test.lisp index bbaf6e0a..f3427df2 100644 --- a/src/lisp/test.lisp +++ b/src/lisp/test.lisp @@ -34,4 +34,10 @@ (defn always (x) (fn () x)) +(defn fletfn (x) + (letfn ((a (b) b) + (c (d) (a d)) + (d (x) (d a))) + (c x))) + (defn fr (a b & c) c)
\ No newline at end of file |