diff options
Diffstat (limited to 'src/lux/analyser/lux.clj')
-rw-r--r-- | src/lux/analyser/lux.clj | 122 |
1 files changed, 69 insertions, 53 deletions
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index 1abc0bcea..f1c7a6035 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -29,18 +29,17 @@ ;; (prn "^^ analyse-tuple ^^") ;; (prn 'analyse-tuple (str "[" (->> ?elems (&/|map &/show-ast) (&/|interpose " ") (&/fold str "")) "]") ;; (&type/show-type exo-type)) - (|do [t-members (matchv ::M/objects [exo-type] - [["lux;TupleT" ?members]] - (return ?members) + (matchv ::M/objects [exo-type] + [["lux;TupleT" ?members]] + (|do [=elems (&/map% (fn [ve] + (|let [[elem-t elem] ve] + (&&/analyse-1 analyse elem-t elem))) + (&/zip2 ?members ?elems))] + (return (&/|list (&/V "Expression" (&/T (&/V "tuple" =elems) + exo-type))))) - [_] - (fail "[Analyser Error] Tuple requires tuple-type.")) - =elems (&/map% (fn [ve] - (|let [[elem-t elem] ve] - (&&/analyse-1 analyse elem-t elem))) - (&/zip2 t-members ?elems))] - (return (&/|list (&/V "Expression" (&/T (&/V "tuple" =elems) - exo-type)))))) + [_] + (fail "[Analyser Error] Tuples require tuple-types."))) (defn analyse-variant [analyse exo-type ident ?value] ;; (prn "^^ analyse-variant ^^") @@ -102,7 +101,7 @@ (if o?? (|do [i?? (&type/is-Type? btype)] (if i?? - (do (println "FOUND TWO TYPES!") + (do ;; (println "FOUND TWO TYPES!") (return (&/|list binding))) (fail "[Type Error] Types don't match."))) (|do [_ (&type/check exo-type btype)] @@ -136,7 +135,7 @@ [=local inner*] (&/fold (fn [register+new-inner frame+in-scope] (|let [[register new-inner] register+new-inner [frame in-scope] frame+in-scope - [register* frame*] (&&lambda/close-over (&/|cons module-name (&/|reverse in-scope)) ?name register frame)] + [register* frame*] (&&lambda/close-over (&/|cons module-name (&/|reverse in-scope)) ident register frame)] (&/T register* (&/|cons frame* new-inner)))) (&/T (or (->> top-outer (&/get$ "lux;locals") (&/get$ "lux;mappings") (&/|get local-ident)) (->> top-outer (&/get$ "lux;closure") (&/get$ "lux;mappings") (&/|get local-ident))) @@ -151,25 +150,42 @@ )) (defn ^:private analyse-apply* [analyse exo-type =fn ?args] - (|do [=args (&/map% (fn [arg] (analyse-1+ analyse arg)) - ?args) - =fn-type (&&/expr-type =fn) - [=apply =output-type] (&/fold% (fn [[=fn =fn-type] =input] - (|do [;; :let [_ (prn "#2")] - =input-type (&&/expr-type =input) - ;; :let [_ (prn "#3")] - =output-type (&type/apply-lambda =fn-type =input-type) - ;; :let [_ (prn "#4")] - ] - (return [(&/V "Expression" (&/T (&/V "apply" (&/T =fn =input)) - =output-type)) - =output-type]))) - [=fn =fn-type] - =args) - _ (&type/check exo-type =output-type)] - (matchv ::M/objects [=apply] - [["Expression" [?expr _]]] - (return (&/|list (&/V "Expression" (&/T ?expr exo-type))))))) + (prn 'analyse-apply*/exo-type (&type/show-type exo-type)) + (matchv ::M/objects [=fn] + [["Statement" _]] + (fail "[Analyser Error] Can't apply a statement!") + + [["Expression" [?fun-expr ?fun-type]]] + (matchv ::M/objects [?args] + [["lux;Nil" _]] + (|do [_ (&type/check exo-type ?fun-type)] + (return (&/|list =fn))) + + [["lux;Cons" [?arg ?args*]]] + (do (prn 'analyse-apply*/=fn (&type/show-type ?fun-type)) + (matchv ::M/objects [?fun-type] + [["lux;AllT" _]] + (&type/with-var + (fn [$var] + (|do [type* (&type/apply-type ?fun-type $var) + output (analyse-apply* analyse exo-type (&/V "Expression" (&/T ?fun-expr type*)) ?args)] + (matchv ::M/objects [output] + [["lux;Cons" [["Expression" [?expr* ?type*]] ["lux;Nil" _]]]] + (|do [type** (&type/clean $var ?type*)] + (return (&/|list (&/V "Expression" (&/T ?expr* type**))))) + + [_] + (do (prn 'analyse-apply*/output (aget output 0)) + (assert false)))))) + + [["lux;LambdaT" [?input-t ?output-t]]] + (|do [=arg (&&/analyse-1 analyse ?input-t ?arg)] + (return (&/|list (&/V "Expression" (&/T (&/V "apply" (&/T =fn =arg)) + ?output-t))))) + + [_] + (fail "[Analyser Error] Can't apply a non-function."))) + ))) (defn analyse-apply [analyse exo-type =fn ?args] ;; (prn 'analyse-apply1 (aget =fn 0)) @@ -183,12 +199,13 @@ (if macro? (let [macro-class (&host/location (&/|list ?module ?name))] (|do [macro-expansion (¯o/expand loader macro-class ?args) - output (&/flat-map% analyse macro-expansion)] + :let [_ (prn 'EXPANDING (&type/show-type exo-type))] + output (&/flat-map% (partial analyse exo-type) macro-expansion)] (return output))) (analyse-apply* analyse exo-type =fn ?args))) [_] - (analyse-apply* analyse =fn ?args))) + (analyse-apply* analyse exo-type =fn ?args))) [_] (fail "[Analyser Error] Can't call a statement!")) @@ -217,7 +234,7 @@ (return (&/V "Expression" (&/T (&/V "lambda" (&/T =scope =captured =body)) exo-type)))) [_] - (fail "[Analyser Error] Functions require function types."))) + (fail (str "[Analyser Error] Functions require function types: " (&type/show-type exo-type))))) (defn analyse-lambda** [analyse exo-type ?self ?arg ?body] (prn 'analyse-lambda**/&& (aget exo-type 0)) @@ -241,10 +258,9 @@ (|do [output (analyse-lambda** analyse exo-type ?self ?arg ?body)] (return (&/|list output)))) -(defn analyse-def [analyse exo-type ?name ?value] +(defn analyse-def [analyse ?name ?value] (prn 'analyse-def/CODE ?name (&/show-ast ?value)) - (|do [_ (&type/check exo-type &type/Nothing) - module-name &/get-module-name + (|do [module-name &/get-module-name ? (&&def/defined? module-name ?name)] (if ? (fail (str "[Analyser Error] Can't redefine " ?name)) @@ -260,34 +276,34 @@ ] (return (&/|list (&/V "Statement" (&/V "def" (&/T ?name =value))))))))) -(defn analyse-declare-macro [exo-type ident] - (|let [[?module ?name] ident] - (|do [module-name &/get-module-name] - (if (= ?module module-name) - (|do [_ (&&def/declare-macro ?module ?name)] - (return (&/|list))) - (fail "Can't declare macros from foreign modules."))))) +(defn analyse-declare-macro [ident] + (|do [current-module &/get-module-name + :let [_ (prn 'analyse-declare-macro/current-module current-module)] + [?module ?name] (&&/resolved-ident* ident) + :let [_ (prn 'analyse-declare-macro '[?module ?name] [?module ?name])]] + (if (= ?module current-module) + (|do [_ (&&def/declare-macro ?module ?name)] + (return (&/|list))) + (fail "Can't declare macros from foreign modules.")))) (defn analyse-import [analyse exo-type ?path] (assert false) (return (&/|list))) (defn analyse-check [analyse eval! exo-type ?type ?value] - (println "analyse-check#0") + ;; (println "analyse-check#0") (|do [=type (&&/analyse-1 analyse &type/Type ?type) ;; =type (analyse-1+ analyse ?type) - :let [_ (println "analyse-check#1")] + ;; :let [_ (println "analyse-check#1")] ==type (eval! =type) _ (&type/check exo-type ==type) - :let [_ (println "analyse-check#4" (&type/show-type ==type))] + ;; :let [_ (println "analyse-check#4" (&type/show-type ==type))] =value (&&/analyse-1 analyse ==type ?value) - :let [_ (println "analyse-check#5")]] + ;; :let [_ (println "analyse-check#5")] + ] (matchv ::M/objects [=value] [["Expression" [?expr ?expr-type]]] - (|do [:let [_ (println "analyse-check#6" (&type/show-type ?expr-type))] - ;; _ (&type/check ==type ?expr-type) - :let [_ (println "analyse-check#7")]] - (return (&/|list (&/V "Expression" (&/T ?expr ==type)))))))) + (return (&/|list (&/V "Expression" (&/T ?expr ==type))))))) (defn analyse-coerce [analyse eval! exo-type ?type ?value] (|do [=type (&&/analyse-1 analyse &type/Type ?type) |