diff options
Diffstat (limited to '')
-rw-r--r-- | source/lux.lux | 29 | ||||
-rw-r--r-- | src/lux/compiler/lux.clj | 152 |
2 files changed, 152 insertions, 29 deletions
diff --git a/source/lux.lux b/source/lux.lux index 2e5752592..2a4cc8660 100644 --- a/source/lux.lux +++ b/source/lux.lux @@ -1341,33 +1341,16 @@ (-> ($' List ($' List a)) ($' List a))) (foldL list:++ #Nil xs)) -## (def'' #export (normalize ident) -## (-> Ident ($' Lux Ident)) -## (_lux_case ident -## ["" name] -## (do Lux:Monad -## [module-name get-module-name] -## (;return (: Ident [module-name name]))) - -## _ -## (return ident))) -(def'' #export (normalize ident state) +(def'' #export (normalize ident) (-> Ident ($' Lux Ident)) (_lux_case ident ["" name] - (_lux_case state - {#source source #modules modules #module-aliases module-aliases - #envs envs #types types #host host - #seed seed} - (_lux_case (reverse envs) - #Nil - (#Left "Can't normalize Ident without a global environment.") - - (#Cons [{#name prefix #inner-closures _ #locals _ #closure _} _]) - (#Right [state [prefix name]]))) - + (do Lux:Monad + [module-name get-module-name] + (;return (_lux_: Ident [module-name name]))) + _ - (#Right [state ident]))) + (return ident))) (defmacro #export (| tokens) (do Lux:Monad diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index d0caff173..b47267d25 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -124,6 +124,147 @@ :let [_ (.visitMethodInsn *writer* Opcodes/INVOKEINTERFACE "lux/Function" "apply" &&/apply-signature)]] (return nil))) +(defn ^:private type->analysis [type] + (matchv ::M/objects [type] + [["lux;DataT" ?class]] + (&/T (&/V "variant" (&/T "lux;DataT" + (&/T (&/V "text" ?class) &type/$Void))) + &type/$Void) + + [["lux;TupleT" ?members]] + (&/T (&/V "variant" (&/T "lux;TupleT" + (&/fold (fn [tail head] + (&/V "variant" (&/T "lux;Cons" + (&/T (&/V "tuple" (&/|list (type->analysis head) + tail)) + &type/$Void)))) + (&/V "variant" (&/T "lux;Nil" + (&/T (&/V "tuple" (&/|list)) + &type/$Void))) + (&/|reverse ?members)))) + &type/$Void) + + [["lux;VariantT" ?cases]] + (&/T (&/V "variant" (&/T "lux;VariantT" + (&/fold (fn [tail head] + (|let [[hlabel htype] head] + (&/V "variant" (&/T "lux;Cons" + (&/T (&/V "tuple" (&/|list (&/T (&/V "tuple" (&/|list (&/T (&/V "text" hlabel) &type/$Void) + (type->analysis htype))) + &type/$Void) + tail)) + &type/$Void))))) + (&/V "variant" (&/T "lux;Nil" + (&/T (&/V "tuple" (&/|list)) + &type/$Void))) + (&/|reverse ?cases)))) + &type/$Void) + + [["lux;RecordT" ?slots]] + (&/T (&/V "variant" (&/T "lux;RecordT" + (&/fold (fn [tail head] + (|let [[hlabel htype] head] + (&/V "variant" (&/T "lux;Cons" + (&/T (&/V "tuple" (&/|list (&/T (&/V "tuple" (&/|list (&/T (&/V "text" hlabel) &type/$Void) + (type->analysis htype))) + &type/$Void) + tail)) + &type/$Void))))) + (&/V "variant" (&/T "lux;Nil" + (&/T (&/V "tuple" (&/|list)) + &type/$Void))) + (&/|reverse ?slots)))) + &type/$Void) + + [["lux;LambdaT" [?input ?output]]] + (&/T (&/V "variant" (&/T "lux;LambdaT" + (&/T (&/V "tuple" (&/|map type->analysis (&/|list ?input ?output))) + &type/$Void))) + &type/$Void) + + [["lux;AllT" [?env ?name ?arg ?body]]] + (&/T (&/V "variant" (&/T "lux;AllT" + (&/T (&/V "tuple" (&/|list (matchv ::M/objects [?env] + [["lux;None" _]] + (&/V "variant" (&/T "lux;Some" + (&/T (&/V "tuple" (&/|list)) + &type/$Void))) + + [["lux;Some" ??env]] + (&/V "variant" (&/T "lux;Some" + (&/T (&/fold (fn [tail head] + (|let [[hlabel htype] head] + (&/V "variant" (&/T "lux;Cons" + (&/T (&/V "tuple" (&/|list (&/T (&/V "tuple" (&/|list (&/T (&/V "text" hlabel) &type/$Void) + (type->analysis htype))) + &type/$Void) + tail)) + &type/$Void))))) + (&/V "variant" (&/T "lux;Nil" + (&/T (&/V "tuple" (&/|list)) + &type/$Void))) + (&/|reverse ??env)) + &type/$Void)))) + (&/T (&/V "text" ?name) &type/$Void) + (&/T (&/V "text" ?arg) &type/$Void) + (type->analysis ?body))) + &type/$Void))) + &type/$Void) + + [["lux;BoundT" ?name]] + (&/T (&/V "variant" (&/T "lux;BoundT" + (&/T (&/V "text" ?name) &type/$Void))) + &type/$Void) + + [["lux;AppT" [?fun ?arg]]] + (&/T (&/V "variant" (&/T "lux;AppT" + (&/T (&/V "tuple" (&/|map type->analysis (&/|list ?fun ?arg))) + &type/$Void))) + &type/$Void) + )) + +(defn ^:private compile-def-type [compile ?body ?def-data] + (|do [^MethodVisitor **writer** &/get-writer] + (matchv ::M/objects [?def-data] + [["lux;TypeD" _]] + (let [_ (doto **writer** + ;; Tail: Begin + (.visitLdcInsn (int 2)) ;; S + (.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object") ;; V + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 0)) ;; VVI + (.visitLdcInsn "lux;TypeD") ;; VVIT + (.visitInsn Opcodes/AASTORE) ;; V + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 1)) ;; VVI + (.visitInsn Opcodes/ACONST_NULL) ;; VVIN + (.visitInsn Opcodes/AASTORE) ;; V + )] + (return nil)) + + [["lux;ValueD" _]] + (|let [;; _ (prn '?body (aget ?body 0) (aget ?body 1 0)) + [?def-value ?def-type] (matchv ::M/objects [?body] + [[["ann" [?def-value ?type-expr]] ?def-type]] + (&/T ?def-value ?type-expr) + + [[?def-value ?def-type]] + (&/T ?body (type->analysis ?def-type)))] + (|do [:let [_ (doto **writer** + (.visitLdcInsn (int 2)) ;; S + (.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object") ;; V + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 0)) ;; VVI + (.visitLdcInsn "lux;ValueD") ;; VVIT + (.visitInsn Opcodes/AASTORE) ;; V + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 1)) ;; VVI + )] + _ (compile ?def-type) + :let [_ (.visitInsn **writer** Opcodes/AASTORE)]] + (return nil))) + ))) + (defn compile-def [compile ?name ?body ?def-data] (|do [^ClassWriter *writer* &/get-writer module-name &/get-module-name @@ -136,17 +277,16 @@ current-class nil "java/lang/Object" (into-array ["lux/Function"])) (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_datum" datum-sig nil nil) (doto (.visitEnd))) - ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_mode" datum-sig nil ...) - ;; (doto (.visitEnd))) - ;; (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_type" datum-sig nil nil) - ;; (doto (.visitEnd))) - )] + (-> (.visitField (+ Opcodes/ACC_PUBLIC Opcodes/ACC_FINAL Opcodes/ACC_STATIC) "_meta" datum-sig nil nil) + (doto (.visitEnd))))] _ (&/with-writer (.visitMethod =class Opcodes/ACC_PUBLIC "<clinit>" "()V" nil nil) (|do [^MethodVisitor **writer** &/get-writer :let [_ (.visitCode **writer**)] _ (compile ?body) + :let [_ (.visitFieldInsn **writer** Opcodes/PUTSTATIC current-class "_datum" datum-sig)] + _ (compile-def-type compile ?body ?def-data) + :let [_ (.visitFieldInsn **writer** Opcodes/PUTSTATIC current-class "_meta" datum-sig)] :let [_ (doto **writer** - (.visitFieldInsn Opcodes/PUTSTATIC current-class "_datum" datum-sig) (.visitInsn Opcodes/RETURN) (.visitMaxs 0 0) (.visitEnd))]] |