From e2fcc7ebbb1f423a3137aa5525b9409f870fe191 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 10 Mar 2015 01:39:35 -0400 Subject: - Modified the compiler so parser syntax tokens are stored in the same format as lux data-structures, to ease communication between the compiler & macros. --- src/lux.clj | 1 - src/lux/analyser.clj | 197 ++++++++++++++++++++++++++-------------------- src/lux/analyser/case.clj | 17 ++-- src/lux/analyser/host.clj | 39 ++++++--- src/lux/analyser/lux.clj | 8 +- src/lux/base.clj | 43 +++++++++- src/lux/compiler/case.clj | 28 ++++--- src/lux/host.clj | 11 +-- src/lux/macro.clj | 76 +++--------------- src/lux/parser.clj | 26 +++--- 10 files changed, 242 insertions(+), 204 deletions(-) (limited to 'src') 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 (¯o/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 [ ] 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 (= token) - (return (list [ (apply concat elems)])) + (return (list (&/V (reduce #(&/V "Cons" (to-array [%2 %1])) + (&/V "Nil" nil) + (reverse (apply concat elems)))))) (fail (str "[Parser Error] Unbalanced " "."))))) - ^: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) -- cgit v1.2.3