diff options
Diffstat (limited to '')
-rw-r--r-- | project.clj | 2 | ||||
-rw-r--r-- | source/lux.lux | 24 | ||||
-rw-r--r-- | source/lux/data/list.lux | 20 | ||||
-rw-r--r-- | source/lux/data/text.lux | 18 | ||||
-rw-r--r-- | source/lux/meta/lux.lux | 8 | ||||
-rw-r--r-- | src/lux/analyser.clj | 62 | ||||
-rw-r--r-- | src/lux/analyser/env.clj | 1 | ||||
-rw-r--r-- | src/lux/analyser/host.clj | 21 | ||||
-rw-r--r-- | src/lux/analyser/lux.clj | 33 | ||||
-rw-r--r-- | src/lux/analyser/module.clj | 6 | ||||
-rw-r--r-- | src/lux/compiler.clj | 27 | ||||
-rw-r--r-- | src/lux/compiler/base.clj | 2 | ||||
-rw-r--r-- | src/lux/compiler/cache.clj | 22 | ||||
-rw-r--r-- | src/lux/compiler/case.clj | 4 | ||||
-rw-r--r-- | src/lux/compiler/lux.clj | 78 | ||||
-rw-r--r-- | src/lux/compiler/type.clj | 2 | ||||
-rw-r--r-- | src/lux/host.clj | 3 | ||||
-rw-r--r-- | src/lux/optimizer.clj | 4 | ||||
-rw-r--r-- | src/lux/type.clj | 4 |
19 files changed, 210 insertions, 131 deletions
diff --git a/project.clj b/project.clj index a0fd8d1cb..88191109a 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject lux-jvm "0.2.0" +(defproject lux-jvm "0.3.0" :description "The JVM compiler for the Lux programming language." :url "https://github.com/LuxLang/lux" :license {:name "Eclipse Public License" diff --git a/source/lux.lux b/source/lux.lux index 3670a9e52..d3dd374d5 100644 --- a/source/lux.lux +++ b/source/lux.lux @@ -220,14 +220,16 @@ #Nil])])]))) ## (deftype (DefData' m) -## (| #TypeD -## (#ValueD Type) +## (| (#TypeD Type) +## (#ValueD (, Type Unit)) ## (#MacroD m) ## (#AliasD Ident))) (_lux_def DefData' (#AllT [(#Some #Nil) "lux;DefData'" "" - (#VariantT (#Cons [["lux;TypeD" (#TupleT #Nil)] - (#Cons [["lux;ValueD" Type] + (#VariantT (#Cons [["lux;TypeD" Type] + (#Cons [["lux;ValueD" (#TupleT (#Cons [Type + (#Cons [Unit + #Nil])]))] (#Cons [["lux;MacroD" (#BoundT "")] (#Cons [["lux;AliasD" Ident] #Nil])])])]))])) @@ -1710,7 +1712,7 @@ (_lux_case pattern (#Meta _ (#FormS (#Cons (#Meta _ (#SymbolS macro-name)) macro-args))) (do Lux/Monad - [expansion (macro-expand-all (form$ (list& (symbol$ macro-name) body macro-args))) + [expansion (macro-expand (form$ (list& (symbol$ macro-name) body macro-args))) expansions (map% Lux/Monad expander (as-pairs expansion))] (;return (list:join expansions))) @@ -2621,8 +2623,8 @@ (#Some _ def-data) (case def-data - #TypeD (#Some Type) - (#ValueD type) (#Some type) + (#TypeD _) (#Some Type) + (#ValueD [type _]) (#Some type) (#MacroD m) (#Some Macro) (#AliasD name') (find-in-defs name' state)))))) ## (def (find-in-defs name state) @@ -3048,3 +3050,11 @@ _ (fail "Wrong syntax for loop"))) + +## (defmacro #export (extend tokens) +## (case tokens +## (\ (list (#Meta _ (#SymbolS name)))) + + +## _ +## (fail "Wrong syntax for extend"))) diff --git a/source/lux/data/list.lux b/source/lux/data/list.lux index 2bbbe66cc..f840688fd 100644 --- a/source/lux/data/list.lux +++ b/source/lux/data/list.lux @@ -11,7 +11,8 @@ (functor #as F #refer #all) (monad #as M #refer #all) (eq #as E) - (dict #as D #refer #all)) + (dict #as D #refer #all) + (stack #as S)) (data (number (int #open ("i" Int/Number Int/Ord Int/Eq))) bool) meta/macro)) @@ -312,3 +313,20 @@ (if (:: eq (E;= k k')) kvs' (#;Cons [[k' v'] (recur kvs')]))))]))) + +(defstruct #export List/Stack (S;Stack List) + (def S;empty (list)) + (def (S;empty? xs) + (case xs + #;Nil true + _ false)) + (def (S;push x xs) + (#;Cons x xs)) + (def (S;pop xs) + (case xs + #;Nil #;None + (#;Cons x xs') (#;Some xs'))) + (def (S;top xs) + (case xs + #;Nil #;None + (#;Cons x xs') (#;Some x)))) diff --git a/source/lux/data/text.lux b/source/lux/data/text.lux index ae4f9974f..1d582c1d5 100644 --- a/source/lux/data/text.lux +++ b/source/lux/data/text.lux @@ -147,16 +147,14 @@ ## [Syntax] (def (extract-var template) (-> Text (Maybe (, Text Text Text))) - (exec (_jvm_invokevirtual "java.io.PrintStream" "println" ["java.lang.Object"] - (_jvm_getstatic "java.lang.System" "out") [(:: Text/Monoid (m;++ "Template: " template))]) - (do Maybe/Monad - [pre-idx (index-of "#{" template) - [pre in] (split pre-idx template) - [_ in] (split 2 in) - post-idx (index-of "}" in) - [var post] (split post-idx in) - [_ post] (split 1 post)] - (M;wrap [pre var post])))) + (do Maybe/Monad + [pre-idx (index-of "#{" template) + [pre in] (split pre-idx template) + [_ in] (split 2 in) + post-idx (index-of "}" in) + [var post] (split post-idx in) + [_ post] (split 1 post)] + (M;wrap [pre var post]))) (def (unravel-template template) (-> Text (List Syntax)) diff --git a/source/lux/meta/lux.lux b/source/lux/meta/lux.lux index 66e4cc341..cdbade999 100644 --- a/source/lux/meta/lux.lux +++ b/source/lux/meta/lux.lux @@ -286,10 +286,10 @@ (#;Some [_ def-data]) (case def-data - #;TypeD (#;Some Type) - (#;ValueD type) (#;Some type) - (#;MacroD m) (#;Some Macro) - (#;AliasD name') (find-in-defs name' state)))))) + (#;TypeD value) (#;Some Type) + (#;ValueD type _) (#;Some type) + (#;MacroD m) (#;Some Macro) + (#;AliasD name') (find-in-defs name' state)))))) (def #export (find-var-type name) (-> Ident (Lux Type)) diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj index f10f6b913..774188d82 100644 --- a/src/lux/analyser.clj +++ b/src/lux/analyser.clj @@ -34,7 +34,7 @@ ["lux;Nil" _]]]]]]]]] (&/T catch+ (&/V "lux;Some" ?finally-body)))) -(defn ^:private aba7 [analyse eval! compile-module exo-type token] +(defn ^:private aba7 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Arrays [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_new-array"]]]] @@ -64,25 +64,25 @@ ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?fields]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?methods]]] ["lux;Nil" _]]]]]]]]]]]]]]] - (&&host/analyse-jvm-class analyse ?name ?super-class ?interfaces ?fields ?methods) + (&&host/analyse-jvm-class analyse compile-token ?name ?super-class ?interfaces ?fields ?methods) [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_interface"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?name]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TupleS" ?supers]]] ?methods]]]]]]]] - (&&host/analyse-jvm-interface analyse ?name ?supers ?methods) + (&&host/analyse-jvm-interface analyse compile-token ?name ?supers ?methods) ;; Programs [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_program"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ?args]]] ["lux;Cons" [?body ["lux;Nil" _]]]]]]]]] - (&&host/analyse-jvm-program analyse ?args ?body) + (&&host/analyse-jvm-program analyse compile-token ?args ?body) [_] (fail ""))) -(defn ^:private aba6 [analyse eval! compile-module exo-type token] +(defn ^:private aba6 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Primitive conversions [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_d2f"]]]] ["lux;Cons" [?value ["lux;Nil" _]]]]]]] @@ -156,9 +156,9 @@ (&&host/analyse-jvm-lushr analyse exo-type ?x ?y) [_] - (aba7 analyse eval! compile-module exo-type token))) + (aba7 analyse eval! compile-module compile-token exo-type token))) -(defn ^:private aba5 [analyse eval! compile-module exo-type token] +(defn ^:private aba5 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Objects [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_null?"]]]] @@ -265,9 +265,9 @@ (&&host/analyse-jvm-monitorexit analyse exo-type ?monitor) [_] - (aba6 analyse eval! compile-module exo-type token))) + (aba6 analyse eval! compile-module compile-token exo-type token))) -(defn ^:private aba4 [analyse eval! compile-module exo-type token] +(defn ^:private aba4 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Float arithmetic [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_jvm_fadd"]]]] ["lux;Cons" [?y ["lux;Cons" [?x ["lux;Nil" _]]]]]]]]] @@ -320,9 +320,9 @@ (&&host/analyse-jvm-dgt analyse exo-type ?x ?y) [_] - (aba5 analyse eval! compile-module exo-type token))) + (aba5 analyse eval! compile-module compile-token exo-type token))) -(defn ^:private aba3 [analyse eval! compile-module exo-type token] +(defn ^:private aba3 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Host special forms ;; Characters @@ -386,9 +386,9 @@ (&&host/analyse-jvm-lgt analyse exo-type ?x ?y) [_] - (aba4 analyse eval! compile-module exo-type token))) + (aba4 analyse eval! compile-module compile-token exo-type token))) -(defn ^:private aba2 [analyse eval! compile-module exo-type token] +(defn ^:private aba2 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] [["lux;SymbolS" ?ident]] (&&lux/analyse-symbol analyse exo-type ?ident) @@ -408,17 +408,17 @@ ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ["" ?name]]]] ["lux;Cons" [?value ["lux;Nil" _]]]]]]]]] - (&&lux/analyse-def analyse ?name ?value) + (&&lux/analyse-def analyse compile-token ?name ?value) [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_lux_declare-macro"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ["" ?name]]]] ["lux;Nil" _]]]]]]] - (&&lux/analyse-declare-macro analyse ?name) + (&&lux/analyse-declare-macro analyse compile-token ?name) [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_lux_import"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?path]]] ["lux;Nil" _]]]]]]] - (&&lux/analyse-import analyse compile-module ?path) + (&&lux/analyse-import analyse compile-module compile-token ?path) [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_lux_:"]]]] ["lux;Cons" [?type @@ -435,18 +435,18 @@ [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_lux_export"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" ["" ?ident]]]] ["lux;Nil" _]]]]]]] - (&&lux/analyse-export analyse ?ident) + (&&lux/analyse-export analyse compile-token ?ident) [["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;SymbolS" [_ "_lux_alias"]]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?alias]]] ["lux;Cons" [["lux;Meta" [_ ["lux;TextS" ?module]]] ["lux;Nil" _]]]]]]]]] - (&&lux/analyse-alias analyse ?alias ?module) + (&&lux/analyse-alias analyse compile-token ?alias ?module) [_] - (aba3 analyse eval! compile-module exo-type token))) + (aba3 analyse eval! compile-module compile-token exo-type token))) -(defn ^:private aba1 [analyse eval! compile-module exo-type token] +(defn ^:private aba1 [analyse eval! compile-module compile-token exo-type token] (matchv ::M/objects [token] ;; Standard special forms [["lux;BoolS" ?value]] @@ -482,7 +482,7 @@ (&&host/analyse-jvm-null analyse exo-type) [_] - (aba2 analyse eval! compile-module exo-type token) + (aba2 analyse eval! compile-module compile-token exo-type token) )) (defn ^:private add-loc [meta ^String msg] @@ -491,12 +491,12 @@ (|let [[file line col] meta] (str "@ " file "," line "," col "\n" msg)))) -(defn ^:private analyse-basic-ast [analyse eval! compile-module exo-type token] +(defn ^:private analyse-basic-ast [analyse eval! compile-module compile-token exo-type token] ;; (prn 'analyse-basic-ast (&/show-ast token)) (matchv ::M/objects [token] [["lux;Meta" [meta ?token]]] (fn [state] - (matchv ::M/objects [((aba1 analyse eval! compile-module exo-type ?token) state)] + (matchv ::M/objects [((aba1 analyse eval! compile-module compile-token exo-type ?token) state)] [["lux;Right" [state* output]]] (return* state* output) @@ -526,28 +526,28 @@ (return (&/T ?output-term ?output-type))) )))) -(defn ^:private analyse-ast [eval! compile-module exo-type token] +(defn ^:private analyse-ast [eval! compile-module compile-token exo-type token] (&/with-expected-type exo-type (matchv ::M/objects [token] [["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [["lux;Meta" [_ ["lux;TagS" ?ident]]] ?values]]]]]] - (&&lux/analyse-variant (partial analyse-ast eval! compile-module) exo-type ?ident ?values) + (&&lux/analyse-variant (partial analyse-ast eval! compile-module compile-token) exo-type ?ident ?values) [["lux;Meta" [meta ["lux;FormS" ["lux;Cons" [?fn ?args]]]]]] (fn [state] - (matchv ::M/objects [((just-analyse (partial analyse-ast eval! compile-module) ?fn) state) + (matchv ::M/objects [((just-analyse (partial analyse-ast eval! compile-module compile-token) ?fn) state) ;; ((&type/with-var #(&&/analyse-1 (partial analyse-ast eval! compile-module) % ?fn)) state) ] [["lux;Right" [state* =fn]]] (do ;; (prn 'GOT_FUN (&/show-ast ?fn) (&/show-ast token) (aget =fn 0 0) (aget =fn 1 0)) - ((&&lux/analyse-apply (partial analyse-ast eval! compile-module) exo-type meta =fn ?args) state*)) + ((&&lux/analyse-apply (partial analyse-ast eval! compile-module compile-token) exo-type meta =fn ?args) state*)) [_] - ((analyse-basic-ast (partial analyse-ast eval! compile-module) eval! compile-module exo-type token) state))) + ((analyse-basic-ast (partial analyse-ast eval! compile-module compile-token) eval! compile-module compile-token exo-type token) state))) [_] - (analyse-basic-ast (partial analyse-ast eval! compile-module) eval! compile-module exo-type token)))) + (analyse-basic-ast (partial analyse-ast eval! compile-module compile-token) eval! compile-module compile-token exo-type token)))) ;; [Resources] -(defn analyse [eval! compile-module] +(defn analyse [eval! compile-module compile-token] (|do [asts &parser/parse] - (&/flat-map% (partial analyse-ast eval! compile-module &type/$Void) asts))) + (&/flat-map% (partial analyse-ast eval! compile-module compile-token &type/$Void) asts))) diff --git a/src/lux/analyser/env.clj b/src/lux/analyser/env.clj index cac0f8cd4..391d78411 100644 --- a/src/lux/analyser/env.clj +++ b/src/lux/analyser/env.clj @@ -20,6 +20,7 @@ (defn with-local [name type body] ;; (prn 'with-local name) (fn [state] + ;; (prn 'with-local name) (let [old-mappings (->> state (&/get$ &/$ENVS) &/|head (&/get$ &/$LOCALS) (&/get$ &/$MAPPINGS)) =return (body (&/update$ &/$ENVS (fn [stack] diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index 5033f4f2c..663c650e7 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -273,7 +273,7 @@ tname )) -(defn analyse-jvm-class [analyse ?name ?super-class ?interfaces ?fields ?methods] +(defn analyse-jvm-class [analyse compile-token ?name ?super-class ?interfaces ?fields ?methods] (|do [=interfaces (&/map% extract-text ?interfaces) =fields (&/map% (fn [?field] (matchv ::M/objects [?field] @@ -328,10 +328,11 @@ [_] (fail "[Analyser Error] Wrong syntax for method."))) - (&/enumerate ?methods))] - (return (&/|list (&/V "jvm-class" (&/T ?name ?super-class =interfaces =fields =methods)))))) + (&/enumerate ?methods)) + _ (compile-token (&/V "jvm-class" (&/T ?name ?super-class =interfaces =fields =methods)))] + (return (&/|list)))) -(defn analyse-jvm-interface [analyse ?name ?supers ?methods] +(defn analyse-jvm-interface [analyse compile-token ?name ?supers ?methods] (|do [=supers (&/map% extract-text ?supers) =methods (&/map% (fn [method] (matchv ::M/objects [method] @@ -349,8 +350,9 @@ [_] (fail (str "[Analyser Error] Invalid method signature: " (&/show-ast method))))) - ?methods)] - (return (&/|list (&/V "jvm-interface" (&/T ?name =supers =methods)))))) + ?methods) + _ (compile-token (&/V "jvm-interface" (&/T ?name =supers =methods)))] + (return (&/|list)))) (defn analyse-jvm-try [analyse exo-type ?body ?catches+?finally] (|do [:let [[?catches ?finally] ?catches+?finally] @@ -431,9 +433,10 @@ analyse-jvm-lushr "jvm-lushr" "java.lang.Long" "java.lang.Integer" ) -(defn analyse-jvm-program [analyse ?args ?body] +(defn analyse-jvm-program [analyse compile-token ?args ?body] (|let [[_module _name] ?args] (|do [=body (&/with-scope "" (&&env/with-local (str _module ";" _name) (&/V "lux;AppT" (&/T &type/List &type/Text)) - (&&/analyse-1 analyse (&/V "lux;AppT" (&/T &type/IO &type/Unit)) ?body)))] - (return (&/|list (&/V "jvm-program" =body)))))) + (&&/analyse-1 analyse (&/V "lux;AppT" (&/T &type/IO &type/Unit)) ?body))) + _ (compile-token (&/V "jvm-program" =body))] + (return (&/|list))))) diff --git a/src/lux/analyser/lux.clj b/src/lux/analyser/lux.clj index 4fb9d1533..c86df3027 100644 --- a/src/lux/analyser/lux.clj +++ b/src/lux/analyser/lux.clj @@ -163,7 +163,7 @@ ?name) ;; :let [_ (prn 'analyse-symbol/_1.1 r-module r-name)] endo-type (matchv ::M/objects [$def] - [["lux;ValueD" ?type]] + [["lux;ValueD" [?type _]]] (return ?type) [["lux;MacroD" _]] @@ -188,7 +188,7 @@ ((|do [[[r-module r-name] $def] (&&module/find-def ?module* ?name*) ;; :let [_ (prn 'analyse-symbol/_2.1.1 r-module r-name)] endo-type (matchv ::M/objects [$def] - [["lux;ValueD" ?type]] + [["lux;ValueD" [?type _]]] (return ?type) [["lux;MacroD" _]] @@ -282,7 +282,7 @@ macro-expansion #(-> macro (.apply ?args) (.apply %)) ;; :let [_ (prn 'MACRO-EXPAND|POST (str r-module ";" r-name))] :let [macro-expansion* (&/|map (partial with-cursor form-cursor) macro-expansion)] - ;; :let [_ (when (or (= "loop" r-name) + ;; :let [_ (when (or (= "<>" r-name) ;; ;; (= "struct" r-name) ;; ) ;; (->> (&/|map &/show-ast macro-expansion*) @@ -377,7 +377,7 @@ (|do [output (analyse-lambda** analyse exo-type ?self ?arg ?body)] (return (&/|list output)))) -(defn analyse-def [analyse ?name ?value] +(defn analyse-def [analyse compile-token ?name ?value] ;; (prn 'analyse-def/BEGIN ?name) ;; (when (= "PList/Dict" ?name) ;; (prn 'DEF ?name (&/show-ast ?value))) @@ -397,24 +397,17 @@ (return (&/|list))) [_] - (|do [=value-type (&&/expr-type =value) - :let [;; _ (prn 'analyse-def/END ?name) - _ (println 'DEF (str module-name ";" ?name)) - ;; _ (println) - def-data (cond (&type/type= &type/Type =value-type) - (&/V "lux;TypeD" nil) - - :else - (&/V "lux;ValueD" =value-type))] - _ (&&module/define module-name ?name def-data =value-type)] - (return (&/|list (&/V "def" (&/T ?name =value def-data)))))) + (do (println 'DEF (str module-name ";" ?name)) + (|do [_ (compile-token (&/V "def" (&/T ?name =value)))] + (return (&/|list))))) )))) -(defn analyse-declare-macro [analyse ?name] +(defn analyse-declare-macro [analyse compile-token ?name] (|do [module-name &/get-module-name] - (return (&/|list (&/V "declare-macro" (&/T module-name ?name)))))) + (|do [_ (compile-token (&/V "declare-macro" (&/T module-name ?name)))] + (return (&/|list))))) -(defn analyse-import [analyse compile-module ?path] +(defn analyse-import [analyse compile-module compile-token ?path] (|do [module-name &/get-module-name _ (if (= module-name ?path) (fail (str "[Analyser Error] Module can't import itself: " ?path)) @@ -426,12 +419,12 @@ _ (&/when% (not already-compiled?) (compile-module ?path))] (return (&/|list)))))) -(defn analyse-export [analyse name] +(defn analyse-export [analyse compile-token name] (|do [module-name &/get-module-name _ (&&module/export module-name name)] (return (&/|list)))) -(defn analyse-alias [analyse ex-alias ex-module] +(defn analyse-alias [analyse compile-token ex-alias ex-module] (|do [module-name &/get-module-name _ (&&module/alias module-name ex-alias ex-module)] (return (&/|list)))) diff --git a/src/lux/analyser/module.clj b/src/lux/analyser/module.clj index 68cdc4747..327dad27f 100644 --- a/src/lux/analyser/module.clj +++ b/src/lux/analyser/module.clj @@ -72,7 +72,7 @@ [[_ ["lux;MacroD" _]]] (return* state &type/Macro) - [[_ ["lux;ValueD" _type]]] + [[_ ["lux;ValueD" [_type _]]]] (return* state _type) [[_ ["lux;AliasD" [?r-module ?r-name]]]] @@ -159,7 +159,7 @@ (if-let [$module (->> state (&/get$ &/$MODULES) (&/|get module) (&/get$ $DEFS))] (if-let [$def (&/|get name $module)] (matchv ::M/objects [$def] - [[exported? ["lux;ValueD" ?type]]] + [[exported? ["lux;ValueD" [?type _]]]] ((|do [_ (&type/check &type/Macro ?type) ^ClassLoader loader &/loader :let [macro (-> (.loadClass loader (str (&host/->module-class module) "." (&/normalize-name name))) @@ -181,7 +181,7 @@ [[_ ["lux;MacroD" _]]] (fail* (str "[Analyser Error] Can't re-declare a macro: " (str module &/+name-separator+ name))) - [[_ ["lux;TypeD" _]]] + [[_ _]] (fail* (str "[Analyser Error] Definition does not have macro type: " (str module &/+name-separator+ name)))) (fail* (str "[Analyser Error] Definition does not exist: " (str module &/+name-separator+ name)))) (fail* (str "[Analyser Error] Module does not exist: " module))))) diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj index b88bb9c0a..4c12f9519 100644 --- a/src/lux/compiler.clj +++ b/src/lux/compiler.clj @@ -326,8 +326,8 @@ (defn ^:private compile-statement [syntax] (matchv ::M/objects [syntax] - [["def" [?name ?body ?def-data]]] - (&&lux/compile-def compile-expression ?name ?body ?def-data) + [["def" [?name ?body]]] + (&&lux/compile-def compile-expression ?name ?body) [["declare-macro" [?module ?name]]] (&&lux/compile-declare-macro compile-expression ?module ?name) @@ -341,6 +341,26 @@ [["jvm-class" [?name ?super-class ?interfaces ?fields ?methods]]] (&&host/compile-jvm-class compile-expression ?name ?super-class ?interfaces ?fields ?methods))) +(defn ^:private compile-token [syntax] + (matchv ::M/objects [syntax] + [["def" [?name ?body]]] + (&&lux/compile-def compile-expression ?name ?body) + + [["declare-macro" [?module ?name]]] + (&&lux/compile-declare-macro compile-expression ?module ?name) + + [["jvm-program" ?body]] + (&&host/compile-jvm-program compile-expression ?body) + + [["jvm-interface" [?name ?supers ?methods]]] + (&&host/compile-jvm-interface compile-expression ?name ?supers ?methods) + + [["jvm-class" [?name ?super-class ?interfaces ?fields ?methods]]] + (&&host/compile-jvm-class compile-expression ?name ?super-class ?interfaces ?fields ?methods) + + [_] + (compile-expression syntax))) + (defn ^:private eval! [expr] (&/with-eval (|do [module &/get-module-name @@ -378,8 +398,7 @@ :let [file-hash (hash file-content)]] (if (&&cache/cached? name) (&&cache/load name file-hash compile-module) - (let [compiler-step (|do [analysis+ (&optimizer/optimize eval! compile-module)] - (&/map% compile-statement analysis+))] + (let [compiler-step (&optimizer/optimize eval! compile-module compile-token)] (|do [module-exists? (&a-module/exists? name)] (if module-exists? (fail "[Compiler Error] Can't redefine a module!") diff --git a/src/lux/compiler/base.clj b/src/lux/compiler/base.clj index 28339c162..74e5625b3 100644 --- a/src/lux/compiler/base.clj +++ b/src/lux/compiler/base.clj @@ -27,7 +27,7 @@ (java.lang.reflect Field))) ;; [Constants] -(def ^String version "0.2") +(def ^String version "0.3") (def ^String input-dir "source") (def ^String output-dir "target/jvm") (def ^String output-package (str output-dir "/program.jar")) diff --git a/src/lux/compiler/cache.clj b/src/lux/compiler/cache.clj index 45513d0a5..565eae898 100644 --- a/src/lux/compiler/cache.clj +++ b/src/lux/compiler/cache.clj @@ -26,6 +26,7 @@ ;; [Utils] (defn ^:private read-file [^File file] + "(-> File (Array Byte))" (with-open [reader (io/input-stream file)] (let [length (.length file) buffer (byte-array length)] @@ -33,6 +34,7 @@ buffer))) (defn ^:private clean-file [^File file] + "(-> File (,))" (if (.isDirectory file) (do (doseq [f (seq (.listFiles file))] (clean-file f)) @@ -40,6 +42,7 @@ (.delete file))) (defn ^:private get-field [^String field-name ^Class class] + "(-> Text Class Object)" (-> class ^Field (.getField field-name) (.get nil))) ;; [Resources] @@ -66,6 +69,7 @@ nil)) (defn load [module module-hash compile-module] + "(-> Text Int (-> Text (Lux (,))) (Lux Bool))" (|do [loader &/loader !classes &/classes already-loaded? (&a-module/exists? module) @@ -112,15 +116,19 @@ ;; _ (prn '[_exported? _name _ann] [_exported? _name _ann]) ] (|do [_ (case _ann - "T" (&a-module/define module _name (&/V "lux;TypeD" nil) &type/Type) - "M" (|do [_ (&a-module/define module _name (&/V "lux;ValueD" &type/Macro) &type/Macro)] - (&a-module/declare-macro module _name)) + "T" (let [def-class (&&/load-class! loader (str module* "." (&/normalize-name _name))) + def-value (get-field "_datum" def-class)] + (&a-module/define module _name (&/V "lux;TypeD" def-value) &type/Type)) + "M" (let [def-class (&&/load-class! loader (str module* "." (&/normalize-name _name))) + def-value (get-field "_datum" def-class)] + (|do [_ (&a-module/define module _name (&/V "lux;ValueD" (&/T &type/Macro def-value)) &type/Macro)] + (&a-module/declare-macro module _name))) "V" (let [def-class (&&/load-class! loader (str module* "." (&/normalize-name _name))) ;; _ (println "Fetching _meta" module _name (str module* "." (&/normalize-name _name)) def-class) - def-type (get-field "_meta" def-class)] - (matchv ::M/objects [def-type] - [["lux;ValueD" _def-type]] - (&a-module/define module _name def-type _def-type))) + def-meta (get-field "_meta" def-class)] + (matchv ::M/objects [def-meta] + [["lux;ValueD" [def-type _]]] + (&a-module/define module _name def-meta def-type))) ;; else (let [[_ __module __name] (re-find #"^A(.*);(.*)$" _ann)] (|do [__type (&a-module/def-type __module __name)] diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj index fc0cce31f..906cc1ca8 100644 --- a/src/lux/compiler/case.clj +++ b/src/lux/compiler/case.clj @@ -47,7 +47,7 @@ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Long") (.visitInsn Opcodes/DUP) (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Long" "longValue" "()J") - (.visitLdcInsn ?value) + (.visitLdcInsn (long ?value)) (.visitInsn Opcodes/LCMP) (.visitJumpInsn Opcodes/IFNE $else) (.visitInsn Opcodes/POP) @@ -58,7 +58,7 @@ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Double") (.visitInsn Opcodes/DUP) (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Double" "doubleValue" "()D") - (.visitLdcInsn ?value) + (.visitLdcInsn (double ?value)) (.visitInsn Opcodes/DCMPL) (.visitJumpInsn Opcodes/IFNE $else) (.visitInsn Opcodes/POP) diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj index b1023689e..def5220f7 100644 --- a/src/lux/compiler/lux.clj +++ b/src/lux/compiler/lux.clj @@ -136,33 +136,38 @@ ?args)] (return nil))) -(defn ^:private compile-def-type [compile ?body ?def-data] +(defn ^:private compile-def-type [compile current-class ?body def-type] (|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 - )] + (matchv ::M/objects [def-type] + ["type"] + (|do [:let [;; ?type* (&&type/->analysis ?type) + _ (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 + (.visitFieldInsn Opcodes/GETSTATIC current-class "_datum" "Ljava/lang/Object;") + ;; (.visitInsn Opcodes/ACONST_NULL) ;; VVIN + (.visitInsn Opcodes/AASTORE) ;; V + )] + ;; _ (compile ?type*) + ;; :let [_ (.visitInsn **writer** Opcodes/AASTORE)] + ] (return nil)) - [["lux;ValueD" _]] + ["value"] (|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-type (matchv ::M/objects [?body] + [[["ann" [?def-value ?type-expr]] ?def-type]] + ?type-expr - [[?def-value ?def-type]] - (&/T ?body (&&type/->analysis ?def-type)))] + [[?def-value ?def-type]] + (&&type/->analysis ?def-type))] (|do [:let [_ (doto **writer** (.visitLdcInsn (int 2)) ;; S (.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object") ;; V @@ -173,13 +178,31 @@ (.visitInsn Opcodes/DUP) ;; VV (.visitLdcInsn (int 1)) ;; VVI )] + :let [_ (doto **writer** + (.visitLdcInsn (int 2)) ;; S + (.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object") ;; V + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 0)) ;; VVI + )] _ (compile ?def-type) + :let [_ (.visitInsn **writer** Opcodes/AASTORE)] + :let [_ (doto **writer** + (.visitInsn Opcodes/DUP) ;; VV + (.visitLdcInsn (int 1)) ;; VVI + (.visitFieldInsn Opcodes/GETSTATIC current-class "_datum" "Ljava/lang/Object;") + (.visitInsn Opcodes/AASTORE))] :let [_ (.visitInsn **writer** Opcodes/AASTORE)]] (return nil))) ))) -(defn compile-def [compile ?name ?body ?def-data] - (|do [^ClassWriter *writer* &/get-writer +(defn compile-def [compile ?name ?body] + (|do [=value-type (&a/expr-type ?body) + :let [def-type (cond (&type/type= &type/Type =value-type) + "type" + + :else + "value")] + ^ClassWriter *writer* &/get-writer module-name &/get-module-name :let [datum-sig "Ljava/lang/Object;" def-name (&/normalize-name ?name) @@ -198,7 +221,7 @@ :let [_ (.visitCode **writer**)] _ (compile ?body) :let [_ (.visitFieldInsn **writer** Opcodes/PUTSTATIC current-class "_datum" datum-sig)] - _ (compile-def-type compile ?body ?def-data) + _ (compile-def-type compile current-class ?body def-type) :let [_ (.visitFieldInsn **writer** Opcodes/PUTSTATIC current-class "_meta" datum-sig)] :let [_ (doto **writer** (.visitInsn Opcodes/RETURN) @@ -206,7 +229,10 @@ (.visitEnd))]] (return nil))) :let [_ (.visitEnd *writer*)] - _ (&&/save-class! def-name (.toByteArray =class))] + _ (&&/save-class! def-name (.toByteArray =class)) + class-loader &/loader + :let [def-class (&&/load-class! class-loader (&host/->class-name current-class))] + _ (&a-module/define module-name ?name (-> def-class (.getField "_meta") (.get nil)) =value-type)] (return nil))) (defn compile-ann [compile *type* ?value-ex ?type-ex] diff --git a/src/lux/compiler/type.clj b/src/lux/compiler/type.clj index a92911444..01141f8e4 100644 --- a/src/lux/compiler/type.clj +++ b/src/lux/compiler/type.clj @@ -75,7 +75,7 @@ (variant$ "lux;AllT" (tuple$ (&/|list (matchv ::M/objects [?env] [["lux;None" _]] - (variant$ "lux;Some" (tuple$ (&/|list))) + (variant$ "lux;None" (tuple$ (&/|list))) [["lux;Some" ??env]] (variant$ "lux;Some" diff --git a/src/lux/host.clj b/src/lux/host.clj index 906e3c714..91582c526 100644 --- a/src/lux/host.clj +++ b/src/lux/host.clj @@ -40,6 +40,9 @@ (defn ^String ->class [class] (string/replace class #"\." "/")) +(defn ^String ->class-name [module] + (string/replace module #"/" ".")) + (defn ^String ->module-class [module-name] (string/replace module-name #"/" module-separator)) diff --git a/src/lux/optimizer.clj b/src/lux/optimizer.clj index 5056a09e0..65dc4eb0d 100644 --- a/src/lux/optimizer.clj +++ b/src/lux/optimizer.clj @@ -22,5 +22,5 @@ ;; Local var aliasing. ;; [Exports] -(defn optimize [eval! compile-module] - (&analyser/analyse eval! compile-module)) +(defn optimize [eval! compile-module compile-token] + (&analyser/analyse eval! compile-module compile-token)) diff --git a/src/lux/type.clj b/src/lux/type.clj index e3255ac5c..f40996d7e 100644 --- a/src/lux/type.clj +++ b/src/lux/type.clj @@ -142,8 +142,8 @@ (def DefData* (fAll "lux;DefData'" "" - (&/V "lux;VariantT" (&/|list (&/T "lux;TypeD" Unit) - (&/T "lux;ValueD" Type) + (&/V "lux;VariantT" (&/|list (&/T "lux;TypeD" Type) + (&/T "lux;ValueD" (&/V "lux;TupleT" (&/|list Type Unit))) (&/T "lux;MacroD" (&/V "lux;BoundT" "")) (&/T "lux;AliasD" Ident))))) |