aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lux.clj12
-rw-r--r--src/lux/analyser.clj115
-rw-r--r--src/lux/analyser/base.clj3
-rw-r--r--src/lux/analyser/case.clj7
-rw-r--r--src/lux/analyser/env.clj23
-rw-r--r--src/lux/analyser/host.clj118
-rw-r--r--src/lux/analyser/lambda.clj160
-rw-r--r--src/lux/analyser/lux.clj81
-rw-r--r--src/lux/compiler.clj69
-rw-r--r--src/lux/compiler/case.clj9
-rw-r--r--src/lux/compiler/host.clj88
-rw-r--r--src/lux/compiler/lux.clj23
-rw-r--r--src/lux/host.clj5
-rw-r--r--src/lux/lexer.clj14
-rw-r--r--src/lux/parser.clj14
-rw-r--r--src/lux/type.clj41
-rw-r--r--src/lux/util.clj119
17 files changed, 467 insertions, 434 deletions
diff --git a/src/lux.clj b/src/lux.clj
index eb81b43a0..b42d0bb42 100644
--- a/src/lux.clj
+++ b/src/lux.clj
@@ -1,10 +1,6 @@
(ns lux
- (:require (lux [lexer :as &lexer]
- [parser :as &parser]
- [type :as &type]
- [analyser :as &analyser]
- [compiler :as &compiler])
- :reload))
+ (:require [lux.compiler :as &compiler]
+ :reload-all))
(comment
;; TODO: Make macros monadic.
@@ -23,8 +19,8 @@
;; TODO:
;; TODO:
- (time (&compiler/compile-all ["lux" ;; "test2"
- ]))
+ (time (&compiler/compile-all ["lux"]))
+ (time (&compiler/compile-all ["lux" "test2"]))
;; jar cvf test2.jar *.class test2 && java -cp "test2.jar" test2
;; cd output && jar cvf test2.jar * && java -cp "test2.jar" test2 && cd ..
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index de6058f50..a9cd8670e 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -8,149 +8,150 @@
[type :as &type]
[macro :as &macro]
[host :as &host])
- (lux.analyser [base :as &]
+ (lux.analyser [base :as &&]
[lux :as &&lux]
[host :as &&host])))
;; [Utils]
(defn ^:private analyse-basic-ast [analyse-ast token]
+ (prn 'analyse-basic-ast token)
(match token
;; Standard special forms
- [::&parser/bool ?value]
- (return (list [::&/Expression [::bool ?value] [::&type/Data "java.lang.Boolean"]]))
+ [::&parser/Bool ?value]
+ (return (list [::&&/Expression [::&&/bool ?value] [::&type/Data "java.lang.Boolean"]]))
- [::&parser/int ?value]
- (return (list [::&/Expression [::int ?value] [::&type/Data "java.lang.Long"]]))
+ [::&parser/Int ?value]
+ (return (list [::&&/Expression [::&&/int ?value] [::&type/Data "java.lang.Long"]]))
- [::&parser/real ?value]
- (return (list [::&/Expression [::real ?value] [::&type/Data "java.lang.Double"]]))
+ [::&parser/Real ?value]
+ (return (list [::&&/Expression [::&&/real ?value] [::&type/Data "java.lang.Double"]]))
- [::&parser/char ?value]
- (return (list [::&/Expression [::char ?value] [::&type/Data "java.lang.Character"]]))
+ [::&parser/Char ?value]
+ (return (list [::&&/Expression [::&&/char ?value] [::&type/Data "java.lang.Character"]]))
- [::&parser/text ?value]
- (return (list [::&/Expression [::text ?value] [::&type/Data "java.lang.String"]]))
+ [::&parser/Text ?value]
+ (return (list [::&&/Expression [::&&/text ?value] [::&type/Data "java.lang.String"]]))
- [::&parser/tuple ?elems]
+ [::&parser/Tuple ?elems]
(&&lux/analyse-tuple analyse-ast ?elems)
- [::&parser/tag ?tag]
- (return (list [::&/Expression [::variant ?tag (list)] [::&type/Variant {?tag [::&type/Tuple (list)]}]]))
+ [::&parser/Tag ?tag]
+ (return (list [::&&/Expression [::&&/variant ?tag (list)] [::&type/Variant {?tag [::&type/Tuple (list)]}]]))
- [::&parser/ident ?ident]
+ [::&parser/Ident ?ident]
(&&lux/analyse-ident analyse-ast ?ident)
- [::&parser/form ([[::&parser/ident "case'"] ?variant & ?branches] :seq)]
+ [::&parser/Form ([[::&parser/Ident "case'"] ?variant & ?branches] :seq)]
(&&lux/analyse-case analyse-ast ?variant ?branches)
- [::&parser/form ([[::&parser/ident "lambda'"] [::&parser/ident ?self] [::&parser/ident ?arg] ?body] :seq)]
+ [::&parser/Form ([[::&parser/Ident "lambda'"] [::&parser/Ident ?self] [::&parser/Ident ?arg] ?body] :seq)]
(&&lux/analyse-lambda analyse-ast ?self ?arg ?body)
- [::&parser/form ([[::&parser/ident "def'"] [::&parser/ident ?name] ?value] :seq)]
+ [::&parser/Form ([[::&parser/Ident "def'"] [::&parser/Ident ?name] ?value] :seq)]
(&&lux/analyse-def analyse-ast ?name ?value)
- [::&parser/form ([[::&parser/ident "declare-macro"] [::&parser/ident ?ident]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "declare-macro"] [::&parser/Ident ?ident]] :seq)]
(&&lux/analyse-declare-macro ?ident)
- [::&parser/form ([[::&parser/ident "require"] [::&parser/text ?path]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "require"] [::&parser/Text ?path]] :seq)]
(&&lux/analyse-require analyse-ast ?path)
;; Host special forms
- [::&parser/form ([[::&parser/ident "exec"] & ?exprs] :seq)]
+ [::&parser/Form ([[::&parser/Ident "exec"] & ?exprs] :seq)]
(&&host/analyse-exec analyse-ast ?exprs)
;; Integer arithmetic
- [::&parser/form ([[::&parser/ident "jvm;iadd"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;iadd"] ?x ?y] :seq)]
(&&host/analyse-jvm-iadd analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;isub"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;isub"] ?x ?y] :seq)]
(&&host/analyse-jvm-isub analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;imul"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;imul"] ?x ?y] :seq)]
(&&host/analyse-jvm-imul analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;idiv"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;idiv"] ?x ?y] :seq)]
(&&host/analyse-jvm-idiv analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;irem"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;irem"] ?x ?y] :seq)]
(&&host/analyse-jvm-irem analyse-ast ?x ?y)
;; Long arithmetic
- [::&parser/form ([[::&parser/ident "jvm;ladd"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;ladd"] ?x ?y] :seq)]
(&&host/analyse-jvm-ladd analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;lsub"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;lsub"] ?x ?y] :seq)]
(&&host/analyse-jvm-lsub analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;lmul"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;lmul"] ?x ?y] :seq)]
(&&host/analyse-jvm-lmul analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;ldiv"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;ldiv"] ?x ?y] :seq)]
(&&host/analyse-jvm-ldiv analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;lrem"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;lrem"] ?x ?y] :seq)]
(&&host/analyse-jvm-lrem analyse-ast ?x ?y)
;; Float arithmetic
- [::&parser/form ([[::&parser/ident "jvm;fadd"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;fadd"] ?x ?y] :seq)]
(&&host/analyse-jvm-fadd analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;fsub"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;fsub"] ?x ?y] :seq)]
(&&host/analyse-jvm-fsub analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;fmul"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;fmul"] ?x ?y] :seq)]
(&&host/analyse-jvm-fmul analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;fdiv"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;fdiv"] ?x ?y] :seq)]
(&&host/analyse-jvm-fdiv analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;frem"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;frem"] ?x ?y] :seq)]
(&&host/analyse-jvm-frem analyse-ast ?x ?y)
;; Double arithmetic
- [::&parser/form ([[::&parser/ident "jvm;dadd"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;dadd"] ?x ?y] :seq)]
(&&host/analyse-jvm-dadd analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;dsub"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;dsub"] ?x ?y] :seq)]
(&&host/analyse-jvm-dsub analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;dmul"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;dmul"] ?x ?y] :seq)]
(&&host/analyse-jvm-dmul analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;ddiv"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;ddiv"] ?x ?y] :seq)]
(&&host/analyse-jvm-ddiv analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;drem"] ?x ?y] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;drem"] ?x ?y] :seq)]
(&&host/analyse-jvm-drem analyse-ast ?x ?y)
- [::&parser/form ([[::&parser/ident "jvm;getstatic"] [::&parser/ident ?class] [::&parser/ident ?field]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;getstatic"] [::&parser/Ident ?class] [::&parser/Ident ?field]] :seq)]
(&&host/analyse-jvm-getstatic analyse-ast ?class ?field)
- [::&parser/form ([[::&parser/ident "jvm;getfield"] [::&parser/ident ?class] [::&parser/ident ?field] ?object] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;getfield"] [::&parser/Ident ?class] [::&parser/Ident ?field] ?object] :seq)]
(&&host/analyse-jvm-getfield analyse-ast ?class ?field ?object)
- [::&parser/form ([[::&parser/ident "jvm;invokestatic"] [::&parser/ident ?class] [::&parser/text ?method] [::&parser/tuple ?classes] [::&parser/tuple ?args]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;invokestatic"] [::&parser/Ident ?class] [::&parser/Text ?method] [::&parser/Tuple ?classes] [::&parser/Tuple ?args]] :seq)]
(&&host/analyse-jvm-invokestatic analyse-ast ?class ?method ?classes ?args)
- [::&parser/form ([[::&parser/ident "jvm;invokevirtual"] [::&parser/ident ?class] [::&parser/text ?method] [::&parser/tuple ?classes] ?object [::&parser/tuple ?args]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;invokevirtual"] [::&parser/Ident ?class] [::&parser/Text ?method] [::&parser/Tuple ?classes] ?object [::&parser/Tuple ?args]] :seq)]
(&&host/analyse-jvm-invokevirtual analyse-ast ?class ?method ?classes ?object ?args)
- [::&parser/form ([[::&parser/ident "jvm;new"] [::&parser/ident ?class] [::&parser/tuple ?classes] [::&parser/tuple ?args]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;new"] [::&parser/Ident ?class] [::&parser/Tuple ?classes] [::&parser/Tuple ?args]] :seq)]
(&&host/analyse-jvm-new analyse-ast ?class ?classes ?args)
- [::&parser/form ([[::&parser/ident "jvm;new-array"] [::&parser/ident ?class] [::&parser/int ?length]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;new-array"] [::&parser/Ident ?class] [::&parser/Int ?length]] :seq)]
(&&host/analyse-jvm-new-array analyse-ast ?class ?length)
- [::&parser/form ([[::&parser/ident "jvm;aastore"] ?array [::&parser/int ?idx] ?elem] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;aastore"] ?array [::&parser/Int ?idx] ?elem] :seq)]
(&&host/analyse-jvm-aastore analyse-ast ?array ?idx ?elem)
- [::&parser/form ([[::&parser/ident "jvm;aaload"] ?array [::&parser/int ?idx]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;aaload"] ?array [::&parser/Int ?idx]] :seq)]
(&&host/analyse-jvm-aaload analyse-ast ?array ?idx)
- [::&parser/form ([[::&parser/ident "jvm;class"] [::&parser/ident ?name] [::&parser/ident ?super-class] [::&parser/tuple ?fields]] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;class"] [::&parser/Ident ?name] [::&parser/Ident ?super-class] [::&parser/Tuple ?fields]] :seq)]
(&&host/analyse-jvm-class analyse-ast ?name ?super-class ?fields)
- [::&parser/form ([[::&parser/ident "jvm;interface"] [::&parser/ident ?name] & ?members] :seq)]
+ [::&parser/Form ([[::&parser/Ident "jvm;interface"] [::&parser/Ident ?name] & ?members] :seq)]
(&&host/analyse-jvm-interface analyse-ast ?name ?members)
_
@@ -158,12 +159,13 @@
(defn ^:private analyse-ast [token]
(match token
- [::&parser/form ([[::&parser/tag ?tag] & ?data] :seq)]
+ [::&parser/Form ([[::&parser/Tag ?tag] & ?data] :seq)]
(exec [=data (mapcat-m analyse-ast ?data)
- =data-types (map-m &/expr-type =data)]
- (return (list [::&/Expression [::variant ?tag =data] [::&type/Variant {?tag [::&type/Tuple =data-types]}]])))
+ :let [_ (prn '=data =data)]
+ =data-types (map-m &&/expr-type =data)]
+ (return (list [::&&/Expression [::&&/variant ?tag =data] [::&type/Variant {?tag [::&type/Tuple =data-types]}]])))
- [::&parser/form ([?fn & ?args] :seq)]
+ [::&parser/Form ([?fn & ?args] :seq)]
(try-all-m [(&&lux/analyse-call analyse-ast ?fn ?args)
(analyse-basic-ast analyse-ast token)])
@@ -172,5 +174,6 @@
;; [Resources]
(def analyse
- (exec [asts &parser/parse]
+ (exec [asts &parser/parse
+ :let [_ (prn 'analyse/asts asts)]]
(mapcat-m analyse-ast asts)))
diff --git a/src/lux/analyser/base.clj b/src/lux/analyser/base.clj
index 713b58f18..4ed3ef569 100644
--- a/src/lux/analyser/base.clj
+++ b/src/lux/analyser/base.clj
@@ -6,12 +6,13 @@
;; [Resources]
(defn expr-type [syntax+]
+ (prn 'expr-type syntax+)
(match syntax+
[::Expression _ type]
(return type)
_
- (fail "Can't retrieve the type of a non-expression.")))
+ (fail "[Analyser Error] Can't retrieve the type of a non-expression.")))
(defn analyse-1 [analyse elem]
(exec [output (analyse elem)]
diff --git a/src/lux/analyser/case.clj b/src/lux/analyser/case.clj
index 8a914ab70..8fa8ff29f 100644
--- a/src/lux/analyser/case.clj
+++ b/src/lux/analyser/case.clj
@@ -5,7 +5,8 @@
assert!]]
[parser :as &parser]
[type :as &type])
- (lux.analyser [env :as &env])))
+ (lux.analyser [base :as &&]
+ [env :as &env])))
;; [Resources]
(defn locals [member]
@@ -22,12 +23,12 @@
_
(list)))
-(defn analyse-branch [analyse-1 max-registers [bindings body]]
+(defn analyse-branch [analyse max-registers [bindings body]]
(reduce (fn [body* name]
(&env/with-local name :local &type/+dont-care-type+ body*))
(reduce (fn [body* _]
(&env/with-local "#" :local &type/+dont-care-type+ body*))
- (analyse-1 body)
+ (&&/analyse-1 analyse body)
(range (- max-registers (count bindings))))
bindings))
diff --git a/src/lux/analyser/env.clj b/src/lux/analyser/env.clj
index ef5620e77..177aa54dd 100644
--- a/src/lux/analyser/env.clj
+++ b/src/lux/analyser/env.clj
@@ -1,8 +1,9 @@
(ns lux.analyser.env
(:require [clojure.core.match :refer [match]]
(lux [util :as &util :refer [exec return fail
- try-all-m map-m mapcat-m reduce-m
- assert!]])))
+ if-m try-all-m map-m mapcat-m reduce-m
+ assert!]])
+ [lux.analyser.base :as &&]))
;; [Resources]
(def next-local-idx
@@ -24,7 +25,7 @@
(defn annotate [module name access type]
(fn [state]
(let [full-name (str module &util/+name-separator+ name)
- bound [::Expression [::global module name] type]]
+ bound [::&&/Expression [::&&/global module name] type]]
[::&util/ok [(-> state
(assoc-in [::&util/modules module name] {:args-n [:None]
:access access
@@ -39,11 +40,11 @@
nil]]))
(defn define [module name]
- (exec [? annotated?
- _ (assert! ? (str "[Analyser Error] Can't define an unannotated element: " name))]
- (fn [state]
- [::&util/ok [(assoc-in state [::&util/modules module name :defined?] true)
- nil]])))
+ (if-m (annotated? module name)
+ (fn [state]
+ [::&util/ok [(assoc-in state [::&util/modules module name :defined?] true)
+ nil]])
+ (fail (str "[Analyser Error] Can't define an unannotated element: " name))))
(defn with-local [name mode type body]
(fn [state]
@@ -51,11 +52,11 @@
=return (body (update-in state [::&util/local-envs]
(fn [[top & stack]]
(let [bound-unit (case mode
- :self [::self (list)]
- :local [::local (get-in top [:locals :counter])])]
+ :self [::&&/self (list)]
+ :local [::&&/local (get-in top [:locals :counter])])]
(cons (-> top
(update-in [:locals :counter] inc)
- (assoc-in [:locals :mappings name] [::Expression bound-unit type]))
+ (assoc-in [:locals :mappings name] [::&&/Expression bound-unit type]))
stack)))))]
(match =return
[::&util/ok [?state ?value]]
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj
index d9804f9e8..5a7585226 100644
--- a/src/lux/analyser/host.clj
+++ b/src/lux/analyser/host.clj
@@ -7,12 +7,12 @@
[parser :as &parser]
[type :as &type]
[host :as &host])
- (lux.analyser [base :as &])))
+ (lux.analyser [base :as &&])))
;; [Utils]
(defn ^:private extract-ident [ident]
(match ident
- [::&parser/ident ?ident]
+ [::&parser/Ident ?ident]
(return ?ident)
_
@@ -22,88 +22,88 @@
(do-template [<name> <ident> <output-tag> <wrapper-class>]
(defn <name> [analyse ?x ?y]
(exec [:let [=type [::&type/Data <wrapper-class>]]
- [=x =y] (&/analyse-2 analyse ?x ?y)
- =x-type (&/expr-type =x)
- =y-type (&/expr-type =y)
+ [=x =y] (&&/analyse-2 analyse ?x ?y)
+ =x-type (&&/expr-type =x)
+ =y-type (&&/expr-type =y)
_ (&type/solve =type =x-type)
_ (&type/solve =type =y-type)]
- (return (list [::&/Expression [<output-tag> =x =y] =type]))))
-
- analyse-jvm-iadd "jvm;iadd" ::jvm-iadd "java.lang.Integer"
- analyse-jvm-isub "jvm;isub" ::jvm-isub "java.lang.Integer"
- analyse-jvm-imul "jvm;imul" ::jvm-imul "java.lang.Integer"
- analyse-jvm-idiv "jvm;idiv" ::jvm-idiv "java.lang.Integer"
- analyse-jvm-irem "jvm;irem" ::jvm-irem "java.lang.Integer"
-
- analyse-jvm-ladd "jvm;ladd" ::jvm-ladd "java.lang.Long"
- analyse-jvm-lsub "jvm;lsub" ::jvm-lsub "java.lang.Long"
- analyse-jvm-lmul "jvm;lmul" ::jvm-lmul "java.lang.Long"
- analyse-jvm-ldiv "jvm;ldiv" ::jvm-ldiv "java.lang.Long"
- analyse-jvm-lrem "jvm;lrem" ::jvm-lrem "java.lang.Long"
-
- analyse-jvm-fadd "jvm;fadd" ::jvm-fadd "java.lang.Float"
- analyse-jvm-fsub "jvm;fsub" ::jvm-fsub "java.lang.Float"
- analyse-jvm-fmul "jvm;fmul" ::jvm-fmul "java.lang.Float"
- analyse-jvm-fdiv "jvm;fdiv" ::jvm-fdiv "java.lang.Float"
- analyse-jvm-frem "jvm;frem" ::jvm-frem "java.lang.Float"
-
- analyse-jvm-dadd "jvm;dadd" ::jvm-dadd "java.lang.Double"
- analyse-jvm-dsub "jvm;dsub" ::jvm-dsub "java.lang.Double"
- analyse-jvm-dmul "jvm;dmul" ::jvm-dmul "java.lang.Double"
- analyse-jvm-ddiv "jvm;ddiv" ::jvm-ddiv "java.lang.Double"
- analyse-jvm-drem "jvm;drem" ::jvm-drem "java.lang.Double"
+ (return (list [::&&/Expression [<output-tag> =x =y] =type]))))
+
+ analyse-jvm-iadd "jvm;iadd" ::&&/jvm-iadd "java.lang.Integer"
+ analyse-jvm-isub "jvm;isub" ::&&/jvm-isub "java.lang.Integer"
+ analyse-jvm-imul "jvm;imul" ::&&/jvm-imul "java.lang.Integer"
+ analyse-jvm-idiv "jvm;idiv" ::&&/jvm-idiv "java.lang.Integer"
+ analyse-jvm-irem "jvm;irem" ::&&/jvm-irem "java.lang.Integer"
+
+ analyse-jvm-ladd "jvm;ladd" ::&&/jvm-ladd "java.lang.Long"
+ analyse-jvm-lsub "jvm;lsub" ::&&/jvm-lsub "java.lang.Long"
+ analyse-jvm-lmul "jvm;lmul" ::&&/jvm-lmul "java.lang.Long"
+ analyse-jvm-ldiv "jvm;ldiv" ::&&/jvm-ldiv "java.lang.Long"
+ analyse-jvm-lrem "jvm;lrem" ::&&/jvm-lrem "java.lang.Long"
+
+ analyse-jvm-fadd "jvm;fadd" ::&&/jvm-fadd "java.lang.Float"
+ analyse-jvm-fsub "jvm;fsub" ::&&/jvm-fsub "java.lang.Float"
+ analyse-jvm-fmul "jvm;fmul" ::&&/jvm-fmul "java.lang.Float"
+ analyse-jvm-fdiv "jvm;fdiv" ::&&/jvm-fdiv "java.lang.Float"
+ analyse-jvm-frem "jvm;frem" ::&&/jvm-frem "java.lang.Float"
+
+ analyse-jvm-dadd "jvm;dadd" ::&&/jvm-dadd "java.lang.Double"
+ analyse-jvm-dsub "jvm;dsub" ::&&/jvm-dsub "java.lang.Double"
+ analyse-jvm-dmul "jvm;dmul" ::&&/jvm-dmul "java.lang.Double"
+ analyse-jvm-ddiv "jvm;ddiv" ::&&/jvm-ddiv "java.lang.Double"
+ analyse-jvm-drem "jvm;drem" ::&&/jvm-drem "java.lang.Double"
)
(defn analyse-jvm-getstatic [analyse ?class ?field]
(exec [=class (&host/full-class-name ?class)
=type (&host/lookup-static-field =class ?field)]
- (return (list [::&/Expression [::jvm-getstatic =class ?field] =type]))))
+ (return (list [::&&/Expression [::&&/jvm-getstatic =class ?field] =type]))))
(defn analyse-jvm-getfield [analyse ?class ?field ?object]
(exec [=class (&host/full-class-name ?class)
=type (&host/lookup-static-field =class ?field)
- =object (&/analyse-1 ?object)]
- (return (list [::&/Expression [::jvm-getfield =class ?field =object] =type]))))
+ =object (&&/analyse-1 ?object)]
+ (return (list [::&&/Expression [::&&/jvm-getfield =class ?field =object] =type]))))
(defn analyse-jvm-invokestatic [analyse ?class ?method ?classes ?args]
(exec [=class (&host/full-class-name ?class)
=classes (map-m &host/extract-jvm-param ?classes)
=return (&host/lookup-virtual-method =class ?method =classes)
=args (mapcat-m analyse ?args)]
- (return (list [::&/Expression [::jvm-invokestatic =class ?method =classes =args] =return]))))
+ (return (list [::&&/Expression [::&&/jvm-invokestatic =class ?method =classes =args] =return]))))
(defn analyse-jvm-invokevirtual [analyse ?class ?method ?classes ?object ?args]
(exec [=class (&host/full-class-name ?class)
=classes (map-m &host/extract-jvm-param ?classes)
=return (&host/lookup-virtual-method =class ?method =classes)
- =object (&/analyse-1 ?object)
+ =object (&&/analyse-1 ?object)
=args (mapcat-m analyse ?args)]
- (return (list [::&/Expression [::jvm-invokevirtual =class ?method =classes =object =args] =return]))))
+ (return (list [::&&/Expression [::&&/jvm-invokevirtual =class ?method =classes =object =args] =return]))))
(defn analyse-jvm-new [analyse ?class ?classes ?args]
(exec [=class (&host/full-class-name ?class)
=classes (map-m &host/extract-jvm-param ?classes)
=args (mapcat-m analyse ?args)]
- (return (list [::&/Expression [::jvm-new =class =classes =args] [::&type/Data =class]]))))
+ (return (list [::&&/Expression [::&&/jvm-new =class =classes =args] [::&type/Data =class]]))))
(defn analyse-jvm-new-array [analyse ?class ?length]
(exec [=class (&host/full-class-name ?class)]
- (return (list [::&/Expression [::jvm-new-array =class ?length] [::&type/Array [::&type/Data =class]]]))))
+ (return (list [::&&/Expression [::&&/jvm-new-array =class ?length] [::&type/Array [::&type/Data =class]]]))))
(defn analyse-jvm-aastore [analyse ?array ?idx ?elem]
- (exec [[=array =elem] (&/analyse-2 ?array ?elem)
- =array-type (&/expr-type =array)]
- (return (list [::&/Expression [::jvm-aastore =array ?idx =elem] =array-type]))))
+ (exec [[=array =elem] (&&/analyse-2 ?array ?elem)
+ =array-type (&&/expr-type =array)]
+ (return (list [::&&/Expression [::&&/jvm-aastore =array ?idx =elem] =array-type]))))
(defn analyse-jvm-aaload [analyse ?array ?idx]
- (exec [=array (&/analyse-1 ?array)
- =array-type (&/expr-type =array)]
- (return (list [::&/Expression [::jvm-aaload =array ?idx] =array-type]))))
+ (exec [=array (&&/analyse-1 ?array)
+ =array-type (&&/expr-type =array)]
+ (return (list [::&&/Expression [::&&/jvm-aaload =array ?idx] =array-type]))))
(defn analyse-jvm-class [analyse ?name ?super-class ?fields]
(exec [?fields (map-m (fn [?field]
(match ?field
- [::&parser/tuple ([[::&parser/ident ?class] [::&parser/ident ?field-name]] :seq)]
+ [::&parser/Tuple ([[::&parser/Ident ?class] [::&parser/Ident ?field-name]] :seq)]
(return [?class ?field-name])
_
@@ -113,27 +113,29 @@
[field {:access :public
:type class}]))]
$module &util/get-module-name]
- (return (list [::&/Statement [::jvm-class [$module ?name] ?super-class =fields {}]]))))
+ (return (list [::&&/Statement [::&&/jvm-class $module ?name ?super-class =fields {}]]))))
(defn analyse-jvm-interface [analyse ?name ?members]
- (exec [?members (map-m #(match %
- [::&parser/form ([[::&parser/ident ":"] [::&parser/ident ?member-name]
- [::&parser/form ([[::&parser/ident "->"] [::&parser/tuple ?inputs] [::&parser/ident ?output]] :seq)]]
- :seq)]
- (exec [?inputs (map-m extract-ident ?inputs)]
- (return [?member-name [?inputs ?output]]))
-
- _
- (fail ""))
+ (prn 'analyse-jvm-interface ?name ?members)
+ (exec [?members (map-m (fn [member]
+ (match member
+ [::&parser/Form ([[::&parser/Ident ":"] [::&parser/Ident ?member-name]
+ [::&parser/Form ([[::&parser/Ident "->"] [::&parser/Tuple ?inputs] [::&parser/Ident ?output]] :seq)]]
+ :seq)]
+ (exec [?inputs (map-m extract-ident ?inputs)]
+ (return [?member-name [?inputs ?output]]))
+
+ _
+ (fail "")))
?members)
:let [=methods (into {} (for [[method [inputs output]] ?members]
[method {:access :public
:type [inputs output]}]))]
$module &util/get-module-name]
- (return (list [::&/Statement [::jvm-interface [$module ?name] {} =methods]]))))
+ (return (list [::&&/Statement [::&&/jvm-interface $module ?name =methods]]))))
(defn analyse-exec [analyse ?exprs]
(exec [_ (assert! (count ?exprs) "\"exec\" expressions can't have empty bodies.")
=exprs (mapcat-m analyse ?exprs)
- =exprs-types (map-m &/expr-type =exprs)]
- (return (list [::&/Expression [::do =exprs] (last =exprs-types)]))))
+ =exprs-types (map-m &&/expr-type =exprs)]
+ (return (list [::&&/Expression [::&&/exec =exprs] (last =exprs-types)]))))
diff --git a/src/lux/analyser/lambda.clj b/src/lux/analyser/lambda.clj
index 2d08ee338..dab4e8901 100644
--- a/src/lux/analyser/lambda.clj
+++ b/src/lux/analyser/lambda.clj
@@ -3,7 +3,8 @@
(lux [util :as &util :refer [exec return fail
try-all-m map-m mapcat-m reduce-m
assert!]])
- (lux.analyser [env :as &env])))
+ (lux.analyser [base :as &&]
+ [env :as &env])))
;; [Resource]
(defn with-lambda [self self-type arg arg-type body]
@@ -17,142 +18,139 @@
(defn close-over [scope ident register frame]
(match register
- [::Expression _ register-type]
- (let [register* [::Expression [::captured scope (get-in frame [:closure :counter]) register] register-type]]
+ [::&&/Expression _ register-type]
+ (let [register* [::&&/Expression [::&&/captured scope (get-in frame [:closure :counter]) register] register-type]]
[register* (update-in frame [:closure] #(-> %
(update-in [:counter] inc)
(assoc-in [:mappings ident] register*)))])))
(defn raise-expr [arg syntax]
(match syntax
- [::Expression ?form ?type]
+ [::&&/Expression ?form ?type]
(match ?form
- [::bool ?value]
+ [::&&/bool ?value]
syntax
- [::int ?value]
+ [::&&/int ?value]
syntax
- [::real ?value]
+ [::&&/real ?value]
syntax
- [::char ?value]
+ [::&&/char ?value]
syntax
- [::text ?value]
+ [::&&/text ?value]
syntax
- [::tuple ?members]
- [::Expression [::tuple (map (partial raise-expr arg) ?members)] ?type]
+ [::&&/tuple ?members]
+ [::&&/Expression [::&&/tuple (map (partial raise-expr arg) ?members)] ?type]
- [::variant ?tag ?members]
- [::Expression [::variant ?tag (map (partial raise-expr arg) ?members)] ?type]
+ [::&&/variant ?tag ?members]
+ [::&&/Expression [::&&/variant ?tag (map (partial raise-expr arg) ?members)] ?type]
- [::local ?idx]
- [::Expression [::local (inc ?idx)] ?type]
+ [::&&/local ?idx]
+ [::&&/Expression [::&&/local (inc ?idx)] ?type]
- [::captured _ _ ?source]
+ [::&&/captured _ _ ?source]
?source
- [::self ?curried]
- [::Expression [::self (cons arg (map (partial raise-expr arg) ?curried))] ?type]
+ [::&&/self ?curried]
+ [::&&/Expression [::&&/self (cons arg (map (partial raise-expr arg) ?curried))] ?type]
- [::global _ _]
+ [::&&/global _ _]
syntax
- [::case ?variant ?base ?num-bindings ?branches]
- [::Expression [::case (raise-expr arg ?variant) (inc ?base) ?num-bindings
- (for [[?pattern ?body] ?branches]
- [?pattern (raise-expr arg ?body)])]
+ [::&&/case ?variant ?base ?num-bindings ?branches]
+ [::&&/Expression [::&&/case (raise-expr arg ?variant) (inc ?base) ?num-bindings
+ (for [[?pattern ?body] ?branches]
+ [?pattern (raise-expr arg ?body)])]
?type]
- [::lambda ?scope ?captured ?args ?value]
- [::Expression [::lambda (pop ?scope)
- (into {} (for [[?name ?sub-syntax] ?captured]
- [?name (raise-expr arg ?sub-syntax)]))
- ?args
- ?value]
+ [::&&/lambda ?scope ?captured ?args ?value]
+ [::&&/Expression [::&&/lambda (pop ?scope)
+ (into {} (for [[?name ?sub-syntax] ?captured]
+ [?name (raise-expr arg ?sub-syntax)]))
+ ?args
+ ?value]
?type]
- [::call ?func ?args]
- [::Expression [::call (raise-expr arg ?func) (map (partial raise-expr arg) ?args)] ?type]
+ [::&&/call ?func ?args]
+ [::&&/Expression [::&&/call (raise-expr arg ?func) (map (partial raise-expr arg) ?args)] ?type]
- [::do ?asts]
- [::Expression [::do (map (partial raise-expr arg) ?asts)] ?type]
+ [::&&/exec ?asts]
+ [::&&/Expression [::&&/exec (map (partial raise-expr arg) ?asts)] ?type]
- [::jvm-getstatic _ _]
+ [::&&/jvm-getstatic _ _]
syntax
- [::jvm-invokevirtual ?class ?method ?arg-classes ?obj ?args]
- [::Expression [::jvm-invokevirtual ?class ?method ?arg-classes
- (raise-expr arg ?obj)
- (map (partial raise-expr arg) ?args)]
+ [::&&/jvm-invokevirtual ?class ?method ?arg-classes ?obj ?args]
+ [::&&/Expression [::&&/jvm-invokevirtual ?class ?method ?arg-classes
+ (raise-expr arg ?obj)
+ (map (partial raise-expr arg) ?args)]
?type]
;; Integer arithmetic
- [::jvm-iadd ?x ?y]
- [::Expression [::jvm-iadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-iadd ?x ?y]
+ [::&&/Expression [::&&/jvm-iadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-isub ?x ?y]
- [::Expression [::jvm-isub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-isub ?x ?y]
+ [::&&/Expression [::&&/jvm-isub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-imul ?x ?y]
- [::Expression [::jvm-imul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-imul ?x ?y]
+ [::&&/Expression [::&&/jvm-imul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-idiv ?x ?y]
- [::Expression [::jvm-idiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-idiv ?x ?y]
+ [::&&/Expression [::&&/jvm-idiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-irem ?x ?y]
- [::Expression [::jvm-irem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-irem ?x ?y]
+ [::&&/Expression [::&&/jvm-irem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
;; Long arithmetic
- [::jvm-ladd ?x ?y]
- [::Expression [::jvm-ladd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-ladd ?x ?y]
+ [::&&/Expression [::&&/jvm-ladd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-lsub ?x ?y]
- [::Expression [::jvm-lsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-lsub ?x ?y]
+ [::&&/Expression [::&&/jvm-lsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-lmul ?x ?y]
- [::Expression [::jvm-lmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-lmul ?x ?y]
+ [::&&/Expression [::&&/jvm-lmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-ldiv ?x ?y]
- [::Expression [::jvm-ldiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-ldiv ?x ?y]
+ [::&&/Expression [::&&/jvm-ldiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-lrem ?x ?y]
- [::Expression [::jvm-lrem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-lrem ?x ?y]
+ [::&&/Expression [::&&/jvm-lrem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
;; Float arithmetic
- [::jvm-fadd ?x ?y]
- [::Expression [::jvm-fadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-fadd ?x ?y]
+ [::&&/Expression [::&&/jvm-fadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-fsub ?x ?y]
- [::Expression [::jvm-fsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-fsub ?x ?y]
+ [::&&/Expression [::&&/jvm-fsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-fmul ?x ?y]
- [::Expression [::jvm-fmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-fmul ?x ?y]
+ [::&&/Expression [::&&/jvm-fmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-fdiv ?x ?y]
- [::Expression [::jvm-fdiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-fdiv ?x ?y]
+ [::&&/Expression [::&&/jvm-fdiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-frem ?x ?y]
- [::Expression [::jvm-frem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-frem ?x ?y]
+ [::&&/Expression [::&&/jvm-frem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
;; Double arithmetic
- [::jvm-dadd ?x ?y]
- [::Expression [::jvm-dadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-dadd ?x ?y]
+ [::&&/Expression [::&&/jvm-dadd (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-dsub ?x ?y]
- [::Expression [::jvm-dsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-dsub ?x ?y]
+ [::&&/Expression [::&&/jvm-dsub (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-dmul ?x ?y]
- [::Expression [::jvm-dmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-dmul ?x ?y]
+ [::&&/Expression [::&&/jvm-dmul (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-ddiv ?x ?y]
- [::Expression [::jvm-ddiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
+ [::&&/jvm-ddiv ?x ?y]
+ [::&&/Expression [::&&/jvm-ddiv (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
- [::jvm-drem ?x ?y]
- [::Expression [::jvm-drem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
-
- _
- (assert false syntax)
+ [::&&/jvm-drem ?x ?y]
+ [::&&/Expression [::&&/jvm-drem (raise-expr arg ?x) (raise-expr arg ?y)] ?type]
)))
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj
index b7aa46cee..ba6f40ff3 100644
--- a/src/lux/analyser/lux.clj
+++ b/src/lux/analyser/lux.clj
@@ -2,7 +2,7 @@
(:require (clojure [template :refer [do-template]])
[clojure.core.match :refer [match]]
(lux [util :as &util :refer [exec return fail
- try-all-m map-m mapcat-m reduce-m
+ if-m try-all-m map-m mapcat-m reduce-m
assert!]]
[parser :as &parser]
[type :as &type]
@@ -19,11 +19,11 @@
=elems-types (map-m &/expr-type =elems)
;; :let [_ (prn 'analyse-tuple =elems)]
]
- (return (list [::&/Expression [::tuple =elems] [::&type/Tuple =elems-types]]))))
+ (return (list [::&/Expression [::&/tuple =elems] [::&type/Tuple =elems-types]]))))
(defn analyse-ident [analyse ident]
(fn [state]
- (let [[top & stack*] (::local-envs state)]
+ (let [[top & stack*] (::&util/local-envs state)]
(if-let [=bound (or (get-in top [:locals :mappings ident])
(get-in top [:closure :mappings ident]))]
[::&util/ok [state (list =bound)]]
@@ -52,7 +52,7 @@
(match =fn
[::&/Expression =fn-form =fn-type]
(match =fn-form
- [::global ?module ?name]
+ [::&/global ?module ?name]
(exec [macro? (&&env/macro? ?module ?name)]
(if macro?
(let [macro-class (&host/location (list ?name ?module))
@@ -66,11 +66,11 @@
(if (> needs-num provides-num)
[needs-num [::&type/function (drop provides-num ?fargs) ?freturn]]
[needs-num &type/+dont-care-type+])))]]
- (return (list [::&/Expression [::static-call needs-num =fn =args] =return-type])))))
+ (return (list [::&/Expression [::&/static-call needs-num =fn =args] =return-type])))))
_
(exec [=args (mapcat-m analyse ?args)]
- (return (list [::&/Expression [::call =fn =args] &type/+dont-care-type+]))))
+ (return (list [::&/Expression [::&/call =fn =args] &type/+dont-care-type+]))))
:else
(fail "Can't call something without a type."))
@@ -84,57 +84,56 @@
locals-per-branch (map &&case/locals (map first branches))
max-locals (reduce max 0 (map count locals-per-branch))]
base-register &&env/next-local-idx
- =bodies (map-m (partial &&case/analyse-branch &/analyse-1 max-locals)
+ =bodies (map-m (partial &&case/analyse-branch analyse max-locals)
(map vector locals-per-branch (map second branches)))
+ :let [_ (prn 'analyse-case/=bodies =bodies)]
=body-types (map-m &/expr-type =bodies)
=case-type (reduce-m &type/merge [::&type/Nothing] =body-types)
:let [=branches (map vector (map first branches) =bodies)]]
- (return (list [::&/Expression [::case =variant base-register max-locals =branches] =case-type]))))
+ (return (list [::&/Expression [::&/case =variant base-register max-locals =branches] =case-type]))))
(defn analyse-lambda [analyse ?self ?arg ?body]
- (exec [[_ =arg =return :as =function] &type/fresh-function
- [=scope =captured =body] (&&lambda/with-lambda ?self =function
+ (exec [[_ =arg =return :as =lambda-type] &type/fresh-function
+ [=scope =captured =body] (&&lambda/with-lambda ?self =lambda-type
?arg =arg
(&/analyse-1 analyse ?body))
=body-type (&/expr-type =body)
- =function (exec [_ (&type/solve =return =body-type)]
- (&type/clean =function))
- :let [=lambda (match =body
- [::&/Expression [::lambda ?sub-scope ?sub-captured ?sub-args ?sub-body] =body-type]
- [::&/Expression [::lambda =scope =captured (cons ?arg ?sub-args) (&&lambda/raise-expr ?arg ?sub-body)] =body-type]
+ =lambda-type (exec [_ (&type/solve =return =body-type)]
+ (&type/clean =lambda-type))
+ :let [=lambda-form (match =body
+ [::&/Expression [::&/lambda ?sub-scope ?sub-captured ?sub-args ?sub-body] _]
+ [::&/lambda =scope =captured (cons ?arg ?sub-args) (&&lambda/raise-expr ?arg ?sub-body)]
- _
- [::&/Expression [::lambda =scope =captured (list ?arg) =body] =body-type])]]
- (return (list [::&/Expression =lambda =function]))))
+ _
+ [::&/lambda =scope =captured (list ?arg) =body])]]
+ (return (list [::&/Expression =lambda-form =lambda-type]))))
(defn analyse-def [analyse ?name ?value]
;; (prn 'analyse-def ?name ?value)
- (exec [def?? (&&env/defined? ?name)]
- (if def??
- (fail (str "Can't redefine " ?name))
- (exec [ann?? (&&env/annotated? ?name)
- $module &util/get-module-name
- =value (&/analyse-1 analyse ?value)
- =value (match =value
- [::&/Expression =value-form =value-type]
- (return (match =value-form
- [::lambda ?old-scope ?env ?args ?body]
- [::&/Expression [::lambda (list ?name $module) ?env ?args ?body] =value-type]
-
- _
- =value))
+ (exec [module-name &util/get-module-name]
+ (if-m (&&env/defined? module-name ?name)
+ (fail (str "Can't redefine " ?name))
+ (exec [=value (&/analyse-1 analyse ?value)
+ =value (match =value
+ [::&/Expression =value-form =value-type]
+ (return (match =value-form
+ [::&/lambda ?old-scope ?env ?args ?body]
+ [::&/Expression [::&/lambda (list module-name ?name) ?env ?args ?body] =value-type]
+
+ _
+ =value))
- _
- (fail ""))
- =value-type (&/expr-type =value)
- _ (if ann??
- (return nil)
- (&&env/annotate ?name ::public false =value-type))
- _ (&&env/define ?name)]
- (return (list [::&/Statement [::def ?name =value]]))))))
+ _
+ (fail ""))
+ =value-type (&/expr-type =value)
+ _ (if-m (&&env/annotated? module-name ?name)
+ (return nil)
+ (&&env/annotate module-name ?name :public =value-type))
+ _ (&&env/define module-name ?name)]
+ (return (list [::&/Statement [::&/def ?name =value]]))))))
(defn analyse-declare-macro [?ident]
- (exec [_ (&&env/annotate ?ident ::public true [::&type/Any])]
+ (exec [_ (&&env/annotate ?ident :public [::&type/Any])]
(return (list))))
(defn analyse-require [analyse ?path]
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index bd1df6157..dcfbfed56 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -5,7 +5,7 @@
[template :refer [do-template]])
[clojure.core.match :refer [match]]
(lux [util :as &util :refer [exec return* return fail fail*
- repeat-m exhaust-m try-m try-all-m map-m reduce-m
+ repeat-m exhaust-m try-m try-all-m map-m mapcat-m reduce-m
apply-m
normalize-ident]]
[type :as &type]
@@ -27,6 +27,7 @@
;; [Utils/Compilers]
(defn ^:private compile-expression [syntax]
+ (prn 'compile-expression syntax)
(match syntax
[::&a/Expression ?form ?type]
(match ?form
@@ -164,49 +165,49 @@
(&&host/compile-jvm-aastore compile-expression ?type ?array ?idx ?elem)
[::&a/jvm-aaload ?array ?idx]
- (&&host/compile-jvm-aaload compile-expression ?type ?array ?idx)
+ (&&host/compile-jvm-aaload compile-expression ?type ?array ?idx))
- _
- (fail "[Compiler Error] Can't compile expressions as top-level forms.")
- )))
+ _
+ (fail "[Compiler Error] Can't compile statements as expressions.")))
(defn ^:private compile-statement [syntax]
+ (prn 'compile-statement syntax)
(match syntax
- [::&a/Expression ?form ?type]
+ [::&a/Statement ?form]
(match ?form
- [::&a/def ?form ?body]
- (&&lux/compile-def compile-expression ?type ?form ?body)
+ [::&a/def ?name ?body]
+ (&&lux/compile-def compile-expression ?name ?body)
- [::&a/jvm-interface [?package ?name] ?members]
- (&&host/compile-jvm-interface compile-expression ?type ?package ?name ?members)
+ [::&a/jvm-interface ?package ?name ?methods]
+ (&&host/compile-jvm-interface compile-expression ?package ?name ?methods)
- [::&a/jvm-class [?package ?name] ?super-class ?members]
- (&&host/compile-jvm-class compile-expression ?type ?package ?name ?super-class ?members)
+ [::&a/jvm-class ?package ?name ?super-class ?fields ?methods]
+ (&&host/compile-jvm-class compile-expression ?package ?name ?super-class ?fields ?methods))
- _
- (fail "[Compiler Error] Can't compile expressions as top-level forms.")
- )))
+ _
+ (fail "[Compiler Error] Can't compile expressions as top-level forms.")))
-(let [compiler-step (exec [analysis+ &analyser/analyse]
- (map-m compile-statement analysis+))]
+(let [compiler-step (exec [analysis+ &analyser/analyse
+ :let [_ (prn 'analysis+ analysis+)]]
+ (mapcat-m compile-statement analysis+))]
(defn ^:private compile-module [name]
- (exec [loader &util/loader]
- (fn [state]
- (if (-> state ::&util/modules (contains? name))
- (fail "[Compiler Error] Can't redefine a module!")
- (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
- (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
- (&host/->class name) nil "java/lang/Object" nil))]
- (match (&util/run-state (exhaust-m compiler-step) (assoc state
- ::&util/source (slurp (str "source/" name ".lux"))
- ::&util/current-module name
- ::&util/writer =class))
- [::&util/ok [?state _]]
- (do (.visitEnd =class)
- (&util/run-state (&&/save-class! name (.toByteArray =class)) ?state))
-
- [::&util/failure ?message]
- (fail* ?message))))))))
+ (fn [state]
+ (if (-> state ::&util/modules (contains? name))
+ (fail "[Compiler Error] Can't redefine a module!")
+ (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
+ (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
+ (&host/->class name) nil "java/lang/Object" nil))]
+ (match (&util/run-state (exhaust-m compiler-step) (assoc state
+ ::&util/source (slurp (str "source/" name ".lux"))
+ ::&util/global-env (&util/env name)
+ ::&util/writer =class))
+ [::&util/ok [?state ?vals]]
+ (do (.visitEnd =class)
+ (prn 'compile-module/?vals ?vals)
+ (&util/run-state (&&/save-class! name (.toByteArray =class)) ?state))
+
+ [::&util/failure ?message]
+ (fail* ?message)))))))
;; [Resources]
(defn compile-all [modules]
diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj
index a6a181a6d..2139bb24a 100644
--- a/src/lux/compiler/case.clj
+++ b/src/lux/compiler/case.clj
@@ -535,25 +535,30 @@
))
(defn ^:private decision-tree [branches]
+ (prn 'decision-tree branches)
(exec [group (reduce-m group-branch [::?PM (list)] branches)
:let [[mappings group*] (map-bodies group)
paths (valid-paths group*)]]
- (sequence-pm paths group*)))
+ (sequence-pm group*)))
;; [Resources]
(let [ex-class (&host/->class "java.lang.IllegalStateException")]
(defn compile-case [compile *type* ?variant ?base-register ?num-registers ?branches]
(exec [*writer* &util/get-writer
+ :let [_ (prn "Has writer")]
:let [$start (new Label)
$end (new Label)
_ (dotimes [offset ?num-registers]
(let [idx (+ ?base-register offset)]
(.visitLocalVariable *writer* (str &&/local-prefix idx) (&host/->java-sig [::&type/Any]) nil $start $end idx)))]
+ :let [_ (prn "PRE Compiled ?variant")]
_ (compile ?variant)
+ :let [_ (prn "POST Compiled ?variant")]
:let [_ (doto *writer*
(.visitInsn Opcodes/DUP)
(.visitLabel $start))]
- :let [[mapping tree] (decision-tree ?branches)]
+ [mapping tree] (decision-tree ?branches)
+ :let [_ (assert false "compile-case")]
;; :let [[mappings pm-struct*] (map-bodies pm-struct)
;; entries (for [[?branch ?body] mappings
diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj
index 0a11decb4..db62312ec 100644
--- a/src/lux/compiler/host.clj
+++ b/src/lux/compiler/host.clj
@@ -57,6 +57,48 @@
;; nil)))
;; [Resources]
+(do-template [<name> <opcode> <wrapper-class> <value-method> <value-method-sig> <wrapper-method> <wrapper-method-sig>]
+ (defn <name> [compile *type* ?x ?y]
+ (exec [:let [+wrapper-class+ (&host/->class <wrapper-class>)]
+ *writer* &util/get-writer
+ _ (compile ?x)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+)
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ <value-method> <value-method-sig>))]
+ _ (compile ?y)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+)
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ <value-method> <value-method-sig>))
+ _ (doto *writer*
+ (.visitInsn <opcode>)
+ (.visitMethodInsn Opcodes/INVOKESTATIC +wrapper-class+ <wrapper-method> (str <wrapper-method-sig> (&host/->type-signature <wrapper-class>))))]]
+ (return nil)))
+
+ compile-jvm-iadd Opcodes/IADD "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
+ compile-jvm-isub Opcodes/ISUB "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
+ compile-jvm-imul Opcodes/IMUL "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
+ compile-jvm-idiv Opcodes/IDIV "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
+ compile-jvm-irem Opcodes/IREM "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
+
+ compile-jvm-ladd Opcodes/LADD "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
+ compile-jvm-lsub Opcodes/LSUB "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
+ compile-jvm-lmul Opcodes/LMUL "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
+ compile-jvm-ldiv Opcodes/LDIV "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
+ compile-jvm-lrem Opcodes/LREM "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
+
+ compile-jvm-fadd Opcodes/FADD "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
+ compile-jvm-fsub Opcodes/FSUB "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
+ compile-jvm-fmul Opcodes/FMUL "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
+ compile-jvm-fdiv Opcodes/FDIV "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
+ compile-jvm-frem Opcodes/FREM "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
+
+ compile-jvm-dadd Opcodes/DADD "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
+ compile-jvm-dsub Opcodes/DSUB "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
+ compile-jvm-dmul Opcodes/DMUL "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
+ compile-jvm-ddiv Opcodes/DDIV "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
+ compile-jvm-drem Opcodes/DREM "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
+ )
+
(defn compile-jvm-invokestatic [compile *type* ?class ?method ?classes ?args]
(exec [*writer* &util/get-writer
:let [method-sig (str "(" (reduce str "" (map &host/->type-signature ?classes)) ")" (&host/->java-sig *type*))]
@@ -138,7 +180,7 @@
:let [_ (.visitFieldInsn *writer* Opcodes/GETFIELD (&host/->class ?class) ?field (&host/->java-sig *type*))]]
(return nil)))
-(defn compile-jvm-class [compile *type* ?package ?name ?super-class ?fields ?methods]
+(defn compile-jvm-class [compile ?package ?name ?super-class ?fields ?methods]
(let [parent-dir (&host/->package ?package)
full-name (str parent-dir "/" ?name)
super-class* (&host/->class ?super-class)
@@ -159,7 +201,7 @@
(.mkdirs (java.io.File. (str "output/" parent-dir))))]
(&&/save-class! full-name (.toByteArray =class))))
-(defn compile-jvm-interface [compile *type* ?package ?name ?fields ?methods]
+(defn compile-jvm-interface [compile ?package ?name ?methods]
(let [parent-dir (&host/->package ?package)
full-name (str parent-dir "/" ?name)
=interface (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
@@ -173,48 +215,6 @@
(.mkdirs (java.io.File. (str "output/" parent-dir))))]
(&&/save-class! full-name (.toByteArray =interface))))
-(do-template [<name> <opcode> <wrapper-class> <value-method> <value-method-sig> <wrapper-method> <wrapper-method-sig>]
- (defn <name> [compile *type* ?x ?y]
- (exec [:let [+wrapper-class+ (&host/->class <wrapper-class>)]
- *writer* &util/get-writer
- _ (compile ?x)
- :let [_ (doto *writer*
- (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+)
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ <value-method> <value-method-sig>))]
- _ (compile ?y)
- :let [_ (doto *writer*
- (.visitTypeInsn Opcodes/CHECKCAST +wrapper-class+)
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL +wrapper-class+ <value-method> <value-method-sig>))
- _ (doto *writer*
- (.visitInsn <opcode>)
- (.visitMethodInsn Opcodes/INVOKESTATIC +wrapper-class+ <wrapper-method> (str <wrapper-method-sig> (&host/->type-signature <wrapper-class>))))]]
- (return nil)))
-
- compile-jvm-iadd Opcodes/IADD "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
- compile-jvm-isub Opcodes/ISUB "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
- compile-jvm-imul Opcodes/IMUL "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
- compile-jvm-idiv Opcodes/IDIV "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
- compile-jvm-irem Opcodes/IREM "java.lang.Integer" "intValue" "()I" "valueOf" "(I)"
-
- compile-jvm-ladd Opcodes/LADD "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
- compile-jvm-lsub Opcodes/LSUB "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
- compile-jvm-lmul Opcodes/LMUL "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
- compile-jvm-ldiv Opcodes/LDIV "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
- compile-jvm-lrem Opcodes/LREM "java.lang.Long" "longValue" "()J" "valueOf" "(J)"
-
- compile-jvm-fadd Opcodes/FADD "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
- compile-jvm-fsub Opcodes/FSUB "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
- compile-jvm-fmul Opcodes/FMUL "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
- compile-jvm-fdiv Opcodes/FDIV "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
- compile-jvm-frem Opcodes/FREM "java.lang.Float" "floatValue" "()F" "valueOf" "(F)"
-
- compile-jvm-dadd Opcodes/DADD "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
- compile-jvm-dsub Opcodes/DSUB "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
- compile-jvm-dmul Opcodes/DMUL "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
- compile-jvm-ddiv Opcodes/DDIV "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
- compile-jvm-drem Opcodes/DREM "java.lang.Double" "doubleValue" "()D" "valueOf" "(D)"
- )
-
(defn compile-exec [compile *type* ?exprs]
(exec [*writer* &util/get-writer
_ (map-m (fn [expr]
diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj
index ebf376e39..13925a50c 100644
--- a/src/lux/compiler/lux.clj
+++ b/src/lux/compiler/lux.clj
@@ -22,7 +22,7 @@
MethodVisitor)))
;; [Utils]
-(defn ^:private compile-field [compile *type* ?name body]
+(defn ^:private compile-field [compile ?name body]
(exec [*writer* &util/get-writer
module-name &util/get-module-name
:let [outer-class (&host/->class module-name)
@@ -172,18 +172,19 @@
)]]
(return nil)))
-(defn compile-def [compile *type* name value]
- (match value
- [::&a/Expression ?form _]
- (match ?form
- [::&a/lambda ?scope ?captured ?args ?body]
- (&&lambda/compile-lambda compile *type* ?scope ?captured ?args ?body true false)
+(defn compile-def [compile name value]
+ (exec [value-type (&a/expr-type value)]
+ (match value
+ [::&a/Expression ?form _]
+ (match ?form
+ [::&a/lambda ?scope ?captured ?args ?body]
+ (&&lambda/compile-lambda compile value-type ?scope ?captured ?args ?body true false)
+ _
+ (compile-field compile name value))
+
_
- (compile-field compile *type* name value))
-
- _
- (fail "Can only define expressions.")))
+ (fail "Can only define expressions."))))
(defn compile-self-call [compile ?assumed-args]
(exec [*writer* &util/get-writer
diff --git a/src/lux/host.clj b/src/lux/host.clj
index b21ed03dc..04d0cd9dd 100644
--- a/src/lux/host.clj
+++ b/src/lux/host.clj
@@ -82,8 +82,11 @@
(defn ->java-sig [type]
(match type
- ::&type/Any
+ [::&type/Any]
(->type-signature "java.lang.Object")
+
+ [::&type/Nothing]
+ "V"
[::&type/Data ?name]
(->type-signature ?name)
diff --git a/src/lux/lexer.clj b/src/lux/lexer.clj
index 74291ec71..2e0abea82 100644
--- a/src/lux/lexer.clj
+++ b/src/lux/lexer.clj
@@ -6,20 +6,20 @@
;; [Utils]
(defn ^:private lex-regex [regex]
(fn [state]
- (if-let [[match] (re-find regex (::source state))]
- (return* (update-in state [::source] #(.substring % (.length match))) match)
+ (if-let [[match] (re-find regex (::&util/source state))]
+ (return* (update-in state [::&util/source] #(.substring % (.length match))) match)
(fail* (str "[Lexer Error] Pattern failed: " regex)))))
(defn ^:private lex-regex2 [regex]
(fn [state]
- (if-let [[match tok1 tok2] (re-find regex (::source state))]
- (return* (update-in state [::source] #(.substring % (.length match))) [tok1 tok2])
+ (if-let [[match tok1 tok2] (re-find regex (::&util/source state))]
+ (return* (update-in state [::&util/source] #(.substring % (.length match))) [tok1 tok2])
(fail* (str "[Lexer Error] Pattern failed: " regex)))))
(defn ^:private lex-prefix [prefix]
(fn [state]
- (if (.startsWith (::source state) prefix)
- (return* (update-in state [::source] #(.substring % (.length prefix))) prefix)
+ (if (.startsWith (::&util/source state) prefix)
+ (return* (update-in state [::&util/source] #(.substring % (.length prefix))) prefix)
(fail* (str "[Lexer Error] Text failed: " prefix)))))
(defn ^:private escape-char [escaped]
@@ -118,7 +118,7 @@
lex-open-brace
lex-close-brace]))
-;; [Interface]
+;; [Exports]
(def lex
(try-all-m [lex-white-space
lex-comment
diff --git a/src/lux/parser.clj b/src/lux/parser.clj
index 3430e3675..a74251d6d 100644
--- a/src/lux/parser.clj
+++ b/src/lux/parser.clj
@@ -5,16 +5,16 @@
[lexer :as &lexer])))
;; [Utils]
-(do-template [<name> <close-token> <description> <ast>]
+(do-template [<name> <close-token> <description> <tag>]
(defn <name> [parse]
(exec [elems (repeat-m parse)
token &lexer/lex]
(if (= <close-token> token)
- (return (list [<ast> (apply concat elems)]))
+ (return (list [<tag> (apply concat elems)]))
(fail (str "[Parser Error] Unbalanced " <description> ".")))))
- ^:private parse-form [::&lexer/close-paren] "parantheses" ::form
- ^:private parse-tuple [::&lexer/close-bracket] "brackets" ::tuple
+ ^:private parse-form [::&lexer/close-paren] "parantheses" ::Form
+ ^:private parse-tuple [::&lexer/close-bracket] "brackets" ::Tuple
)
(defn ^:private parse-record [parse]
@@ -28,11 +28,13 @@
(fail (str "[Parser Error] Records must have an even number of elements."))
:else
- (return (list [::record elems])))))
+ (return (list [::Record elems])))))
;; [Interface]
(def parse
- (exec [token &lexer/lex]
+ (exec [token &lexer/lex
+ ;; :let [_ (prn 'parse/token token)]
+ ]
(match token
[::&lexer/white-space _]
(return (list))
diff --git a/src/lux/type.clj b/src/lux/type.clj
index bb22d343f..f558f1fc8 100644
--- a/src/lux/type.clj
+++ b/src/lux/type.clj
@@ -11,29 +11,30 @@
(defn ^:private deref [id]
(fn [state]
- (if-let [top+bottom (get-in state [::&util/types ::mappings id])]
+ (if-let [top+bottom (get-in state [::&util/types :mappings id])]
[::&util/ok [state top+bottom]]
[::&util/failure (str "Unknown type-var: " id)])))
(defn ^:private update [id top bottom]
(fn [state]
- (if-let [top+bottom (get-in state [::&util/types ::mappings id])]
- [::&util/ok [(assoc-in state [::&util/types ::mappings id] [top bottom]) nil]]
+ (if-let [top+bottom (get-in state [::&util/types :mappings id])]
+ [::&util/ok [(assoc-in state [::&util/types :mappings id] [top bottom]) nil]]
[::&util/failure (str "Unknown type-var: " id)])))
;; [Interface]
(def fresh-var
(fn [state]
- (let [id (::counter state)]
- [::&util/ok [(-> state
- (update-in [::counter] inc)
- (assoc-in [::mappings id] [::any ::nothing]))
- [::var id]]])))
+ (let [id (-> state ::&util/types :counter)]
+ [::&util/ok [(update-in state [::&util/types]
+ #(-> %
+ (update-in [:counter] inc)
+ (assoc-in [:mappings id] [[::Any] [::Nothing]])))
+ [::Var id]]])))
(def fresh-function
(exec [=arg fresh-var
=return fresh-var]
- (return [::function =arg =return])))
+ (return [::Lambda =arg =return])))
;; (defn solve [expected actual]
;; ;; (prn 'solve expected actual)
@@ -98,20 +99,17 @@
(defn clean [type]
(match type
- [::var ?id]
+ [::Var ?id]
(exec [[=top =bottom] (deref ?id)]
(clean =top))
- [::function ?args ?return]
- (exec [=args (map-m clean ?args)
+ [::Lambda ?arg ?return]
+ (exec [=arg (clean ?arg)
=return (clean ?return)]
- (return [::function =args =return]))
+ (return [::Lambda =arg =return]))
- ;; ::any
- ;; (return [::object "java.lang.Object" []])
-
- ;; _
- ;; (return type)
+ _
+ (return type)
))
;; Java Reflection
@@ -159,6 +157,13 @@
[[::Lambda n!input n!output] [::Lambda g!input g!output]]
(exec [_ (solve g!input n!input)]
(solve n!output g!output))
+
+ [[::Var n!id] _]
+ (exec [[n!top n!bottom] (deref n!id)
+ _ (solve n!top given)
+ _ (solve given n!bottom)
+ _ (update n!id n!top given)]
+ success)
))
(let [&& #(and %1 %2)]
diff --git a/src/lux/util.clj b/src/lux/util.clj
index 3139cd20b..c27e05ab8 100644
--- a/src/lux/util.clj
+++ b/src/lux/util.clj
@@ -66,44 +66,45 @@
(do ;; (println "Failed at last:" ?message)
(return* state '())))))
-(defn exhaust-m [monad]
+(def source-consumed?
(fn [state]
- (let [result (monad state)]
- (match result
- [::ok [?state ?head]]
- (if (empty? (:forms ?state))
- (return* ?state (list ?head))
- (let [result* ((exhaust-m monad) ?state)]
- (match result*
- [::ok [?state* ?tail]]
- (return* ?state* (cons ?head ?tail))
-
- _
- result*)))
-
- _
- result))))
+ [::ok [state (empty? (::source state))]]))
+
+(defn exhaust-m [monad]
+ (exec [output-h monad
+ ? source-consumed?
+ output-t (if ?
+ (return (list))
+ (exhaust-m monad))]
+ (return (cons output-h output-t))))
(defn try-all-m [monads]
- (fn [state]
- (if (empty? monads)
- (fail* "No alternative worked!")
+ (if (empty? monads)
+ (fail "Can't try no alternatives!")
+ (fn [state]
(let [output ((first monads) state)]
(match output
[::ok _]
output
- :else
+
+ _
(if-let [monads* (seq (rest monads))]
((try-all-m monads*) state)
output)
)))))
+(defn if-m [text-m then-m else-m]
+ (exec [? text-m]
+ (if ?
+ then-m
+ else-m)))
+
(do-template [<name> <joiner>]
(defn <name> [f inputs]
(if (empty? inputs)
(return '())
(exec [output (f (first inputs))
- outputs (map-m f (rest inputs))]
+ outputs (<name> f (rest inputs))]
(return (<joiner> output outputs)))))
map-m cons
@@ -184,36 +185,54 @@
(defn normalize-ident [ident]
(reduce str "" (map normalize-char ident)))
-(defn class-loader! []
- (-> (java.io.File. "./output/") .toURL vector into-array java.net.URLClassLoader.))
-
(def loader
(fn [state]
(return* state (::loader state))))
-(def +init-env+
+(def +init-bindings+
{:counter 0
:mappings {}})
-(defn scope [name]
+(defn env [name]
{:name name
- :inner-lambdas 0
- :locals +init-env+
- :closure +init-env+})
+ :inner-closures 0
+ :locals +init-bindings+
+ :closure +init-bindings+})
(defn init-state []
{::source nil
- ::current-module nil
::modules {}
- ::global-env {}
+ ::global-env nil
::local-envs (list)
- ::types +init-env+
+ ::types +init-bindings+
::writer nil
- ::loader (class-loader!)})
+ ::loader (-> (java.io.File. "./output/") .toURL vector into-array java.net.URLClassLoader.)})
+
+(def get-writer
+ (fn [state]
+ (if-let [datum (::writer state)]
+ [::ok [state datum]]
+ [::failure "Writer hasn't been set."])))
+
+(def get-top-local-env
+ (fn [state]
+ (if-let [datum (first (::local-envs state))]
+ [::ok [state datum]]
+ [::failure "Module hasn't been set."])))
+
+(def get-current-module-env
+ (fn [state]
+ (if-let [datum (::global-env state)]
+ [::ok [state datum]]
+ [::failure "Module hasn't been set."])))
+
+(def get-module-name
+ (exec [module get-current-module-env]
+ (return (:name module))))
(defn ^:private with-scope [name body]
(fn [state]
- (let [output (body (update-in state [::local-envs] conj (scope name)))]
+ (let [output (body (update-in state [::local-envs] conj (env name)))]
(match output
[::ok [state* datum]]
[::ok [(update-in state* [::local-envs] rest) datum]]
@@ -222,27 +241,23 @@
output))))
(defn with-closure [body]
- (fn [state]
- (let [body* (with-scope (-> state ::local-envs first :inner-closures str)
- body)]
- (body* (update-in state [::local-envs]
- #(cons (update-in (first %) [:inner-closures] inc)
- (rest %)))))))
-
-(do-template [<name> <tag>]
- (def <name>
+ (exec [[local? closure-name] (try-all-m (list (exec [top get-top-local-env]
+ (return [true (-> top :inner-closures str)]))
+ (exec [global get-current-module-env]
+ (return [false (-> global :inner-closures str)]))))]
(fn [state]
- (if-let [datum (<tag> state)]
- [::ok [state datum]]
- [::failure (str "Data does not exist: " <tag>)])))
-
- get-module-name ::current-module
- get-writer ::writer
- )
+ (let [body* (with-scope closure-name
+ body)]
+ (body* (if local?
+ (update-in state [::local-envs]
+ #(cons (update-in (first %) [:inner-closures] inc)
+ (rest %)))
+ (update-in state [::global-env :inner-closures] inc)))))))
(def get-scope-name
- (fn [state]
- [::ok [state (->> state ::local-envs (map :name) reverse (cons (::current-module state)))]]))
+ (exec [module-name get-module-name]
+ (fn [state]
+ [::ok [state (->> state ::local-envs (map :name) reverse (cons module-name))]])))
(defn with-writer [writer body]
(fn [state]