aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEduardo Julian2015-03-10 01:39:35 -0400
committerEduardo Julian2015-03-10 01:39:35 -0400
commite2fcc7ebbb1f423a3137aa5525b9409f870fe191 (patch)
treea9765d5d44be59bae48b1a411444f1112b1a00a4 /src
parenta386d0c4688b8749db3e4d612658774a24bc61a2 (diff)
- Modified the compiler so parser syntax tokens are stored in the same format as lux data-structures, to ease communication between the compiler & macros.
Diffstat (limited to 'src')
-rw-r--r--src/lux.clj1
-rw-r--r--src/lux/analyser.clj197
-rw-r--r--src/lux/analyser/case.clj17
-rw-r--r--src/lux/analyser/host.clj39
-rw-r--r--src/lux/analyser/lux.clj8
-rw-r--r--src/lux/base.clj43
-rw-r--r--src/lux/compiler/case.clj28
-rw-r--r--src/lux/host.clj11
-rw-r--r--src/lux/macro.clj76
-rw-r--r--src/lux/parser.clj26
10 files changed, 242 insertions, 204 deletions
diff --git a/src/lux.clj b/src/lux.clj
index 888618de6..5b56f9244 100644
--- a/src/lux.clj
+++ b/src/lux.clj
@@ -6,7 +6,6 @@
;; TODO: Finish type system.
;; TODO: Re-implement compiler in language.
;; TODO: Adding metadata to global vars.
- ;; TODO: Add records.
;; TODO: throw, try, catch, finally
;; TODO: Allow setting fields.
;; TODO: monitor enter & monitor exit.
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index a26ee44b2..6ea706814 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -1,6 +1,7 @@
(ns lux.analyser
(:require (clojure [template :refer [do-template]])
- [clojure.core.match :refer [match]]
+ [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
(lux [base :as & :refer [exec return fail
try-all-m map-m mapcat-m reduce-m
assert!]]
@@ -14,212 +15,240 @@
;; [Utils]
(defn ^:private analyse-basic-ast [analyse-ast token]
- ;; (prn 'analyse-basic-ast token)
- (match token
+ ;; (prn 'analyse-basic-ast token (&/show-ast token))
+ (matchv ::M/objects [token]
;; Standard special forms
- [::&parser/Bool ?value]
+ [["Bool" ?value]]
(return (list [::&&/Expression [::&&/bool ?value] [::&type/Data "java.lang.Boolean"]]))
- [::&parser/Int ?value]
+ [["Int" ?value]]
(return (list [::&&/Expression [::&&/int ?value] [::&type/Data "java.lang.Long"]]))
- [::&parser/Real ?value]
+ [["Real" ?value]]
(return (list [::&&/Expression [::&&/real ?value] [::&type/Data "java.lang.Double"]]))
- [::&parser/Char ?value]
+ [["Char" ?value]]
(return (list [::&&/Expression [::&&/char ?value] [::&type/Data "java.lang.Character"]]))
- [::&parser/Text ?value]
+ [["Text" ?value]]
(return (list [::&&/Expression [::&&/text ?value] [::&type/Data "java.lang.String"]]))
- [::&parser/Tuple ?elems]
- (&&lux/analyse-tuple analyse-ast ?elems)
+ [["Tuple" ?elems]]
+ (&&lux/analyse-tuple analyse-ast (&/->seq ?elems))
- [::&parser/Record ?elems]
- (&&lux/analyse-record analyse-ast ?elems)
+ [["Record" ?elems]]
+ (&&lux/analyse-record analyse-ast (&/->seq ?elems))
- [::&parser/Tag ?tag]
+ [["Tag" ?tag]]
(let [tuple-type [::&type/Tuple (list)]]
(return (list [::&&/Expression [::&&/variant ?tag [::&&/Expression [::&&/tuple (list)] tuple-type]]
[::&type/Variant (list [?tag tuple-type])]])))
- [::&parser/Ident ?ident]
+ [["Ident" ?ident]]
(&&lux/analyse-ident analyse-ast ?ident)
- [::&parser/Form ([[::&parser/Ident "case'"] ?variant & ?branches] :seq)]
- (&&lux/analyse-case analyse-ast ?variant ?branches)
+ [["Form" ["Cons" [["Ident" "case'"]
+ ["Cons" [?variant ?branches]]]]]]
+ (&&lux/analyse-case analyse-ast ?variant (&/->seq ?branches))
- [::&parser/Form ([[::&parser/Ident "lambda'"] [::&parser/Ident ?self] [::&parser/Ident ?arg] ?body] :seq)]
+ [["Form" ["Cons" [["Ident" "lambda'"]
+ ["Cons" [["Ident" ?self]
+ ["Cons" [["Ident" ?arg]
+ ["Cons" [?body
+ ["Nil" _]]]]]]]]]]]
(&&lux/analyse-lambda analyse-ast ?self ?arg ?body)
- [::&parser/Form ([[::&parser/Ident "get@'"] [::&parser/Tag ?slot] ?record] :seq)]
+ [["Form" ["Cons" [["Ident" "get@'"] ["Cons" [["Tag" ?slot] ["Cons" [?record ["Nil" _]]]]]]]]]
(&&lux/analyse-get analyse-ast ?slot ?record)
- [::&parser/Form ([[::&parser/Ident "set@'"] [::&parser/Tag ?slot] ?value ?record] :seq)]
+ [["Form" ["Cons" [["Ident" "set@'"] ["Cons" [["Tag" ?slot] ["Cons" [?value ["Cons" [?record ["Nil" _]]]]]]]]]]]
(&&lux/analyse-set analyse-ast ?slot ?value ?record)
- [::&parser/Form ([[::&parser/Ident "def'"] [::&parser/Ident ?name] ?value] :seq)]
+ [["Form" ["Cons" [["Ident" "def'"] ["Cons" [["Ident" ?name] ["Cons" [?value ["Nil" _]]]]]]]]]
(&&lux/analyse-def analyse-ast ?name ?value)
- [::&parser/Form ([[::&parser/Ident "declare-macro"] [::&parser/Ident ?ident]] :seq)]
+ [["Form" ["Cons" [["Ident" "declare-macro"] ["Cons" [["Ident" ?ident] ["Nil" _]]]]]]]
(&&lux/analyse-declare-macro ?ident)
- [::&parser/Form ([[::&parser/Ident "require"] [::&parser/Text ?path]] :seq)]
- (&&lux/analyse-require analyse-ast ?path)
+ [["Form" ["Cons" [["Ident" "import'"] ["Cons" [["Text" ?path] ["Nil" _]]]]]]]
+ (&&lux/analyse-import analyse-ast ?path)
;; Host special forms
- [::&parser/Form ([[::&parser/Ident "exec"] & ?exprs] :seq)]
- (&&host/analyse-exec analyse-ast ?exprs)
+ [["Form" ["Cons" [["Ident" "exec"] ?exprs]]]]
+ (&&host/analyse-exec analyse-ast (&/->seq ?exprs))
;; Integer arithmetic
- [::&parser/Form ([[::&parser/Ident "jvm-iadd"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-iadd"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-iadd analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-isub"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-isub"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-isub analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-imul"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-imul"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-imul analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-idiv"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-idiv"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-idiv analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-irem"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-irem"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-irem analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-ieq"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-ieq"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-ieq analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-ilt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-ilt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-ilt analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-igt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-igt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-igt analyse-ast ?x ?y)
;; Long arithmetic
- [::&parser/Form ([[::&parser/Ident "jvm-ladd"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-ladd"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-ladd analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-lsub"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-lsub"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-lsub analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-lmul"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-lmul"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-lmul analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-ldiv"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-ldiv"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-ldiv analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-lrem"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-lrem"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-lrem analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-leq"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-leq"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-leq analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-llt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-llt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-llt analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-lgt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-lgt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-lgt analyse-ast ?x ?y)
;; Float arithmetic
- [::&parser/Form ([[::&parser/Ident "jvm-fadd"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-fadd"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-fadd analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-fsub"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-fsub"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-fsub analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-fmul"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-fmul"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-fmul analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-fdiv"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-fdiv"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-fdiv analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-frem"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-frem"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-frem analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-feq"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-feq"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-feq analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-flt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-flt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-flt analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-fgt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-fgt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-fgt analyse-ast ?x ?y)
;; Double arithmetic
- [::&parser/Form ([[::&parser/Ident "jvm-dadd"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-dadd"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-dadd analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-dsub"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-dsub"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-dsub analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-dmul"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-dmul"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-dmul analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-ddiv"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-ddiv"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-ddiv analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-drem"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-drem"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-drem analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-deq"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-deq"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-deq analyse-ast ?x ?y)
-
- [::&parser/Form ([[::&parser/Ident "jvm-dlt"] ?x ?y] :seq)]
+
+ [["Form" ["Cons" [["Ident" "jvm-dlt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-dlt analyse-ast ?x ?y)
- [::&parser/Form ([[::&parser/Ident "jvm-dgt"] ?x ?y] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-dgt"] ["Cons" [?y ["Cons" [?x ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-dgt analyse-ast ?x ?y)
- ;; Fields & methods
- [::&parser/Form ([[::&parser/Ident "jvm-getstatic"] [::&parser/Ident ?class] [::&parser/Text ?field]] :seq)]
+ ;; Objects
+ [["Form" ["Cons" [["Ident" "jvm-new"]
+ ["Cons" [["Ident" ?class]
+ ["Cons" [["Tuple" ?classes]
+ ["Cons" [["Tuple" ?args]
+ ["Nil" _]]]]]]]]]]]
+ (&&host/analyse-jvm-new analyse-ast ?class ?classes ?args)
+
+
+ [["Form" ["Cons" [["Ident" "jvm-getstatic"]
+ ["Cons" [["Ident" ?class]
+ ["Cons" [["Text" ?field]
+ ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-getstatic analyse-ast ?class ?field)
- [::&parser/Form ([[::&parser/Ident "jvm-getfield"] [::&parser/Ident ?class] [::&parser/Text ?field] ?object] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-getfield"]
+ ["Cons" [["Ident" ?class]
+ ["Cons" [["Text" ?field]
+ ["Cons" [?object
+ ["Nil" _]]]]]]]]]]]
(&&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)]
- (&&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)]
- (&&host/analyse-jvm-invokevirtual analyse-ast ?class ?method ?classes ?object ?args)
-
+ [["Form" ["Cons" [["Ident" "jvm-invokestatic"]
+ ["Cons" [["Ident" ?class]
+ ["Cons" [["Text" ?method]
+ ["Cons" [["Tuple" ?classes]
+ ["Cons" [["Tuple" ?args]
+ ["Nil" _]]]]]]]]]]]]]
+ (&&host/analyse-jvm-invokestatic analyse-ast ?class ?method (&/->seq ?classes) (&/->seq ?args))
+
+ [["Form" ["Cons" [["Ident" "jvm-invokevirtual"]
+ ["Cons" [["Ident" ?class]
+ ["Cons" [["Text" ?method]
+ ["Cons" [["Tuple" ?classes]
+ ["Cons" [?object
+ ["Cons" [["Tuple" ?args]
+ ["Nil" _]]]]]]]]]]]]]]]
+ (&&host/analyse-jvm-invokevirtual analyse-ast ?class ?method (&/->seq ?classes) ?object (&/->seq ?args))
+
;; Arrays
- [::&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)]
+ [["Form" ["Cons" [["Ident" "jvm-new-array"] ["Cons" [["Ident" ?class] ["Cons" [["Int" ?length] ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-new-array analyse-ast ?class ?length)
- [::&parser/Form ([[::&parser/Ident "jvm-aastore"] ?array [::&parser/Int ?idx] ?elem] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-aastore"] ["Cons" [?array ["Cons" [["Int" ?idx] ["Cons" [?elem ["Nil" _]]]]]]]]]]]
(&&host/analyse-jvm-aastore analyse-ast ?array ?idx ?elem)
- [::&parser/Form ([[::&parser/Ident "jvm-aaload"] ?array [::&parser/Int ?idx]] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-aaload"] ["Cons" [?array ["Cons" [["Int" ?idx] ["Nil" _]]]]]]]]]
(&&host/analyse-jvm-aaload analyse-ast ?array ?idx)
;; Classes & interfaces
- [::&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)
+ [["Form" ["Cons" [["Ident" "jvm-class"] ["Cons" [["Ident" ?name] ["Cons" [["Ident" ?super-class] ["Cons" [["Tuple" ?fields] ["Nil" _]]]]]]]]]]]
+ (&&host/analyse-jvm-class analyse-ast ?name ?super-class (&/->seq ?fields))
- [::&parser/Form ([[::&parser/Ident "jvm-interface"] [::&parser/Ident ?name] & ?members] :seq)]
+ [["Form" ["Cons" [["Ident" "jvm-interface"] ["Cons" [["Ident" ?name] ?members]]]]]]
(&&host/analyse-jvm-interface analyse-ast ?name ?members)
- _
- (fail (str "[Analyser Error] Unmatched token: " (pr-str token)))))
+ [_]
+ (fail (str "[Analyser Error] Unmatched token: " (&/show-ast token)))))
(defn ^:private analyse-ast [token]
;; (prn 'analyse-ast token)
- (match token
- [::&parser/Form ([[::&parser/Tag ?tag] & ?values] :seq)]
+ (matchv ::M/objects [token]
+ [["Form" ["Cons" [["Tag" ?tag] ?values]]]]
(exec [;; :let [_ (prn 'PRE-ASSERT)]
+ :let [?values (&/->seq ?values)]
:let [_ (assert (= 1 (count ?values)) (str "[Analyser Error] Can only tag 1 value: " (pr-str token)))]
;; :let [_ (prn 'POST-ASSERT)]
- :let [?value (first ?values)]
- =value (&&/analyse-1 analyse-ast ?value)
+ =value (&&/analyse-1 analyse-ast (first ?values))
=value-type (&&/expr-type =value)]
(return (list [::&&/Expression [::&&/variant ?tag =value] [::&type/Variant (list [?tag =value-type])]])))
- [::&parser/Form ([?fn & ?args] :seq)]
+ [["Form" ["Cons" [?fn ?args]]]]
(fn [state]
(match ((&&/analyse-1 analyse-ast ?fn) state)
[::&/ok [state* =fn]]
@@ -228,7 +257,7 @@
_
((analyse-basic-ast analyse-ast token) state)))
- _
+ [_]
(analyse-basic-ast analyse-ast token)))
;; [Resources]
diff --git a/src/lux/analyser/case.clj b/src/lux/analyser/case.clj
index 5227bfcb0..0980b2865 100644
--- a/src/lux/analyser/case.clj
+++ b/src/lux/analyser/case.clj
@@ -1,5 +1,6 @@
(ns lux.analyser.case
- (:require [clojure.core.match :refer [match]]
+ (:require [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
(lux [base :as & :refer [exec return fail
try-all-m map-m mapcat-m reduce-m
assert!]]
@@ -10,17 +11,17 @@
;; [Resources]
(defn locals [member]
- (match member
- [::&parser/Ident ?name]
+ (matchv ::M/objects [member]
+ [["Ident" ?name]]
(list ?name)
- [::&parser/Tuple ?submembers]
- (mapcat locals ?submembers)
+ [["Tuple" ?submembers]]
+ (mapcat locals (&/->seq ?submembers))
- [::&parser/Form ([[::&parser/Tag _] & ?submembers] :seq)]
- (mapcat locals ?submembers)
+ [["Form" ["Cons" [["Tag" _] ?submembers]]]]
+ (mapcat locals (&/->seq ?submembers))
- _
+ [_]
(list)))
(defn analyse-branch [analyse max-registers [bindings body]]
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj
index 5b96a2a74..f6f20d695 100644
--- a/src/lux/analyser/host.clj
+++ b/src/lux/analyser/host.clj
@@ -1,6 +1,7 @@
(ns lux.analyser.host
(:require (clojure [template :refer [do-template]])
- [clojure.core.match :refer [match]]
+ [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
(lux [base :as & :refer [exec return fail
try-all-m map-m mapcat-m reduce-m
assert!]]
@@ -10,12 +11,20 @@
(lux.analyser [base :as &&])))
;; [Utils]
+(defn ^:private ->seq [xs]
+ (matchv ::M/objects [xs]
+ [["Nil" _]]
+ (list)
+
+ [["Cons" [x xs*]]]
+ (cons x (->seq xs*))))
+
(defn ^:private extract-ident [ident]
- (match ident
- [::&parser/Ident ?ident]
+ (matchv ::M/objects [ident]
+ [["Ident" ?ident]]
(return ?ident)
- _
+ [_]
(fail "[Analyser Error] Can't extract Ident.")))
;; [Resources]
@@ -156,16 +165,22 @@
(defn analyse-jvm-interface [analyse ?name ?members]
;; (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]]))
+ ;; (prn 'analyse-jvm-interface (&/show-ast member))
+ (matchv ::M/objects [member]
+ [["Form" ["Cons" [["Ident" ":"]
+ ["Cons" [["Ident" ?member-name]
+ ["Cons" [["Form" ["Cons" [["Ident" "->"]
+ ["Cons" [["Tuple" ?inputs]
+ ["Cons" [["Ident" ?output]
+ ["Nil" _]]]]]]]]
+ ["Nil" _]]]]]]]]]
+ (do ;; (prn 'analyse-jvm-interface ?member-name ?inputs ?output)
+ (exec [?inputs (map-m extract-ident (&/->seq ?inputs))]
+ (return [?member-name [?inputs ?output]])))
- _
+ [_]
(fail "[Analyser Error] Invalid method signature!")))
- ?members)
+ (&/->seq ?members))
:let [=methods (into {} (for [[method [inputs output]] ?members]
[method {:access :public
:type [inputs output]}]))]
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj
index 82f6eb4da..077799144 100644
--- a/src/lux/analyser/lux.clj
+++ b/src/lux/analyser/lux.clj
@@ -75,12 +75,12 @@
(if macro?
(let [macro-class (&host/location (list ?module ?name))]
(exec [macro-expansion (&macro/expand loader macro-class ?args)]
- (mapcat-m analyse macro-expansion)))
- (exec [=args (mapcat-m analyse ?args)]
+ (mapcat-m analyse (&/->seq macro-expansion))))
+ (exec [=args (mapcat-m analyse (&/->seq ?args))]
(return (list [::&&/Expression [::&&/call =fn =args] &type/+dont-care-type+])))))
_
- (exec [=args (mapcat-m analyse ?args)]
+ (exec [=args (mapcat-m analyse (&/->seq ?args))]
(return (list [::&&/Expression [::&&/call =fn =args] &type/+dont-care-type+]))))
:else
@@ -145,6 +145,6 @@
_ (&&def/declare-macro module-name ?ident)]
(return (list))))
-(defn analyse-require [analyse ?path]
+(defn analyse-import [analyse ?path]
(assert false)
(return (list)))
diff --git a/src/lux/base.clj b/src/lux/base.clj
index 599ff6c72..689cf205f 100644
--- a/src/lux/base.clj
+++ b/src/lux/base.clj
@@ -1,6 +1,6 @@
(ns lux.base
(:require (clojure [template :refer [do-template]])
- [clojure.core.match :refer [match]]))
+ [clojure.core.match :as M :refer [match matchv]]))
;; [Resources]
;; [Resources/Contants]
@@ -272,3 +272,44 @@
(defn run-state [monad state]
(monad state))
+
+(defn V [tag value]
+ (to-array [tag value]))
+
+(defn ->seq [xs]
+ (matchv ::M/objects [xs]
+ [["Nil" _]]
+ (list)
+
+ [["Cons" [x xs*]]]
+ (cons x (->seq xs*))))
+
+(defn show-ast [ast]
+ (matchv ::M/objects [ast]
+ [["Bool" ?value]]
+ (pr-str ?value)
+
+ [["Int" ?value]]
+ (pr-str ?value)
+
+ [["Real" ?value]]
+ (pr-str ?value)
+
+ [["Char" ?value]]
+ (pr-str ?value)
+
+ [["Text" ?value]]
+ (str "\"" ?value "\"")
+
+ [["Tag" ?tag]]
+ (str "#" ?tag)
+
+ [["Ident" ?ident]]
+ ?ident
+
+ [["Tuple" ?elems]]
+ (str "[" (->> (->seq ?elems) (map show-ast) (interpose " ") (apply str)) "]")
+
+ [["Form" ?elems]]
+ (str "(" (->> (->seq ?elems) (map show-ast) (interpose " ") (apply str)) ")")
+ ))
diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj
index 37fe6c61f..4f39e5c66 100644
--- a/src/lux/compiler/case.clj
+++ b/src/lux/compiler/case.clj
@@ -1,7 +1,8 @@
(ns lux.compiler.case
(:require (clojure [set :as set]
[template :refer [do-template]])
- [clojure.core.match :refer [match]]
+ [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
(lux [base :as & :refer [exec return* return fail fail*
repeat-m exhaust-m try-m try-all-m map-m reduce-m
apply-m
@@ -19,36 +20,39 @@
;; [Utils]
(defn ^:private ->match [$body register token]
- (match token
- [::&parser/Ident ?name]
+ (matchv ::M/objects [token]
+ [["Ident" ?name]]
[(inc register) [::Pattern $body [::StoreMatch register]]]
- [::&parser/Bool ?value]
+ [["Bool" ?value]]
[register [::Pattern $body [::BoolMatch ?value]]]
- [::&parser/Int ?value]
+ [["Int" ?value]]
[register [::Pattern $body [::IntMatch ?value]]]
- [::&parser/Real ?value]
+ [["Real" ?value]]
[register [::Pattern $body [::RealMatch ?value]]]
- [::&parser/Char ?value]
+ [["Char" ?value]]
[register [::Pattern $body [::CharMatch ?value]]]
- [::&parser/Text ?value]
+ [["Text" ?value]]
[register [::Pattern $body [::TextMatch ?value]]]
- [::&parser/Tuple ?members]
+ [["Tuple" ?members]]
(let [[register* =members] (reduce (fn [[register =members] member]
(let [[register* =member] (->match $body register member)]
[register* (cons =member =members)]))
- [register (list)] ?members)]
+ [register (list)]
+ (&/->seq ?members))]
[register* [::Pattern $body [::TupleMatch (reverse =members)]]])
- [::&parser/Tag ?tag]
+ [["Tag" ?tag]]
[register [::Pattern $body [::VariantMatch ?tag [::Pattern $body [::TupleMatch (list)]]]]]
- [::&parser/Form ([[::&parser/Tag ?tag] ?value] :seq)]
+ [["Form" ["Cons" [["Tag" ?tag]
+ ["Cons" [?value
+ ["Nil" _]]]]]]]
(let [[register* =value] (->match $body register ?value)]
[register* [::Pattern $body [::VariantMatch ?tag =value]]])
diff --git a/src/lux/host.clj b/src/lux/host.clj
index 7490bf152..ef4f1ca54 100644
--- a/src/lux/host.clj
+++ b/src/lux/host.clj
@@ -1,7 +1,8 @@
(ns lux.host
(:require (clojure [string :as string]
[template :refer [do-template]])
- [clojure.core.match :refer [match]]
+ [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
(lux [base :as & :refer [exec return* return fail fail*
repeat-m try-all-m map-m mapcat-m reduce-m
normalize-ident]]
@@ -96,15 +97,15 @@
(->type-signature function-class)))
(defn extract-jvm-param [token]
- (match token
- [::&parser/Ident ?ident]
+ (matchv ::M/objects [token]
+ [["Ident" ?ident]]
(full-class-name ?ident)
- [::&parser/Form ([[::&parser/Ident "Array"] [::&parser/Ident ?inner]] :seq)]
+ [["Form" ["Cons" [["Ident" "Array"] ["Cons" [["Ident" ?inner] ["Nil" _]]]]]]]
(exec [=inner (full-class-name ?inner)]
(return (str "[L" (->class =inner) ";")))
- _
+ [_]
(fail (str "[Host] Unknown JVM param: " (pr-str token)))))
(do-template [<name> <static?>]
diff --git a/src/lux/macro.clj b/src/lux/macro.clj
index 9f42d6402..9a2b7e2d9 100644
--- a/src/lux/macro.clj
+++ b/src/lux/macro.clj
@@ -1,66 +1,7 @@
(ns lux.macro
- (:require [clojure.core.match :refer [match]]
- (lux [base :as & :refer [fail* return*]]
- [parser :as &parser])))
-
-;; [Utils]
-(defn ^:private ->lux+ [->lux loader xs]
- (reduce (fn [tail x]
- (to-array ["Cons" (to-array [(->lux loader x) tail])]))
- (to-array ["Nil" (to-array [])])
- (reverse xs)))
-
-(defn ^:private ->lux-one [loader tag value]
- (to-array [tag value]))
-
-(defn ^:private ->lux-many [->lux loader tag values]
- (to-array [tag (->lux+ ->lux loader values)]))
-
-(defn ^:private ->lux [loader x]
- (match x
- [::&parser/Bool ?value]
- (->lux-one loader "Bool" ?value)
- [::&parser/Int ?value]
- (->lux-one loader "Int" ?value)
- [::&parser/Real ?value]
- (->lux-one loader "Real" ?value)
- [::&parser/Char ?value]
- (->lux-one loader "Char" ?value)
- [::&parser/Text ?value]
- (->lux-one loader "Text" ?value)
- [::&parser/Tag ?value]
- (->lux-one loader "Tag" ?value)
- [::&parser/Ident ?value]
- (->lux-one loader "Ident" ?value)
- [::&parser/Tuple ?elems]
- (->lux-many ->lux loader "Tuple" ?elems)
- [::&parser/Form ?elems]
- (->lux-many ->lux loader "Form" ?elems)
- ))
-
-(defn ^:private ->clojure+ [->clojure xs]
- ;; (prn '->clojure+ (aget xs 0))
- (case (aget xs 0)
- "Nil" (list)
- "Cons" (let [tuple2 (aget xs 1)]
- (cons (->clojure (aget tuple2 0))
- (->clojure+ ->clojure (aget tuple2 1))))
- ))
-
-(defn ^:private ->clojure [x]
- ;; (if (= "Tag" (aget x 0))
- ;; (println " ->clojure" (pr-str (aget x 0)) (aget x 1))
- ;; (println " ->clojure" (pr-str (aget x 0))))
- (case (aget x 0)
- "Bool" [::&parser/Bool (aget x 1)]
- "Int" [::&parser/Int (aget x 1)]
- "Real" [::&parser/Real (aget x 1)]
- "Char" [::&parser/Char (aget x 1)]
- "Text" [::&parser/Text (aget x 1)]
- "Tag" [::&parser/Tag (aget x 1)]
- "Ident" [::&parser/Ident (aget x 1)]
- "Tuple" [::&parser/Tuple (->clojure+ ->clojure (aget x 1))]
- "Form" [::&parser/Form (->clojure+ ->clojure (aget x 1))]))
+ (:require [clojure.core.match :as M :refer [match matchv]]
+ clojure.core.match.array
+ (lux [base :as & :refer [fail* return*]])))
;; [Resources]
(defn expand [loader macro-class tokens]
@@ -68,8 +9,11 @@
(let [output (-> (.loadClass loader macro-class)
(.getField "_datum")
(.get nil)
- (.apply (->lux+ ->lux loader tokens))
+ (.apply tokens)
(.apply state))]
- (case (aget output 0)
- "Ok" (return* (aget output 1 0) (->clojure+ ->clojure (aget output 1 1)))
- "Error" (fail* (aget output 1))))))
+ (matchv ::M/objects [output]
+ [["Ok" [state* tokens*]]]
+ (return* state* tokens*)
+
+ [["Error" ?msg]]
+ (fail* ?msg)))))
diff --git a/src/lux/parser.clj b/src/lux/parser.clj
index 1b31e8da7..f506f5dc2 100644
--- a/src/lux/parser.clj
+++ b/src/lux/parser.clj
@@ -10,11 +10,13 @@
(exec [elems (repeat-m parse)
token &lexer/lex]
(if (= <close-token> token)
- (return (list [<tag> (apply concat elems)]))
+ (return (list (&/V <tag> (reduce #(&/V "Cons" (to-array [%2 %1]))
+ (&/V "Nil" nil)
+ (reverse (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,7 +30,9 @@
(fail (str "[Parser Error] Records must have an even number of elements."))
:else
- (return (list [::Record elems])))))
+ (return (list (&/V "Record" (reduce #(&/V "Cons" (to-array [%2 %1]))
+ (&/V "Nil" nil)
+ (reverse elems))))))))
;; [Interface]
(def parse
@@ -43,25 +47,25 @@
(return (list))
[::&lexer/bool ?value]
- (return (list [::Bool (Boolean/parseBoolean ?value)]))
+ (return (list (&/V "Bool" (Boolean/parseBoolean ?value))))
[::&lexer/int ?value]
- (return (list [::Int (Integer/parseInt ?value)]))
+ (return (list (&/V "Int" (Integer/parseInt ?value))))
[::&lexer/real ?value]
- (return (list [::Real (Float/parseFloat ?value)]))
+ (return (list (&/V "Real" (Float/parseFloat ?value))))
[::&lexer/char ?value]
- (return (list [::Char (.charAt ?value 0)]))
+ (return (list (&/V "Char" (.charAt ?value 0))))
[::&lexer/text ?value]
- (return (list [::Text ?value]))
+ (return (list (&/V "Text" ?value)))
[::&lexer/ident ?value]
- (return (list [::Ident ?value]))
+ (return (list (&/V "Ident" ?value)))
[::&lexer/tag ?value]
- (return (list [::Tag ?value]))
+ (return (list (&/V "Tag" ?value)))
[::&lexer/open-paren]
(parse-form parse)