aboutsummaryrefslogtreecommitdiff
path: root/src/lux/compiler.clj
diff options
context:
space:
mode:
authorEduardo Julian2016-05-22 00:55:49 -0400
committerEduardo Julian2016-05-22 00:55:49 -0400
commit18ff8ef70aa422fc76244459f07a2cc4e81cc63e (patch)
treec4e2b4caac9e41bff1e246ec452b382c99510bdd /src/lux/compiler.clj
parentaa4722d0c459a59ac896ef1b30ff0e141281d41c (diff)
- Added Tail-Recursion Optimization.
Diffstat (limited to 'src/lux/compiler.clj')
-rw-r--r--src/lux/compiler.clj44
1 files changed, 24 insertions, 20 deletions
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index b9acff72a..69b3d4345 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -39,7 +39,7 @@
;; [Resources]
(def ^:private !source->last-line (atom nil))
-(defn compile-expression [syntax]
+(defn compile-expression [$begin syntax]
(|let [[[?type [_file-name _line _]] ?form] syntax]
(|do [^MethodVisitor *writer* &/get-writer
:let [debug-label (new Label)
@@ -50,50 +50,53 @@
(swap! !source->last-line assoc _file-name _line))]]
(|case ?form
(&o/$bool ?value)
- (&&lux/compile-bool compile-expression ?value)
+ (&&lux/compile-bool ?value)
(&o/$int ?value)
- (&&lux/compile-int compile-expression ?value)
+ (&&lux/compile-int ?value)
(&o/$real ?value)
- (&&lux/compile-real compile-expression ?value)
+ (&&lux/compile-real ?value)
(&o/$char ?value)
- (&&lux/compile-char compile-expression ?value)
+ (&&lux/compile-char ?value)
(&o/$text ?value)
- (&&lux/compile-text compile-expression ?value)
+ (&&lux/compile-text ?value)
(&o/$tuple ?elems)
- (&&lux/compile-tuple compile-expression ?elems)
+ (&&lux/compile-tuple (partial compile-expression $begin) ?elems)
(&o/$var (&/$Local ?idx))
- (&&lux/compile-local compile-expression ?idx)
+ (&&lux/compile-local (partial compile-expression $begin) ?idx)
(&o/$captured ?scope ?captured-id ?source)
- (&&lux/compile-captured compile-expression ?scope ?captured-id ?source)
+ (&&lux/compile-captured (partial compile-expression $begin) ?scope ?captured-id ?source)
(&o/$var (&/$Global ?owner-class ?name))
- (&&lux/compile-global compile-expression ?owner-class ?name)
+ (&&lux/compile-global (partial compile-expression $begin) ?owner-class ?name)
(&o/$apply ?fn ?args)
- (&&lux/compile-apply compile-expression ?fn ?args)
+ (&&lux/compile-apply (partial compile-expression $begin) ?fn ?args)
+
+ (&o/$loop ?args)
+ (&&lux/compile-loop (partial compile-expression $begin) $begin ?args)
(&o/$variant ?tag ?tail ?members)
- (&&lux/compile-variant compile-expression ?tag ?tail ?members)
+ (&&lux/compile-variant (partial compile-expression $begin) ?tag ?tail ?members)
(&o/$case ?value ?match)
- (&&case/compile-case compile-expression ?value ?match)
+ (&&case/compile-case (partial compile-expression $begin) ?value ?match)
(&o/$function ?arity ?scope ?env ?body)
(&&lambda/compile-function compile-expression &/$None ?arity ?scope ?env ?body)
;; Must get rid of this one...
(&o/$ann ?value-ex ?type-ex ?value-type)
- (compile-expression ?value-ex)
+ (compile-expression $begin ?value-ex)
(&o/$proc [?proc-category ?proc-name] ?args special-args)
- (&&host/compile-host compile-expression ?proc-category ?proc-name ?args special-args)
+ (&&host/compile-host (partial compile-expression $begin) ?proc-category ?proc-name ?args special-args)
_
(assert false (prn-str 'compile-expression (&/adt->text syntax)))
@@ -122,7 +125,7 @@
_ (&/with-writer (.visitMethod =class Opcodes/ACC_PUBLIC "<clinit>" "()V" nil nil)
(|do [^MethodVisitor *writer* &/get-writer
:let [_ (.visitCode *writer*)]
- _ (compile-expression expr)
+ _ (compile-expression nil expr)
:let [_ (doto *writer*
(.visitFieldInsn Opcodes/PUTSTATIC class-name &/eval-field "Ljava/lang/Object;")
(.visitInsn Opcodes/RETURN)
@@ -139,10 +142,11 @@
return))))
(def all-compilers
- (&/T [(partial &&lux/compile-def compile-expression)
- (partial &&lux/compile-program compile-expression)
- (partial &&host/compile-jvm-class compile-expression)
- &&host/compile-jvm-interface]))
+ (let [compile-expression* (partial compile-expression nil)]
+ (&/T [(partial &&lux/compile-def compile-expression)
+ (partial &&lux/compile-program compile-expression*)
+ (partial &&host/compile-jvm-class compile-expression*)
+ &&host/compile-jvm-interface])))
(defn compile-module [source-dirs name]
(let [file-name (str name ".lux")]