(.module: [lux #- not or and function] (lux (data [text] text/format (coll [list "list/" Functor Fold])))) (type: #export Lua Text) (type: #export Expression Lua) (type: #export Statement Lua) (def: #export nil Expression "nil") (def: #export bool (-> Bool Expression) %b) (def: #export int (-> Int Expression) %i) (def: #export float (-> Frac Expression) %f) (def: #export (string value) (-> Text Expression) (%t value)) (def: #export (array elements) (-> (List Expression) Expression) (format "{" (text.join-with "," elements) "}")) (def: #export (nth idx array) (-> Expression Expression Expression) (format "(" array ")[" idx "]")) (def: #export (length array) (-> Expression Expression) (format "#(" array ")")) (def: #export (apply func args) (-> Expression (List Expression) Expression) (format func "(" (text.join-with "," args) ")")) (def: #export (method field table args) (-> Text Expression (List Expression) Expression) (format table ":" field "(" (text.join-with "," args) ")")) (def: #export (local! name value) (-> Text (Maybe Expression) Statement) (case value #.None (format "local " name ";") (#.Some value) (format "local " name " = " value ";"))) (def: #export (global! name value) (-> Text (Maybe Expression) Statement) (case value #.None (format name ";") (#.Some value) (format name " = " value ";"))) (def: #export (set! name value) (-> Text Expression Statement) (format name " = " value ";")) (def: #export (if! test then! else!) (-> Expression Statement Statement Statement) (format "if " test " then " then! " else " else! " end;")) (def: #export (when! test then!) (-> Expression Statement Statement) (format "if " test " then " then! " end;")) (def: #export (cond! clauses else!) (-> (List [Expression Statement]) Statement Statement) (list/fold (.function (_ [test then!] next!) (if! test then! next!)) else! (list.reverse clauses))) (def: #export (block! statements) (-> (List Statement) Statement) (text.join-with " " statements)) (def: #export (while! test body) (-> Expression Statement Statement) (format "while " test " do " body " end;")) (def: #export (for-in! vars source body) (-> (List Text) Expression Statement Statement) (format "for " (text.join-with "," vars) " in " source " do " body " end;")) (def: #export (for-step! var from to step body) (-> Text Expression Expression Expression Statement Statement) (format "for " var " = " from ", " to ", " step " do " body " end;")) (def: #export (error message) (-> Expression Expression) (apply "error" (list message))) (def: #export (return! value) (-> Expression Statement) (format "return " value ";")) (def: #export (function args body) (-> (List Text) Statement Expression) (format "(" (format "function " (format "(" (text.join-with ", " args) ")") " " body " end") ")")) (def: #export (function! name args body) (-> Text (List Text) Statement Expression) (format "function " name (format "(" (text.join-with ", " args) ")") " " body " end;")) (def: #export (table fields) (-> (List [Text Expression]) Expression) (format "{" (|> fields (list/map (.function (_ [key val]) (format key " = " val))) (text.join-with ", ")) "}")) (do-template [ ] [(def: #export ( param subject) (-> Expression Expression Expression) (format "(" subject " " " " param ")"))] [= "=="] [< "<"] [<= "<="] [> ">"] [>= ">="] [+ "+"] [- "-"] [* "*"] [/ "/"] [// "//"] [% "%"] ) (do-template [ ] [(def: #export ( param subject) (-> Expression Expression Expression) (format "(" param " " " " subject ")"))] [or "or"] [and "and"] [bit-or "|"] [bit-and "&"] [bit-xor "~"] ) (do-template [ ] [(def: #export ( param subject) (-> Expression Expression Expression) (format "(" subject " " " " param ")"))] [bit-shl "<<"] [bit-shr ">>"] ) (def: #export (not subject) (-> Expression Expression) (format "(not " subject ")"))