diff options
Diffstat (limited to 'stdlib/source/lux/target/js.lux')
-rw-r--r-- | stdlib/source/lux/target/js.lux | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/stdlib/source/lux/target/js.lux b/stdlib/source/lux/target/js.lux new file mode 100644 index 000000000..756530817 --- /dev/null +++ b/stdlib/source/lux/target/js.lux @@ -0,0 +1,397 @@ +(.module: + [lux (#- Code or and function if cond undefined for comment false true not) + [control + [pipe (#+ case>)]] + [data + ["." text + format] + [collection + ["." list ("#@." functor fold)]]] + [macro + ["." template]] + [type + abstract]]) + +(def: argument (text.enclose ["(" ")"])) +(def: element (text.enclose ["[" "]"])) + +(abstract: #export (Code brand) + {} + + Text + + (def: #export code + (-> (Code Any) Text) + (|>> :representation)) + + (template [<type> <brand> <super>+] + [(abstract: #export (<brand> brand) {} Any) + (`` (type: #export <type> (|> Any <brand> (~~ (template.splice <super>+)))))] + + [Expression Expression' [Code]] + [Computation Computation' [Expression' Code]] + [Location Location' [Computation' Expression' Code]] + [Statement Statement' [Code]] + ) + + (template [<type> <brand> <super>+] + [(abstract: #export <brand> {} Any) + (`` (type: #export <type> (|> <brand> (~~ (template.splice <super>+)))))] + + [Var Var' [Location' Computation' Expression' Code]] + [Access Access' [Location' Computation' Expression' Code]] + [Loop Loop' [Statement' Code]] + [Label Label' [Code]] + ) + + (template [<name> <literal>] + [(def: #export <name> Computation (|> <literal> ..argument :abstraction))] + + [null "null"] + [undefined "undefined"] + [false "false"] + [true "true"] + [positive-infinity "Infinity"] + [negative-infinity "-Infinity"] + [not-a-number "NaN"] + ) + + (def: #export boolean + (-> Bit Computation) + (|>> (case> + #0 ..false + #1 ..true))) + + (def: #export number + (-> Frac Computation) + (|>> %f ..argument :abstraction)) + + (def: sanitize + (-> Text Text) + (`` (|>> (~~ (template [<find> <replace>] + [(text.replace-all <find> <replace>)] + + ["\" "\\"] + [text.tab "\t"] + [text.vertical-tab "\v"] + [text.null "\0"] + [text.back-space "\b"] + [text.form-feed "\f"] + [text.new-line "\n"] + [text.carriage-return "\r"] + [text.double-quote (format "\" text.double-quote)] + )) + ))) + + (def: #export string + (-> Text Computation) + (|>> ..sanitize + (text.enclose [text.double-quote text.double-quote]) + :abstraction)) + + (def: argument-separator ", ") + (def: field-separator ": ") + (def: statement-suffix ";") + + (def: #export array + (-> (List Expression) Computation) + (|>> (list@map ..code) + (text.join-with ..argument-separator) + ..element + :abstraction)) + + (def: #export var + (-> Text Var) + (|>> :abstraction)) + + (def: #export (at index array-or-object) + (-> Expression Expression Access) + (|> (format (:representation array-or-object) (..element (:representation index))) + ..argument + :abstraction)) + + (def: #export (the field object) + (-> Text Expression Access) + (:abstraction (format (:representation object) "." field))) + + (def: #export (apply/* function inputs) + (-> Expression (List Expression) Computation) + (|> inputs + (list@map ..code) + (text.join-with ..argument-separator) + ..argument + (format (:representation function)) + :abstraction)) + + (def: #export (do method inputs object) + (-> Text (List Expression) Expression Computation) + (apply/* (..the method object) inputs)) + + (def: #export object + (-> (List [Text Expression]) Computation) + (|>> (list@map (.function (_ [key val]) + (format (:representation (..string key)) ..field-separator (:representation val)))) + (text.join-with ..argument-separator) + (text.enclose ["{" "}"]) + ..argument + :abstraction)) + + (def: #export (, pre post) + (-> Expression Expression Computation) + (|> (format (:representation pre) ", " (:representation post)) + ..argument + :abstraction)) + + (def: #export (then pre post) + (-> Statement Statement Statement) + (:abstraction (format (:representation pre) + text.new-line + (:representation post)))) + + ## (def: indent + ## (-> Text Text) + ## (text.replace-all text.new-line (format text.new-line text.tab))) + + (def: block + (-> Statement Text) + (let [close (format text.new-line "}")] + (|>> :representation + (format text.new-line) + ## ..indent + (text.enclose ["{" + close])))) + + (def: #export (function name inputs body) + (-> Var (List Var) Statement Computation) + (|> body + ..block + (format "function " (:representation name) + (|> inputs + (list@map ..code) + (text.join-with ..argument-separator) + ..argument) + " ") + ..argument + :abstraction)) + + (def: #export (closure inputs body) + (-> (List Var) Statement Computation) + (|> body + ..block + (format "function" + (|> inputs + (list@map ..code) + (text.join-with ..argument-separator) + ..argument) + " ") + ..argument + :abstraction)) + + (template [<name> <op>] + [(def: #export (<name> param subject) + (-> Expression Expression Computation) + (|> (format (:representation subject) " " <op> " " (:representation param)) + ..argument + :abstraction))] + + [= "==="] + [< "<"] + [<= "<="] + [> ">"] + [>= ">="] + + [+ "+"] + [- "-"] + [* "*"] + [/ "/"] + [% "%"] + + [left-shift "<<"] + [arithmetic-right-shift ">>"] + [logic-right-shift ">>>"] + + [or "||"] + [and "&&"] + [bit-xor "^"] + [bit-or "|"] + [bit-and "&"] + ) + + (template [<name> <prefix>] + [(def: #export <name> + (-> Expression Computation) + (|>> :representation (text.prefix <prefix>) ..argument :abstraction))] + + [not "!"] + [bit-not "~"] + [negate "-"] + ) + + (template [<name> <input> <format>] + [(def: #export (<name> value) + {#.doc "A 32-bit integer expression."} + (-> <input> Computation) + (:abstraction (..argument (format (<format> value) "|0"))))] + + [to-i32 Expression :representation] + [i32 Int %i] + ) + + (def: #export (? test then else) + (-> Expression Expression Expression Computation) + (|> (format (:representation test) + " ? " (:representation then) + " : " (:representation else)) + ..argument + :abstraction)) + + (def: #export type-of + (-> Expression Computation) + (|>> :representation + (format "typeof ") + ..argument + :abstraction)) + + (def: #export (new constructor inputs) + (-> Expression (List Expression) Computation) + (|> (format "new " (:representation constructor) + (|> inputs + (list@map ..code) + (text.join-with ..argument-separator) + ..argument)) + ..argument + :abstraction)) + + (def: #export statement + (-> Expression Statement) + (|>> :representation (text.suffix ..statement-suffix) :abstraction)) + + (def: #export use-strict + Statement + (:abstraction (format text.double-quote "use strict" text.double-quote ..statement-suffix))) + + (def: #export (declare name) + (-> Var Statement) + (:abstraction (format "var " (:representation name) ..statement-suffix))) + + (def: #export (define name value) + (-> Var Expression Statement) + (:abstraction (format "var " (:representation name) " = " (:representation value) ..statement-suffix))) + + (def: #export (set name value) + (-> Location Expression Statement) + (:abstraction (format (:representation name) " = " (:representation value) ..statement-suffix))) + + (def: #export (throw message) + (-> Expression Statement) + (:abstraction (format "throw " (:representation message) ..statement-suffix))) + + (def: #export (return value) + (-> Expression Statement) + (:abstraction (format "return " (:representation value) ..statement-suffix))) + + (def: #export (delete value) + (-> Location Statement) + (:abstraction (format "delete " (:representation value) ..statement-suffix))) + + (def: #export (if test then! else!) + (-> Expression Statement Statement Statement) + (:abstraction (format "if(" (:representation test) ") " + (..block then!) + " else " + (..block else!)))) + + (def: #export (when test then!) + (-> Expression Statement Statement) + (:abstraction (format "if(" (:representation test) ") " + (..block then!)))) + + (def: #export (while test body) + (-> Expression Statement Loop) + (:abstraction (format "while(" (:representation test) ") " + (..block body)))) + + (def: #export (do-while test body) + (-> Expression Statement Loop) + (:abstraction (format "do " (..block body) + " while(" (:representation test) ")" ..statement-suffix))) + + (def: #export (try body [exception catch]) + (-> Statement [Var Statement] Statement) + (:abstraction (format "try " + (..block body) + " catch(" (:representation exception) ") " + (..block catch)))) + + (def: #export (for var init condition update iteration) + (-> Var Expression Expression Expression Statement Loop) + (:abstraction (format "for(" (:representation (..define var init)) + " " (:representation condition) + ..statement-suffix " " (:representation update) + ")" + (..block iteration)))) + + (def: #export label + (-> Text Label) + (|>> :abstraction)) + + (def: #export (with-label label loop) + (-> Label Loop Statement) + (:abstraction (format (:representation label) ": " (:representation loop)))) + + (template [<keyword> <0> <1>] + [(def: #export <0> + Statement + (:abstraction (format <keyword> ..statement-suffix))) + + (def: #export (<1> label) + (-> Label Statement) + (:abstraction (format <keyword> " " (:representation label) ..statement-suffix)))] + + ["break" break break-at] + ["continue" continue continue-at] + ) + + (template [<name> <js>] + [(def: #export <name> + (-> Location Expression) + (|>> :representation + (text.suffix <js>) + :abstraction))] + + [++ "++"] + [-- "--"] + ) + + (def: #export (comment commentary on) + (All [kind] (-> Text (Code kind) (Code kind))) + (:abstraction (format "/* " commentary " */" " " (:representation on)))) + ) + +(def: #export (cond clauses else!) + (-> (List [Expression Statement]) Statement Statement) + (list@fold (.function (_ [test then!] next!) + (..if test then! next!)) + else! + (list.reverse clauses))) + +(template [<apply> <arg>+ <type>+ <function>+] + [(`` (def: #export (<apply> function) + (-> Expression (~~ (template.splice <type>+)) Computation) + (.function (_ (~~ (template.splice <arg>+))) + (..apply/* function (list (~~ (template.splice <arg>+))))))) + + (`` (template [<definition> <function>] + [(def: #export <definition> (<apply> (..var <function>)))] + + (~~ (template.splice <function>+))))] + + [apply/1 [_0] [Expression] + [[not-a-number? "isNaN"]]] + + [apply/2 [_0 _1] [Expression Expression] + []] + + [apply/3 [_0 _1 _2] [Expression Expression Expression] + []] + ) |