aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/translation/lua.lux
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--new-luxc/source/luxc/lang/translation/lua.lux228
1 files changed, 228 insertions, 0 deletions
diff --git a/new-luxc/source/luxc/lang/translation/lua.lux b/new-luxc/source/luxc/lang/translation/lua.lux
new file mode 100644
index 000000000..115471cbe
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/lua.lux
@@ -0,0 +1,228 @@
+(.module:
+ lux
+ (lux (control ["ex" exception #+ exception:]
+ pipe
+ [monad #+ do])
+ (data [bit]
+ [maybe]
+ ["e" error #+ Error]
+ [text "text/" Eq<Text>]
+ text/format
+ (coll [array]))
+ [macro]
+ [io #+ IO Process io]
+ [host #+ class: interface: object]
+ (world [file #+ File]))
+ (luxc [lang]
+ (lang [".L" variable #+ Register]
+ (host [lua #+ Lua Expression Statement]))
+ [".C" io]))
+
+(host.import java/lang/Object)
+
+(host.import java/lang/String
+ (getBytes [String] #try (Array byte)))
+
+(host.import java/lang/CharSequence)
+
+(host.import java/lang/Appendable
+ (append [CharSequence] Appendable))
+
+(host.import java/lang/StringBuilder
+ (new [])
+ (toString [] String))
+
+(host.import net/sandius/rembulan/StateContext)
+
+(host.import net/sandius/rembulan/impl/StateContexts
+ (#static newDefaultInstance [] StateContext))
+
+(host.import net/sandius/rembulan/env/RuntimeEnvironment)
+
+(host.import net/sandius/rembulan/env/RuntimeEnvironments
+ (#static system [] RuntimeEnvironment))
+
+(host.import net/sandius/rembulan/Table)
+
+(host.import net/sandius/rembulan/lib/StandardLibrary
+ (#static in [RuntimeEnvironment] StandardLibrary)
+ (installInto [StateContext] Table))
+
+(host.import net/sandius/rembulan/Variable
+ (new [Object]))
+
+(host.import net/sandius/rembulan/runtime/LuaFunction)
+
+(host.import net/sandius/rembulan/load/ChunkLoader
+ (loadTextChunk [Variable String String] LuaFunction))
+
+(host.import net/sandius/rembulan/compiler/CompilerChunkLoader
+ (#static of [String] CompilerChunkLoader))
+
+(host.import net/sandius/rembulan/exec/DirectCallExecutor
+ (#static newExecutor [] DirectCallExecutor)
+ (call [StateContext Object (Array Object)] (Array Object)))
+
+(type: #export Anchor [Text Register])
+
+(type: #export Host
+ {#context [Text Nat]
+ #anchor (Maybe Anchor)
+ #interpreter (-> Text (Error Top))
+ #module-buffer (Maybe StringBuilder)
+ #program-buffer StringBuilder})
+
+(def: #export init
+ (IO Host)
+ (io {#context ["" +0]
+ #anchor #.None
+ #interpreter (let [runtime-env (RuntimeEnvironments::system [])
+ std-lib (StandardLibrary::in [runtime-env])
+ state-context (StateContexts::newDefaultInstance [])
+ table (StandardLibrary::installInto [state-context] std-lib)
+ variable (Variable::new [table])
+ loader (CompilerChunkLoader::of ["_lux_definition"])
+ executor (DirectCallExecutor::newExecutor [])]
+ (function [code]
+ (let [lua-function (ChunkLoader::loadTextChunk [variable "lux compilation" code]
+ loader)]
+ ("lux try" (io (DirectCallExecutor::call [state-context (:! Object lua-function) (array.new +0)]
+ executor))))))
+ #module-buffer #.None
+ #program-buffer (StringBuilder::new [])}))
+
+(def: #export lua-module-name Text "module.lua")
+
+(def: #export init-module-buffer
+ (Meta Unit)
+ (function [compiler]
+ (#e.Success [(update@ #.host
+ (|>> (:! Host)
+ (set@ #module-buffer (#.Some (StringBuilder::new [])))
+ (:! Void))
+ compiler)
+ []])))
+
+(exception: #export No-Active-Module-Buffer)
+(exception: #export Cannot-Execute)
+
+(def: #export (with-sub-context expr)
+ (All [a] (-> (Meta a) (Meta [Text a])))
+ (function [compiler]
+ (let [old (:! Host (get@ #.host compiler))
+ [old-name old-sub] (get@ #context old)
+ new-name (format old-name "___" (%i (nat-to-int old-sub)))]
+ (case (expr (set@ #.host
+ (:! Void (set@ #context [new-name +0] old))
+ compiler))
+ (#e.Success [compiler' output])
+ (#e.Success [(update@ #.host
+ (|>> (:! Host)
+ (set@ #context [old-name (n/inc old-sub)])
+ (:! Void))
+ compiler')
+ [new-name output]])
+
+ (#e.Error error)
+ (#e.Error error)))))
+
+(def: #export context
+ (Meta Text)
+ (function [compiler]
+ (#e.Success [compiler
+ (|> (get@ #.host compiler)
+ (:! Host)
+ (get@ #context)
+ (let> [name sub]
+ name))])))
+
+(def: #export (with-anchor anchor expr)
+ (All [a] (-> Anchor (Meta a) (Meta a)))
+ (function [compiler]
+ (let [old (:! Host (get@ #.host compiler))]
+ (case (expr (set@ #.host
+ (:! Void (set@ #anchor (#.Some anchor) old))
+ compiler))
+ (#e.Success [compiler' output])
+ (#e.Success [(update@ #.host
+ (|>> (:! Host)
+ (set@ #anchor (get@ #anchor old))
+ (:! Void))
+ compiler')
+ output])
+
+ (#e.Error error)
+ (#e.Error error)))))
+
+(exception: #export No-Anchor)
+
+(def: #export anchor
+ (Meta Anchor)
+ (function [compiler]
+ (case (|> compiler (get@ #.host) (:! Host) (get@ #anchor))
+ (#.Some anchor)
+ (#e.Success [compiler anchor])
+
+ #.None
+ ((lang.throw No-Anchor "") compiler))))
+
+(def: #export module-buffer
+ (Meta StringBuilder)
+ (function [compiler]
+ (case (|> compiler (get@ #.host) (:! Host) (get@ #module-buffer))
+ #.None
+ ((lang.fail (No-Active-Module-Buffer "")) compiler)
+
+ (#.Some module-buffer)
+ (#e.Success [compiler module-buffer]))))
+
+(def: #export program-buffer
+ (Meta StringBuilder)
+ (function [compiler]
+ (#e.Success [compiler (|> compiler (get@ #.host) (:! Host) (get@ #program-buffer))])))
+
+(def: (execute code)
+ (-> Expression (Meta Unit))
+ (function [compiler]
+ (let [interpreter (|> compiler (get@ #.host) (:! Host) (get@ #interpreter))]
+ (case (interpreter code)
+ (#e.Error error)
+ ((lang.fail (Cannot-Execute error)) compiler)
+
+ (#e.Success _)
+ (#e.Success [compiler []])))))
+
+(exception: #export Unknown-Member)
+
+(def: #export variant-tag-field "_lux_tag")
+(def: #export variant-flag-field "_lux_flag")
+(def: #export variant-value-field "_lux_value")
+
+(def: #export unit Text "\u0000")
+
+(def: #export (definition-name [module name])
+ (-> Ident Text)
+ (lang.normalize-name (format module "$" name)))
+
+(def: #export (save code)
+ (-> Lua (Meta Unit))
+ (do macro.Monad<Meta>
+ [module-buffer module-buffer
+ #let [_ (Appendable::append [(:! CharSequence code)]
+ module-buffer)]]
+ (execute code)))
+
+(def: #export (save-module! target)
+ (-> File (Meta (Process Unit)))
+ (do macro.Monad<Meta>
+ [module macro.current-module-name
+ module-buffer module-buffer
+ program-buffer program-buffer
+ #let [module-code (StringBuilder::toString [] module-buffer)
+ _ (Appendable::append [(:! CharSequence (format module-code "\n"))]
+ program-buffer)]]
+ (wrap (ioC.write target
+ (format (lang.normalize-name module) "/" lua-module-name)
+ (|> module-code
+ (String::getBytes ["UTF-8"])
+ e.assume)))))