aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/translation.lux
diff options
context:
space:
mode:
Diffstat (limited to 'new-luxc/source/luxc/lang/translation.lux')
-rw-r--r--new-luxc/source/luxc/lang/translation.lux179
1 files changed, 179 insertions, 0 deletions
diff --git a/new-luxc/source/luxc/lang/translation.lux b/new-luxc/source/luxc/lang/translation.lux
new file mode 100644
index 000000000..4fcc3ccb2
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation.lux
@@ -0,0 +1,179 @@
+(;module:
+ lux
+ (lux (control [monad #+ do])
+ (concurrency ["T" task])
+ (data ["e" error]
+ [text "text/" Hash<Text>]
+ text/format
+ (coll [dict]))
+ [meta]
+ [host]
+ [io]
+ (world [file #+ File]))
+ (luxc ["&" base]
+ [";L" host]
+ ["&;" io]
+ ["&;" module]
+ ["&;" eval]
+ (lang ["&;" syntax]
+ (analysis [";A" expression]
+ [";A" common])
+ (synthesis [";S" expression])
+ (translation [";T" runtime]
+ [";T" statement]
+ [";T" common]
+ [";T" expression]
+ [";T" eval]))
+ ))
+
+(def: analyse
+ (&;Analyser)
+ (expressionA;analyser &eval;eval))
+
+(def: (generate code)
+ (-> Code (Meta Unit))
+ (case code
+ (^ [_ (#;Form (list [_ (#;Text "lux def")]
+ [_ (#;Symbol ["" def-name])]
+ valueC
+ metaC))])
+ (do meta;Monad<Meta>
+ [[_ metaA] (&;with-scope
+ (&;with-expected-type Code
+ (analyse metaC)))
+ metaI (expressionT;generate (expressionS;synthesize metaA))
+ metaV (evalT;eval metaI)
+ [_ valueT valueA] (&;with-scope
+ (if (meta;type? (:! Code metaV))
+ (&;with-expected-type Type
+ (do @
+ [valueA (analyse valueC)]
+ (wrap [Type valueA])))
+ (commonA;with-unknown-type
+ (analyse valueC))))
+ valueI (expressionT;generate (expressionS;synthesize valueA))
+ _ (&;with-scope
+ (statementT;generate-def def-name valueT valueI metaI (:! Code metaV)))]
+ (wrap []))
+
+ (^ [_ (#;Form (list [_ (#;Text "lux program")]
+ [_ (#;Symbol ["" program-args])]
+ programC))])
+ (do meta;Monad<Meta>
+ [[_ programA] (&;with-scope
+ (&;with-expected-type (type (io;IO Unit))
+ (analyse programC)))
+ programI (expressionT;generate (expressionS;synthesize programA))]
+ (statementT;generate-program program-args programI))
+
+ _
+ (&;fail (format "Unrecognized statement: " (%code code)))))
+
+(def: (exhaust action)
+ (All [a] (-> (Meta a) (Meta Unit)))
+ (do meta;Monad<Meta>
+ [result action]
+ (exhaust action)))
+
+(def: prelude Text "lux")
+
+(def: (with-active-compilation [module-name file-name source-code] action)
+ (All [a] (-> [Text Text Text] (Meta a) (Meta a)))
+ (do meta;Monad<Meta>
+ [#let [init-cursor [file-name +1 +0]]
+ output (&;with-source-code [init-cursor +0 source-code]
+ action)
+ _ (&module;flag-compiled! module-name)]
+ (wrap output)))
+
+(def: parse
+ (Meta Code)
+ (function [compiler]
+ (case (&syntax;parse (get@ #;source compiler))
+ (#e;Error error)
+ (#e;Error error)
+
+ (#e;Success [source' output])
+ (#e;Success [(set@ #;source source' compiler)
+ output]))))
+
+(def: (generate-module source-dirs module-name target-dir compiler)
+ (-> (List File) Text File Compiler (T;Task Compiler))
+ (do T;Monad<Task>
+ [_ (&io;prepare-module target-dir module-name)
+ [file-name file-content] (&io;read-module source-dirs module-name)
+ #let [module-hash (text/hash file-content)]]
+ (case (meta;run' compiler
+ (do meta;Monad<Meta>
+ [[_ artifacts _] (&module;with-module module-hash module-name
+ (commonT;with-artifacts
+ (with-active-compilation [module-name
+ file-name
+ file-content]
+ (exhaust
+ (do @
+ [code parse
+ #let [[cursor _] code]]
+ (&;with-cursor cursor
+ (generate code)))))))]
+ (wrap artifacts)
+ ## (&module;generate-descriptor module-name)
+ ))
+ (#e;Success [compiler artifacts ## module-descriptor
+ ])
+ (do @
+ [## _ (&io;write-module module-name module-descriptor)
+ _ (monad;map @ (function [[class-name class-bytecode]]
+ (&io;write-file target-dir class-name class-bytecode))
+ (dict;entries artifacts))]
+ (wrap compiler))
+
+ (#e;Error error)
+ (T;fail error))))
+
+(def: init-cursor Cursor ["" +1 +0])
+
+(def: #export init-type-context
+ Type-Context
+ {#;ex-counter +0
+ #;var-counter +0
+ #;var-bindings (list)})
+
+(def: #export init-info
+ Info
+ {#;target "JVM"
+ #;version &;version
+ #;mode #;Build})
+
+(def: #export (init-compiler host)
+ (-> commonT;Host Compiler)
+ {#;info init-info
+ #;source [init-cursor +0 ""]
+ #;cursor init-cursor
+ #;current-module #;None
+ #;modules (list)
+ #;scopes (list)
+ #;type-context init-type-context
+ #;expected #;None
+ #;seed +0
+ #;scope-type-vars (list)
+ #;host (:! Void host)})
+
+(def: #export (generate-program program target sources)
+ (-> Text File (List File) (T;Task Unit))
+ (do T;Monad<Task>
+ [compiler (|> (case (runtimeT;generate (init-compiler (io;run hostL;init-host)))
+ (#e;Error error)
+ (T;fail error)
+
+ (#e;Success [compiler [runtime-bc function-bc]])
+ (do @
+ [_ (&io;prepare-target target)
+ _ (&io;write-file target hostL;runtime-class runtime-bc)
+ _ (&io;write-file target hostL;function-class function-bc)]
+ (wrap compiler)))
+ (: (T;Task Compiler))
+ (:: @ map (generate-module sources prelude target)) (:: @ join)
+ (:: @ map (generate-module sources program target)) (:: @ join))
+ #let [_ (log! "Compilation complete!")]]
+ (wrap [])))