aboutsummaryrefslogtreecommitdiff
path: root/src/lux/analyser/lux.clj
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lux/analyser/lux.clj132
1 files changed, 79 insertions, 53 deletions
diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj
index 61ca08b42..a9a42ffe3 100644
--- a/src/lux/analyser/lux.clj
+++ b/src/lux/analyser/lux.clj
@@ -19,30 +19,53 @@
;; [Exports]
(defn analyse-tuple [analyse exo-type ?elems]
- (|do [=elems (&/map% (analyse-1+ analyse) ?elems)
- =elems-types (&/map% &&/expr-type =elems)
- ;; :let [_ (prn 'analyse-tuple =elems)]
- :let [endo-type (&/V "lux;TupleT" =elems-types)]
- _ (&type/check exo-type endo-type)
- ;; :let [_ (prn 'analyse-tuple 'DONE)]
- ]
+ (prn 'analyse-tuple (str "[" (->> ?elems (&/|map &/show-ast) (&/|interpose " ") (&/fold str "")) "]")
+ (&type/show-type exo-type))
+ (|do [members-vars (&/map% (constantly &type/fresh-var) ?elems)
+ _ (&type/check exo-type (&/V "lux;TupleT" members-vars))
+ =elems (&/map% (fn [ve]
+ (|let [[=var elem] ve]
+ (|do [output (&&/analyse-1 analyse =var elem)]
+ (matchv ::M/objects [output]
+ [["Expression" [?val ?type]]]
+ (|do [=val-type (&type/clean =var ?type)]
+ (return (&/V "Expression" (&/T ?val exo-type))))))))
+ (&/zip2 members-vars ?elems))]
(return (&/|list (&/V "Expression" (&/T (&/V "tuple" =elems)
exo-type))))))
(defn analyse-variant [analyse exo-type ident ?value]
(|let [[?module ?name] ident]
- (|do [module (if (= "" ?module)
- &/get-module-name
- (return ?module))
- :let [?tag (str module ";" ?name)]
- =value ((analyse-1+ analyse) ?value)
- =value-type (&&/expr-type =value)
- :let [endo-type (&/V "lux;VariantT" (|list (&/T ?tag =value-type)))]
- _ (&type/check exo-type endo-type)
- ;; :let [_ (prn 'analyse-variant 'DONE)]
- ]
- (return (&/|list (&/V "Expression" (&/T (&/V "variant" (&/T ?tag =value))
- exo-type)))))))
+ (do (prn 'analyse-variant (str ?module ";" ?name) (&/show-ast ?value))
+ (|do [:let [_ (prn 'analyse-variant/exo-type (&type/show-type exo-type))]
+ module (if (= "" ?module)
+ &/get-module-name
+ (return ?module))
+ :let [?tag (str module ";" ?name)]
+ exo-type* (matchv ::M/objects [exo-type]
+ [["lux;VarT" ?id]]
+ (|do [? (&type/bound? ?id)]
+ (if ?
+ (|do [exo-type (&type/deref ?id)]
+ (&type/actual-type exo-type))
+ (|do [_ (&type/set-var ?id &type/Type)]
+ (&type/actual-type &type/Type))))
+
+ [_]
+ (&type/actual-type exo-type))
+ :let [_ (prn 'exo-type* (&type/show-type exo-type*))]]
+ (matchv ::M/objects [exo-type*]
+ [["lux;VariantT" ?cases]]
+ (if-let [vtype (&/|get ?tag ?cases)]
+ (|do [:let [_ (prn 'VARIANT_BODY ?tag (&/show-ast ?value) (&type/show-type vtype))]
+ =value (&&/analyse-1 analyse vtype ?value)
+ :let [_ (prn 'GOT_VALUE =value)]]
+ (return (&/|list (&/V "Expression" (&/T (&/V "variant" (&/T ?tag =value))
+ exo-type)))))
+ (fail (str "[Analyser Error] There is no case " ?tag " for variant type " (&type/show-type exo-type*))))
+
+ [_]
+ (fail (str "[Analyser Error] Can't create a variant if the expected type is " (&type/show-type exo-type*))))))))
(defn analyse-record [analyse exo-type ?elems]
(|do [=elems (&/map% (fn [kv]
@@ -162,39 +185,41 @@
(defn analyse-lambda [analyse exo-type ?self ?arg ?body]
;; (prn 'analyse-lambda ?self ?arg ?body)
- (|do [=lambda-type* &type/fresh-lambda]
+ (|do [=lambda-type* &type/fresh-lambda
+ _ (&type/check exo-type =lambda-type*)]
(matchv ::M/objects [=lambda-type*]
[["lux;LambdaT" [=arg =return]]]
(|do [[=scope =captured =body] (&&lambda/with-lambda ?self =lambda-type*
?arg =arg
(&&/analyse-1 analyse =return ?body))
=lambda-type** (&type/clean =return =lambda-type*)
- =bound-arg (&type/lookup =arg)
- =lambda-type (matchv ::M/objects [=arg =bound-arg]
- [["lux;VarT" id] ["lux;Some" bound]]
- (&type/clean =arg =lambda-type**)
-
- [["lux;VarT" id] ["lux;None" _]]
- (let [var-name (str (gensym ""))
- bound (&/V "lux;BoundT" var-name)]
- (|do [_ (&type/reset id bound)
- lambda-type (&type/clean =arg =lambda-type**)]
- (return (&/V "lux;AllT" (&/T (&/|list) "" var-name lambda-type))))))]
+ =lambda-type (matchv ::M/objects [=arg]
+ [["lux;VarT" ?id]]
+ (&/try-all% (&/|list (|do [bound (&type/deref ?id)]
+ (&type/clean =arg =lambda-type**))
+ (let [var-name (str (gensym ""))]
+ (|do [_ (&type/set-var ?id (&/V "lux;BoundT" var-name))
+ lambda-type (&type/clean =arg =lambda-type**)]
+ (return (&/V "lux;AllT" (&/T (&/|list) "" var-name lambda-type)))))))
+
+ [_]
+ (fail ""))]
(return (&/|list (&/V "Expression" (&/T (&/V "lambda" (&/T =scope =captured =body)) =lambda-type))))))))
(defn analyse-def [analyse exo-type ?name ?value]
- ;; (prn 'analyse-def ?name ?value)
- (|do [_ (&type/check &type/Nothing exo-type)
- module-name &/get-module-name]
- (&/if% (&&def/defined? module-name ?name)
- (fail (str "[Analyser Error] Can't redefine " ?name))
- (|do [=value (&/with-scope ?name
- (&&/with-var
- #(&&/analyse-1 analyse % ?value)))
- =value-type (&&/expr-type =value)
- :let [_ (prn 'analyse-def ?name (&type/show-type =value-type))]
- _ (&&def/define module-name ?name =value-type)]
- (return (&/|list (&/V "Statement" (&/V "def" (&/T ?name =value)))))))))
+ (prn 'analyse-def ?name (&/show-ast ?value))
+ (|do [_ (&type/check exo-type &type/Nothing)
+ module-name &/get-module-name
+ ? (&&def/defined? module-name ?name)]
+ (if ?
+ (fail (str "[Analyser Error] Can't redefine " ?name))
+ (|do [=value (&/with-scope ?name
+ (&&/with-var
+ #(&&/analyse-1 analyse % ?value)))
+ =value-type (&&/expr-type =value)
+ :let [_ (prn 'analyse-def ?name (&type/show-type =value-type))]
+ _ (&&def/define module-name ?name =value-type)]
+ (return (&/|list (&/V "Statement" (&/V "def" (&/T ?name =value)))))))))
(defn analyse-declare-macro [exo-type ident]
(|let [[?module ?name] ident]
@@ -211,23 +236,24 @@
(defn analyse-check [analyse eval! exo-type ?type ?value]
(println "analyse-check#0")
(|do [=type (&&/analyse-1 analyse &type/Type ?type)
- :let [_ (println "analyse-check#1")]
- ==type (eval! =type)
- _ (&type/check exo-type ==type)
- :let [_ (println "analyse-check#4" (&type/show-type ==type))]
- =value (&&/analyse-1 analyse ==type ?value)
- :let [_ (println "analyse-check#5")]]
+ ;; =type ((analyse-1+ analyse) ?type)
+ :let [_ (println "analyse-check#1")]
+ ==type (eval! =type)
+ _ (&type/check exo-type ==type)
+ :let [_ (println "analyse-check#4" (&type/show-type ==type))]
+ =value (&&/analyse-1 analyse exo-type ?value)
+ :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")]]
+ _ (&type/check ==type ?expr-type)
+ :let [_ (println "analyse-check#7")]]
(return (&/|list (&/V "Expression" (&/T ?expr ==type))))))))
(defn analyse-coerce [analyse eval! exo-type ?type ?value]
(|do [=type (&&/analyse-1 analyse &type/Type ?type)
- ==type (eval! =type)
- =value (&&/analyse-1 analyse ==type ?value)]
+ ==type (eval! =type)
+ =value (&&/analyse-1 analyse ==type ?value)]
(matchv ::M/objects [=value]
[["Expression" [?expr ?expr-type]]]
(return (&/|list (&/V "Expression" (&/T ?expr ==type)))))))