From f2c0473640e8029f27797f6ecf21662dddb0685b Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 24 Apr 2019 21:28:56 -0400 Subject: WIP: PHP compiler. --- stdlib/source/lux/host/php.lux | 444 +++++++++++++++++++++ stdlib/source/lux/host/ruby.lux | 8 +- .../tool/compiler/phase/extension/statement.lux | 4 +- .../source/lux/tool/compiler/phase/generation.lux | 8 +- .../lux/tool/compiler/phase/generation/php.lux | 60 +++ .../tool/compiler/phase/generation/php/case.lux | 250 ++++++++++++ .../compiler/phase/generation/php/extension.lux | 13 + .../phase/generation/php/extension/common.lux | 126 ++++++ .../compiler/phase/generation/php/function.lux | 104 +++++ .../tool/compiler/phase/generation/php/loop.lux | 47 +++ .../compiler/phase/generation/php/primitive.lux | 27 ++ .../compiler/phase/generation/php/reference.lux | 11 + .../tool/compiler/phase/generation/php/runtime.lux | 305 ++++++++++++++ .../compiler/phase/generation/php/structure.lux | 36 ++ .../phase/generation/python/extension/common.lux | 26 +- .../compiler/phase/generation/ruby/runtime.lux | 30 -- stdlib/source/program/compositor.lux | 3 +- stdlib/source/test/lux.lux | 3 + 18 files changed, 1448 insertions(+), 57 deletions(-) create mode 100644 stdlib/source/lux/host/php.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/case.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/extension.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/extension/common.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/function.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/loop.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/primitive.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/reference.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/runtime.lux create mode 100644 stdlib/source/lux/tool/compiler/phase/generation/php/structure.lux (limited to 'stdlib/source') diff --git a/stdlib/source/lux/host/php.lux b/stdlib/source/lux/host/php.lux new file mode 100644 index 000000000..286d8d397 --- /dev/null +++ b/stdlib/source/lux/host/php.lux @@ -0,0 +1,444 @@ +(.module: + [lux (#- Code static int if cond or and not comment for) + [control + [pipe (#+ case> cond> new>)]] + [data + [number + ["." frac]] + ["." text + format] + [collection + ["." list ("#@." functor fold)]]] + [macro + ["." template]] + [type + abstract]]) + +(def: input-separator ", ") +(def: statement-suffix ";") + +(def: nest + (-> Text Text) + (|>> (format text.new-line) + (text.replace-all text.new-line (format text.new-line text.tab)))) + +(def: block + (-> Text Text) + (|>> ..nest (text.enclose ["{" (format text.new-line "}")]))) + +(def: group + (-> Text Text) + (text.enclose ["(" ")"])) + +(abstract: #export (Code brand) + {} + + Text + + (def: #export manual + (-> Text Code) + (|>> :abstraction)) + + (def: #export code + (-> (Code Any) Text) + (|>> :representation)) + + (template [ ] + [(with-expansions [ (template.identifier [ "'"])] + (`` (abstract: #export ( brand) {} Any)) + (`` (type: #export ( brand) + ( ( brand)))))] + + [Expression Code] + [Computation Expression] + [Location Computation] + ) + + (template [ ] + [(with-expansions [ (template.identifier [ "'"])] + (`` (abstract: #export {} Any)) + (`` (type: #export ( ))))] + + [Literal Computation] + [Var Location] + [Constant Location] + [Global Location] + [Access Location] + [Statement Code] + ) + + (type: #export Argument + {#reference? Bit + #var Var}) + + (def: #export ; + (-> (Expression Any) Statement) + (|>> :representation + (text.suffix ..statement-suffix) + :abstraction)) + + (def: #export var + (-> Text Var) + (|>> (format "$") :abstraction)) + + (def: #export constant + (-> Text Constant) + (|>> :abstraction)) + + (def: #export null + Literal + (:abstraction "NULL")) + + (def: #export bool + (-> Bit Literal) + (|>> (case> #0 "false" + #1 "true") + :abstraction)) + + (def: #export int + (-> Int Literal) + (|>> %i :abstraction)) + + (def: #export float + (-> Frac Literal) + (|>> (cond> [(f/= frac.positive-infinity)] + [(new> "+INF" [])] + + [(f/= frac.negative-infinity)] + [(new> "-INF" [])] + + [(f/= frac.not-a-number)] + [(new> "NAN" [])] + + ## else + [%f]) + :abstraction)) + + (def: sanitize + (-> Text Text) + (`` (|>> (~~ (template [ ] + [(text.replace-all )] + + ["\" "\\"] + [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 Literal) + (|>> ..sanitize + (text.enclose [text.double-quote text.double-quote]) + :abstraction)) + + (def: arguments + (-> (List (Expression Any)) Text) + (|>> (list@map ..code) (text.join-with ..input-separator) ..group)) + + (def: #export (apply/* args func) + (-> (List (Expression Any)) (Expression Any) (Computation Any)) + (:abstraction + (format (:representation func) (..arguments args)))) + + (def: parameters + (-> (List Argument) Text) + (|>> (list@map (function (_ [reference? var]) + (.if reference? + (format "&" (:representation var)) + (:representation var)))) + (text.join-with ..input-separator) + ..group)) + + (template [ ] + [(def: #export + (-> Var Argument) + (|>> []))] + + [parameter #0] + [reference #1] + ) + + (def: #export (closure uses arguments body!) + (-> (List Argument) (List Argument) Statement Literal) + (let [uses (case uses + #.Nil + "" + + _ + (format "use " (..parameters uses)))] + (|> (format "function " (..parameters arguments) + " " uses " " + (..block (:representation body!))) + ..group + :abstraction))) + + (template [ + + +] + [(`` (def: #export ( [(~~ (template.splice +))] function) + (-> [(~~ (template.splice +))] (Expression Any) (Computation Any)) + (..apply/* (list (~~ (template.splice +))) function))) + + (`` (template [ ] + [(def: #export ( args) + (-> [(~~ (template.splice +))] (Computation Any)) + ( args (..constant )))] + + (~~ (template.splice +))))] + + [apply/0 [] [] + [[func-num-args/0 "func_num_args"] + [func-get-args/0 "func_get_args"] + [time/0 "time"]]] + [apply/1 [in0] [(Expression Any)] + [[is-null/1 "is_null"] + [empty/1 "empty"] + [count/1 "count"] + [strlen/1 "strlen"] + [array-pop/1 "array_pop"] + [array-reverse/1 "array_reverse"] + [intval/1 "intval"] + [floatval/1 "floatval"] + [strval/1 "strval"] + [ord/1 "ord"] + [chr/1 "chr"] + [print/1 "print"] + [exit/1 "exit"]]] + [apply/2 [in0 in1] [(Expression Any) (Expression Any)] + [[call-user-func-array/2 "call_user_func_array"] + [array-slice/2 "array_slice"] + [array-push/2 "array_push"]]] + [apply/3 [in0 in1 in2] [(Expression Any) (Expression Any) (Expression Any)] + [[array-slice/3 "array_slice"] + [array-splice/3 "array_splice"] + [strpos/3 "strpos"] + [substr/3 "substr"]]] + ) + + (def: #export (array/* values) + (-> (List (Expression Any)) Literal) + (|> values + (list@map ..code) + (text.join-with ..input-separator) + ..group + (format "array") + :abstraction)) + + (def: #export (array-merge/+ required optionals) + (-> (Expression Any) (List (Expression Any)) (Computation Any)) + (..apply/* (list& required optionals) (..constant "array_merge"))) + + (def: #export (array/** kvs) + (-> (List [(Expression Any) (Expression Any)]) Literal) + (|> kvs + (list@map (function (_ [key value]) + (format (:representation key) " => " (:representation value)))) + (text.join-with ..input-separator) + ..group + (format "array") + :abstraction)) + + (def: #export (new constructor inputs) + (-> Constant (List (Expression Any)) (Computation Any)) + (|> (format "new " (:representation constructor) (arguments inputs)) + :abstraction)) + + (def: #export (do method inputs object) + (-> Text (List (Expression Any)) (Expression Any) (Computation Any)) + (|> (format (:representation object) "->" method (arguments inputs)) + :abstraction)) + + (def: #export (nth idx array) + (-> (Expression Any) (Expression Any) Access) + (|> (format (:representation array) "[" (:representation idx) "]") + :abstraction)) + + (def: #export (global name) + (-> Text Global) + (|> (..var "GLOBALS") (..nth (..string name)) :transmutation)) + + (def: #export (? test then else) + (-> (Expression Any) (Expression Any) (Expression Any) (Computation Any)) + (|> (format (:representation test) " ? " + (:representation then) " : " + (:representation else)) + ..group + :abstraction)) + + (template [ ] + [(def: #export ( parameter subject) + (-> (Expression Any) (Expression Any) (Computation Any)) + (|> (format (:representation subject) " " " " (:representation parameter)) + ..group + :abstraction))] + + [or "||"] + [and "&&"] + [= "==="] + [< "<"] + [<= "<="] + [> ">"] + [>= ">="] + [+ "+"] + [- "-"] + [* "*"] + [/ "/"] + [% "%"] + [bit-or "|"] + [bit-and "&"] + [bit-xor "^"] + [bit-shl "<<"] + [bit-shr ">>"] + [concat "."] + ) + + (def: #export not + (-> (Computation Any) (Computation Any)) + (|>> :representation (format "!") :abstraction)) + + (def: #export (set var value) + (-> (Location Any) (Expression Any) (Computation Any)) + (|> (format (:representation var) " = " (:representation value)) + ..group + :abstraction)) + + (def: #export (set? var) + (-> Var (Computation Any)) + (..apply/1 [var] (..constant "isset"))) + + (template [ ] + [(def: #export + (-> Var Statement) + (|>> :representation (format " ") (text.suffix ..statement-suffix) :abstraction))] + + [define-global "global"] + ) + + (template [ ] + [(def: #export ( location value) + (-> (Expression Any) Statement) + (:abstraction (format " " (:representation location) + " = " (:representation value) + ..statement-suffix)))] + + [define-static "static" Var] + [define-constant "const" Constant] + ) + + (def: #export (if test then! else!) + (-> (Expression Any) Statement Statement Statement) + (:abstraction + (format "if " (..group (:representation test)) " " + (..block (:representation then!)) + " else " + (..block (:representation else!))))) + + (def: #export (when test then!) + (-> (Expression Any) Statement Statement) + (:abstraction + (format "if " (..group (:representation test)) " " + (..block (:representation then!))))) + + (def: #export (then pre! post!) + (-> Statement Statement Statement) + (:abstraction + (format (:representation pre!) + text.new-line + (:representation post!)))) + + (def: #export (while test body!) + (-> (Expression Any) Statement Statement) + (:abstraction + (format "while " (..group (:representation test)) " " + (..block (:representation body!))))) + + (def: #export (do-while test body!) + (-> (Expression Any) Statement Statement) + (:abstraction + (format "do " (..block (:representation body!)) + " while " (..group (:representation test)) + ..statement-suffix))) + + (def: #export (for-each array value body!) + (-> (Expression Any) Var Statement Statement) + (:abstraction + (format "foreach(" (:representation array) + " as " (:representation value) + ") " (..block (:representation body!))))) + + (type: #export Except + {#class Constant + #exception Var + #handler Statement}) + + (def: (catch except) + (-> Except Text) + (let [declaration (format (:representation (get@ #class except)) + " " (:representation (get@ #exception except)))] + (format "catch" (..group declaration) " " + (..block (:representation (get@ #handler except)))))) + + (def: #export (try body! excepts) + (-> Statement (List Except) Statement) + (:abstraction + (format "try " (..block (:representation body!)) + text.new-line + (|> excepts + (list@map catch) + (text.join-with text.new-line))))) + + (template [ ] + [(def: #export + (-> (Expression Any) Statement) + (|>> :representation (format " ") (text.suffix ..statement-suffix) :abstraction))] + + [throw "throw"] + [return "return"] + [echo "echo"] + ) + + (def: #export (define name value) + (-> Constant (Expression Any) (Expression Any)) + (..apply/2 [(|> name :representation ..string) + value] + (..constant "define"))) + + (def: #export (define-function name uses arguments body!) + (-> Constant (List Argument) (List Argument) Statement Statement) + (let [uses (case uses + #.Nil + "" + + _ + (format " use " (..parameters uses)))] + (:abstraction + (format "function " (:representation name) " " (..parameters arguments) + uses " " + (..block (:representation body!)))))) + + (template [ ] + [(def: #export + Statement + (|> + (text.suffix ..statement-suffix) + :abstraction))] + + [break "break"] + [continue "continue"] + ) + ) + +(def: #export (cond clauses else!) + (-> (List [(Expression Any) Statement]) Statement Statement) + (list@fold (function (_ [test then!] next!) + (..if test then! next!)) + else! + (list.reverse clauses))) + +(def: #export command-line-arguments + Var + (..var "argv")) diff --git a/stdlib/source/lux/host/ruby.lux b/stdlib/source/lux/host/ruby.lux index e52fb6f37..037cdca5b 100644 --- a/stdlib/source/lux/host/ruby.lux +++ b/stdlib/source/lux/host/ruby.lux @@ -1,9 +1,7 @@ (.module: [lux (#- Code static int if cond function or and not comment) [control - [pipe (#+ case> cond> new>)] - [parser - ["s" code]]] + [pipe (#+ case> cond> new>)]] [data [number ["." frac]] @@ -12,9 +10,7 @@ [collection ["." list ("#@." functor fold)]]] [macro - ["." template] - ["." code] - [syntax (#+ syntax:)]] + ["." template]] [type abstract]]) diff --git a/stdlib/source/lux/tool/compiler/phase/extension/statement.lux b/stdlib/source/lux/tool/compiler/phase/extension/statement.lux index 61243a9bc..6c2ba872f 100644 --- a/stdlib/source/lux/tool/compiler/phase/extension/statement.lux +++ b/stdlib/source/lux/tool/compiler/phase/extension/statement.lux @@ -80,7 +80,7 @@ (do ///.monad [codeT (generate codeS) [target-name value statement] (///generation.define! name codeT) - _ (///generation.save! name statement)] + _ (///generation.save! false name statement)] (wrap [code//type codeT target-name value])))) (def: (definition name ?type codeC) @@ -296,7 +296,7 @@ (///generation.Operation anchor expression statement Any))) (do ///.monad [programG (generate programS)] - (///generation.save! ["" ""] (program programG)))) + (///generation.save! false ["" ""] (program programG)))) (def: (def::program program) (All [anchor expression statement] diff --git a/stdlib/source/lux/tool/compiler/phase/generation.lux b/stdlib/source/lux/tool/compiler/phase/generation.lux index edf260e19..4482daa3b 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation.lux @@ -221,12 +221,14 @@ (#error.Failure error) (exception.throw cannot-interpret error)))) -(def: #export (save! name code) +(def: #export (save! execute? name code) (All [anchor expression statement] - (-> Name statement (Operation anchor expression statement Any))) + (-> Bit Name statement (Operation anchor expression statement Any))) (do //.monad [label (..gensym "save") - _ (execute! label code) + _ (if execute? + (execute! label code) + (wrap [])) ?buffer (extension.read (get@ #buffer))] (case ?buffer (#.Some buffer) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php.lux b/stdlib/source/lux/tool/compiler/phase/generation/php.lux new file mode 100644 index 000000000..480c473bf --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php.lux @@ -0,0 +1,60 @@ +(.module: + [lux #* + [abstract + [monad (#+ do)]]] + [/ + [runtime (#+ Phase)] + ["." primitive] + ["." structure] + ["." reference ("#@." system)] + ["." case] + ["." loop] + ["." function] + ["." /// + ["." extension] + [// + ["." synthesis]]]]) + +(def: #export (generate synthesis) + Phase + (case synthesis + (^template [ ] + (^ ( value)) + (:: ///.monad wrap ( value))) + ([synthesis.bit primitive.bit] + [synthesis.i64 primitive.i64] + [synthesis.f64 primitive.f64] + [synthesis.text primitive.text]) + + (^ (synthesis.variant variantS)) + (structure.variant generate variantS) + + (^ (synthesis.tuple members)) + (structure.tuple generate members) + + (#synthesis.Reference value) + (reference@reference value) + + (^ (synthesis.branch/case case)) + (case.case generate case) + + (^ (synthesis.branch/let let)) + (case.let generate let) + + (^ (synthesis.branch/if if)) + (case.if generate if) + + (^ (synthesis.loop/scope scope)) + (loop.scope generate scope) + + (^ (synthesis.loop/recur updates)) + (loop.recur generate updates) + + (^ (synthesis.function/abstraction abstraction)) + (function.function generate abstraction) + + (^ (synthesis.function/apply application)) + (function.apply generate application) + + (#synthesis.Extension extension) + (extension.apply generate extension))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/case.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/case.lux new file mode 100644 index 000000000..1167ae5a6 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/case.lux @@ -0,0 +1,250 @@ +(.module: + [lux (#- case let if) + [abstract + [monad (#+ do)]] + [control + ["ex" exception (#+ exception:)]] + [data + ["." product] + ["." text + format] + [collection + ["." list ("#@." functor fold)] + ["." set]]] + [host + ["_" php (#+ Var Expression Statement)]]] + ["." // #_ + ["#." runtime (#+ Operation Phase)] + ["#." reference] + ["#." primitive] + ["#/" // + ["#." reference] + ["#/" // ("#@." monad) + [synthesis + ["." case]] + ["#/" // #_ + ["." reference (#+ Register)] + ["#." synthesis (#+ Synthesis Path)]]]]]) + +(def: #export register + (///reference.local _.var)) + +(def: #export capture + (///reference.foreign _.var)) + +(def: #export (let generate [valueS register bodyS]) + (-> Phase [Synthesis Register Synthesis] + (Operation (Expression Any))) + (do ////.monad + [valueG (generate valueS) + bodyG (generate bodyS)] + (wrap (|> bodyG + (list (_.set (..register register) valueG)) + _.array/* + (_.nth (_.int +1)))))) + +(def: #export (record-get generate valueS pathP) + (-> Phase Synthesis (List (Either Nat Nat)) + (Operation (Expression Any))) + (do ////.monad + [valueG (generate valueS)] + (wrap (list@fold (function (_ side source) + (.let [method (.case side + (^template [ ] + ( lefts) + ( (_.int (.int lefts)))) + ([#.Left //runtime.tuple//left] + [#.Right //runtime.tuple//right]))] + (method source))) + valueG + pathP)))) + +(def: #export (if generate [testS thenS elseS]) + (-> Phase [Synthesis Synthesis Synthesis] + (Operation (Expression Any))) + (do ////.monad + [testG (generate testS) + thenG (generate thenS) + elseG (generate elseS)] + (wrap (_.? testG thenG elseG)))) + +(def: @savepoint (_.var "lux_pm_savepoint")) +(def: @cursor (_.var "lux_pm_cursor")) +(def: @temp (_.var "lux_pm_temp")) + +(def: (push! value) + (-> (Expression Any) Statement) + (_.; (_.array-push/2 [@cursor value]))) + +(def: peek-and-pop + (Expression Any) + (_.array-pop/1 @cursor)) + +(def: pop! + Statement + (_.; ..peek-and-pop)) + +(def: peek + (Expression Any) + (_.nth (|> @cursor _.count/1 (_.- (_.int +1))) + @cursor)) + +(def: save! + Statement + (.let [cursor (_.array-slice/2 [@cursor (_.int +0)])] + (_.; (_.array-push/2 [@savepoint cursor])))) + +(def: restore! + Statement + (_.; (_.set @cursor (_.array-pop/1 @savepoint)))) + +(def: fail! _.break) + +(exception: #export unrecognized-path) + +(def: (multi-pop! pops) + (-> Nat Statement) + (_.; (_.array-splice/3 [@cursor + (_.int +0) + (_.int (i/* -1 (.int pops)))]))) + +(template [ ] + [(def: ( simple? idx) + (-> Bit Nat Statement) + ($_ _.then + (_.; (_.set @temp (|> idx .int _.int (//runtime.sum//get ..peek )))) + (.if simple? + (_.when (_.is-null/1 @temp) + fail!) + (_.if (_.is-null/1 @temp) + fail! + (..push! @temp)))))] + + [left-choice _.null (<|)] + [right-choice (_.string "") inc] + ) + +(def: (alternation pre! post!) + (-> Statement Statement Statement) + ($_ _.then + (_.do-while (_.bool false) + ($_ _.then + ..save! + pre!)) + ($_ _.then + ..restore! + post!))) + +(def: (pattern-matching' generate pathP) + (-> Phase Path (Operation Statement)) + (.case pathP + (^ (/////synthesis.path/then bodyS)) + (:: ////.monad map _.return (generate bodyS)) + + #/////synthesis.Pop + (////@wrap ..pop!) + + (#/////synthesis.Bind register) + (////@wrap (_.; (_.set (..register register) ..peek))) + + (^template [ ] + (^ ( value)) + (////@wrap (_.when (|> value (_.= ..peek) _.not) + fail!))) + ([/////synthesis.path/bit //primitive.bit] + [/////synthesis.path/i64 //primitive.i64] + [/////synthesis.path/f64 //primitive.f64] + [/////synthesis.path/text //primitive.text]) + + (^template [ ] + (^ ( idx)) + (////@wrap ( false idx)) + + (^ ( idx nextP)) + (|> nextP + (pattern-matching' generate) + (:: ////.monad map (_.then ( true idx))))) + ([/////synthesis.side/left /////synthesis.simple-left-side ..left-choice] + [/////synthesis.side/right /////synthesis.simple-right-side ..right-choice]) + + (^ (/////synthesis.member/left 0)) + (////@wrap (|> ..peek (_.nth (_.int +0)) ..push!)) + + (^template [ ] + (^ ( lefts)) + (////@wrap (|> ..peek ( (_.int (.int lefts))) ..push!))) + ([/////synthesis.member/left //runtime.tuple//left] + [/////synthesis.member/right //runtime.tuple//right]) + + (^ (/////synthesis.!bind-top register thenP)) + (do ////.monad + [then! (pattern-matching' generate thenP)] + (////@wrap ($_ _.then + (_.; (_.set (..register register) ..peek-and-pop)) + then!))) + + ## (^ (/////synthesis.!multi-pop nextP)) + ## (.let [[extra-pops nextP'] (case.count-pops nextP)] + ## (do ////.monad + ## [next! (pattern-matching' generate nextP')] + ## (////@wrap ($_ _.then + ## (..multi-pop! (n/+ 2 extra-pops)) + ## next!)))) + + (^template [ ] + (^ ( preP postP)) + (do ////.monad + [pre! (pattern-matching' generate preP) + post! (pattern-matching' generate postP)] + (wrap ( pre! post!)))) + ([/////synthesis.path/seq _.then] + [/////synthesis.path/alt ..alternation]) + + _ + (////.throw unrecognized-path []))) + +(def: (pattern-matching generate pathP) + (-> Phase Path (Operation Statement)) + (do ////.monad + [pattern-matching! (pattern-matching' generate pathP)] + (wrap ($_ _.then + (_.do-while (_.bool false) + pattern-matching!) + (_.throw (_.new (_.constant "Exception") (list (_.string case.pattern-matching-error)))))))) + +(def: (gensym prefix) + (-> Text (Operation Text)) + (:: ////.monad map (|>> %n (format prefix)) ///.next)) + +(def: #export (case generate [valueS pathP]) + (-> Phase [Synthesis Path] (Operation (Expression Any))) + (do ////.monad + [initG (generate valueS) + pattern-matching! (pattern-matching generate pathP) + @case (..gensym "case") + #let [@caseG (_.global @case) + @caseL (_.var @case)] + @init (:: @ map _.var (..gensym "init")) + #let [@dependencies+ (|> (case.storage pathP) + (get@ #case.dependencies) + set.to-list + (list@map (function (_ variable) + [#0 (.case variable + (#reference.Local register) + (..register register) + + (#reference.Foreign register) + (..capture register))])))] + _ (///.save! true ["" @case] + ($_ _.then + (<| _.; + (_.set @caseL) + (_.closure (list (_.reference @caseL)) (list& [#0 @init] + @dependencies+)) + ($_ _.then + (_.; (_.set @cursor (_.array/* (list @init)))) + (_.; (_.set @savepoint (_.array/* (list)))) + pattern-matching!)) + (_.; (_.set @caseG @caseL))))] + (wrap (_.apply/* (list& initG (list@map product.right @dependencies+)) + @caseG)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/extension.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/extension.lux new file mode 100644 index 000000000..3bc0a0887 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/extension.lux @@ -0,0 +1,13 @@ +(.module: + [lux #* + [data + [collection + ["." dictionary]]]] + [// + [runtime (#+ Bundle)]] + [/ + ["." common]]) + +(def: #export bundle + Bundle + common.bundle) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/extension/common.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/extension/common.lux new file mode 100644 index 000000000..9938bb2c1 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/extension/common.lux @@ -0,0 +1,126 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [control + ["." function]] + [data + ["." product] + ["." text] + [collection + ["." dictionary]]] + [host (#+ import:) + ["_" php (#+ Expression)]]] + ["." /// #_ + ["#." runtime (#+ Operation Phase Handler Bundle)] + ["#." primitive] + [// + [extension (#+ Nullary Unary Binary Trinary + nullary unary binary trinary)] + [// + [extension + ["." bundle]]]]]) + +(def: lux-procs + Bundle + (|> bundle.empty + (bundle.install "is" (binary (product.uncurry _.=))) + (bundle.install "try" (unary ///runtime.lux//try)))) + +(def: i64-procs + Bundle + (<| (bundle.prefix "i64") + (|> bundle.empty + (bundle.install "and" (binary (product.uncurry _.bit-and))) + (bundle.install "or" (binary (product.uncurry _.bit-or))) + (bundle.install "xor" (binary (product.uncurry _.bit-xor))) + (bundle.install "left-shift" (binary (product.uncurry _.bit-shl))) + (bundle.install "logical-right-shift" (binary (product.uncurry ///runtime.i64//logic-right-shift))) + (bundle.install "arithmetic-right-shift" (binary (product.uncurry _.bit-shr))) + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "+" (binary (product.uncurry _.+))) + (bundle.install "-" (binary (product.uncurry _.-))) + ))) + +(def: int-procs + Bundle + (<| (bundle.prefix "int") + (|> bundle.empty + (bundle.install "<" (binary (product.uncurry _.<))) + (bundle.install "*" (binary (product.uncurry _.*))) + (bundle.install "/" (binary (product.uncurry _./))) + (bundle.install "%" (binary (product.uncurry _.%))) + (bundle.install "frac" (unary _.floatval/1)) + (bundle.install "char" (unary _.chr/1))))) + +(import: #long java/lang/Double + (#static MIN_VALUE Double) + (#static MAX_VALUE Double)) + +(template [ ] + [(def: ( _) + (Nullary (Expression Any)) + (_.float ))] + + [frac//smallest (java/lang/Double::MIN_VALUE)] + [frac//min (f/* -1.0 (java/lang/Double::MAX_VALUE))] + [frac//max (java/lang/Double::MAX_VALUE)] + ) + +(def: frac-procs + Bundle + (<| (bundle.prefix "frac") + (|> bundle.empty + (bundle.install "+" (binary (product.uncurry _.+))) + (bundle.install "-" (binary (product.uncurry _.-))) + (bundle.install "*" (binary (product.uncurry _.*))) + (bundle.install "/" (binary (product.uncurry _./))) + (bundle.install "%" (binary (product.uncurry _.%))) + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "<" (binary (product.uncurry _.<))) + (bundle.install "smallest" (nullary frac//smallest)) + (bundle.install "min" (nullary frac//min)) + (bundle.install "max" (nullary frac//max)) + (bundle.install "int" (unary _.intval/1)) + (bundle.install "encode" (unary _.strval/1)) + (bundle.install "decode" (unary (|>> _.floatval/1 ///runtime.some))) + ))) + +(def: (text//index [startO partO textO]) + (Trinary (Expression Any)) + (///runtime.text//index textO partO startO)) + +(def: text-procs + Bundle + (<| (bundle.prefix "text") + (|> bundle.empty + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "<" (binary (product.uncurry _.<))) + (bundle.install "concat" (binary (product.uncurry _.concat))) + (bundle.install "index" (trinary text//index)) + (bundle.install "size" (unary _.strlen/1)) + (bundle.install "char" (binary (function (text//char [text idx]) + (|> text (_.nth idx) _.ord/1)))) + (bundle.install "clip" (trinary (function (text//clip [from to text]) + (_.substr/3 [text from (_.- from to)])))) + ))) + +(def: io-procs + Bundle + (<| (bundle.prefix "io") + (|> bundle.empty + (bundle.install "log" (unary (|>> (_.concat (_.string text.new-line)) _.print/1))) + (bundle.install "error" (unary ///runtime.io//throw!)) + (bundle.install "exit" (unary _.exit/1)) + (bundle.install "current-time" (nullary (|>> _.time/0 (_.* (_.int +1,000)))))))) + +(def: #export bundle + Bundle + (<| (bundle.prefix "lux") + (|> lux-procs + (dictionary.merge i64-procs) + (dictionary.merge int-procs) + (dictionary.merge frac-procs) + (dictionary.merge text-procs) + (dictionary.merge io-procs) + ))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/function.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/function.lux new file mode 100644 index 000000000..b2b446ed0 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/function.lux @@ -0,0 +1,104 @@ +(.module: + [lux (#- function) + [abstract + ["." monad (#+ do)]] + [control + pipe] + [data + ["." product] + ["." text + format] + [collection + ["." list ("#@." functor fold)]]] + [host + ["_" php (#+ Argument Expression Statement)]]] + ["." // #_ + [runtime (#+ Operation Phase)] + ["#." reference] + ["#." case] + ["#/" // + ["#." reference] + ["#/" // + ["." // #_ + [reference (#+ Register Variable)] + [analysis (#+ Variant Tuple Environment Arity Abstraction Application Analysis)] + [synthesis (#+ Synthesis)]]]]]) + +(def: #export (apply generate [functionS argsS+]) + (-> Phase (Application Synthesis) (Operation (Expression Any))) + (do ////.monad + [functionG (generate functionS) + argsG+ (monad.map @ generate argsS+)] + (wrap (_.apply/* argsG+ functionG)))) + +(def: #export capture + (///reference.foreign _.var)) + +(def: input + (|>> inc //case.register)) + +(def: #export (function generate [environment arity bodyS]) + (-> Phase (Abstraction Synthesis) (Operation (Expression Any))) + (do ////.monad + [[function-name bodyG] (///.with-context + (do @ + [function-name ///.context] + (///.with-anchor (_.var function-name) + (generate bodyS)))) + closureG+ (: (Operation (List Argument)) + (monad.map @ (|>> (:: //reference.system variable) + (:: @ map _.reference)) + environment)) + #let [@curried (_.var "curried") + arityG (|> arity .int _.int) + @num-args (_.var "num_args") + @selfG (_.global function-name) + @selfL (_.var function-name) + initialize-self! (_.; (_.set (//case.register 0) @selfL)) + initialize! (list@fold (.function (_ post pre!) + ($_ _.then + pre! + (_.; (_.set (..input post) (_.nth (|> post .int _.int) @curried))))) + initialize-self! + (list.indices arity))] + _ (///.save! true ["" function-name] + ($_ _.then + (<| _.; + (_.set @selfL) + (_.closure (list& (_.reference @selfL) closureG+) (list)) + ($_ _.then + (_.echo (_.string "'ello, world! ")) + (_.; (_.set @num-args (_.func-num-args/0 []))) + (_.echo @num-args) (_.echo (_.string " ~ ")) (_.echo arityG) + (_.echo (_.string text.new-line)) + (_.; (_.set @curried (_.func-get-args/0 []))) + (_.cond (list [(|> @num-args (_.= arityG)) + ($_ _.then + initialize! + (_.return bodyG))] + [(|> @num-args (_.> arityG)) + (let [arity-inputs (_.array-slice/3 [@curried (_.int +0) arityG]) + extra-inputs (_.array-slice/2 [@curried arityG]) + next (_.call-user-func-array/2 [@selfL arity-inputs]) + done (_.call-user-func-array/2 [next extra-inputs])] + ($_ _.then + (_.echo (_.string "STAGED ")) (_.echo (_.count/1 arity-inputs)) + (_.echo (_.string " + ")) (_.echo (_.count/1 extra-inputs)) + (_.echo (_.string text.new-line)) + (_.echo (_.string "@selfL ")) (_.echo @selfL) (_.echo (_.string text.new-line)) + (_.echo (_.string " next ")) (_.echo next) (_.echo (_.string text.new-line)) + (_.echo (_.string " done ")) (_.echo done) (_.echo (_.string text.new-line)) + (_.return done)))]) + ## (|> @num-args (_.< arityG)) + (let [@missing (_.var "missing")] + (_.return (<| (_.closure (list (_.reference @selfL) (_.reference @curried)) (list)) + ($_ _.then + (_.; (_.set @missing (_.func-get-args/0 []))) + (_.echo (_.string "NEXT ")) (_.echo (_.count/1 @curried)) + (_.echo (_.string " ")) (_.echo (_.count/1 @missing)) + (_.echo (_.string " ")) (_.echo (_.count/1 (_.array-merge/+ @curried (list @missing)))) + (_.echo (_.string text.new-line)) + (_.return (_.call-user-func-array/2 [@selfL (_.array-merge/+ @curried (list @missing))]))))))) + )) + (_.; (_.set @selfG @selfL))))] + (wrap @selfG))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/loop.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/loop.lux new file mode 100644 index 000000000..3404953fe --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/loop.lux @@ -0,0 +1,47 @@ +(.module: + [lux (#- Scope) + [abstract + ["." monad (#+ do)]] + [data + ["." product] + [text + format] + [collection + ["." list ("#@." functor)]]] + [host + ["_" php (#+ Expression)]]] + ["." // #_ + [runtime (#+ Operation Phase)] + ["#." case] + ["#/" // + ["#/" // + [// + [synthesis (#+ Scope Synthesis)]]]]]) + +(def: #export (scope generate [start initsS+ bodyS]) + (-> Phase (Scope Synthesis) (Operation (Expression Any))) + (do ////.monad + [@loop (:: @ map (|>> %n (format "loop")) ///.next) + #let [@loopG (_.global @loop) + @loopL (_.var @loop)] + initsO+ (monad.map @ generate initsS+) + bodyO (///.with-anchor @loopL + (generate bodyS)) + _ (///.save! true ["" @loop] + ($_ _.then + (<| _.; + (_.set @loopL) + (_.closure (list (_.reference @loopL)) + (|> initsS+ + list.enumerate + (list@map (|>> product.left (n/+ start) //case.register [#0]))) + (_.return bodyO))) + (_.; (_.set @loopG @loopL))))] + (wrap (_.apply/* initsO+ @loopG)))) + +(def: #export (recur generate argsS+) + (-> Phase (List Synthesis) (Operation (Expression Any))) + (do ////.monad + [@scope ///.anchor + argsO+ (monad.map @ generate argsS+)] + (wrap (_.apply/* argsO+ @scope)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/primitive.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/primitive.lux new file mode 100644 index 000000000..48a32389b --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/primitive.lux @@ -0,0 +1,27 @@ +(.module: + [lux (#- i64) + [control + [pipe (#+ cond> new>)]] + [data + [number + ["." frac]]] + [host + ["_" php (#+ Literal)]]] + ["." // #_ + ["#." runtime]]) + +(def: #export bit + (-> Bit Literal) + _.bool) + +(def: #export i64 + (-> (I64 Any) Literal) + (|>> .int _.int)) + +(def: #export f64 + (-> Frac Literal) + _.float) + +(def: #export text + (-> Text Literal) + _.string) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/reference.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/reference.lux new file mode 100644 index 000000000..8f5313421 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/reference.lux @@ -0,0 +1,11 @@ +(.module: + [lux #* + [host + ["_" php (#+ Expression)]]] + [// + [// + ["." reference]]]) + +(def: #export system + (reference.system (: (-> Text (Expression Any)) _.global) + (: (-> Text (Expression Any)) _.var))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/runtime.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/runtime.lux new file mode 100644 index 000000000..e29b7622a --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/runtime.lux @@ -0,0 +1,305 @@ +(.module: + [lux (#- inc) + [abstract + [monad (#+ do)]] + [control + ["." function] + ["p" parser + ["s" code]]] + [data + [number (#+ hex) + ["." i64]] + ["." text + format] + [collection + ["." list ("#@." functor)]]] + ["." macro + ["." code] + [syntax (#+ syntax:)]] + [host + ["_" php (#+ Expression Var Global Computation Literal Statement)]]] + ["." /// + ["//." // + [// + ["/////." name] + ["." synthesis]]]] + ) + +(template [ ] + [(type: #export + ( Var (Expression Any) Statement))] + + [Operation ///.Operation] + [Phase ///.Phase] + [Handler ///.Handler] + [Bundle ///.Bundle] + ) + +(def: prefix Text "LuxRuntime") + +(def: #export unit (_.string synthesis.unit)) + +(def: (flag value) + (-> Bit Literal) + (if value + (_.string "") + _.null)) + +(def: #export variant-tag-field "_lux_tag") +(def: #export variant-flag-field "_lux_flag") +(def: #export variant-value-field "_lux_value") + +(def: (variant' tag last? value) + (-> (Expression Any) (Expression Any) (Expression Any) Literal) + (_.array/** (list [(_.string ..variant-tag-field) tag] + [(_.string ..variant-flag-field) last?] + [(_.string ..variant-value-field) value]))) + +(def: #export (variant tag last? value) + (-> Nat Bit (Expression Any) Literal) + (variant' (_.int (.int tag)) + (..flag last?) + value)) + +(def: #export none + Literal + (..variant 0 #0 ..unit)) + +(def: #export some + (-> (Expression Any) Literal) + (..variant 1 #1)) + +(def: #export left + (-> (Expression Any) Literal) + (..variant 0 #0)) + +(def: #export right + (-> (Expression Any) Literal) + (..variant 1 #1)) + +(def: (runtime-name raw) + (-> Text [Global Var]) + (let [refined (|> raw + /////name.normalize + (format ..prefix "_"))] + [(_.global refined) (_.var refined)])) + +(def: (feature name definition) + (-> [Global Var] (-> [Global Var] Statement) Statement) + (definition name)) + +(syntax: #export (with-vars {vars (s.tuple (p.some s.local-identifier))} + body) + (wrap (list (` (let [(~+ (|> vars + (list@map (function (_ var) + (list (code.local-identifier var) + (` (_.var (~ (code.text (/////name.normalize var)))))))) + list.concat))] + (~ body)))))) + +(syntax: (runtime: {declaration (p.or s.local-identifier + (s.form (p.and s.local-identifier + (p.some s.local-identifier))))} + code) + (macro.with-gensyms [g!_ g!G g!L] + (case declaration + (#.Left name) + (let [code-nameC (code.local-identifier (format "@" name)) + runtime-nameC (` (runtime-name (~ (code.text name))))] + (wrap (list (` (def: #export (~ (code.local-identifier name)) _.Global (~ runtime-nameC))) + (` (def: (~ code-nameC) + _.Statement + (..feature (~ runtime-nameC) + (function ((~ g!_) [(~ g!G) (~ g!L)]) + (_.; (_.set (~ g!G) (~ code)))))))))) + + (#.Right [name inputs]) + (let [code-nameC (code.local-identifier (format "@" name)) + runtime-nameC (` (runtime-name (~ (code.text name)))) + inputsC (list@map code.local-identifier inputs) + inputs-typesC (list@map (function.constant (` (_.Expression Any))) + inputs)] + (wrap (list (` (def: #export ((~ (code.local-identifier name)) (~+ inputsC)) + (-> (~+ inputs-typesC) (_.Computation Any)) + (.let [[(~ g!G) (~ g!L)] (~ runtime-nameC)] + (_.apply/* (list (~+ inputsC)) (~ g!G))))) + (` (def: (~ code-nameC) + _.Statement + (..feature (~ runtime-nameC) + (function ((~ g!_) [(~ g!G) (~ g!L)]) + (..with-vars [(~+ inputsC)] + ($_ _.then + (<| _.; + (_.set (~ g!L)) + (_.closure (list (_.reference (~ g!L))) + (list (~+ (|> inputsC + (list@map (function (_ inputC) + (` [#0 (~ inputC)])))))) + (~ code))) + (_.; (_.set (~ g!G) (~ g!L))) + )))))))))))) + +(runtime: (lux//try op) + (with-vars [value] + (_.try ($_ _.then + (_.; (_.set value (_.apply/1 [..unit] op))) + (_.return (..right value))) + (list (with-vars [error] + {#_.class (_.constant "Exception") + #_.exception error + #_.handler (_.return (..left (_.do "getMessage" (list) error)))}))))) + +(runtime: (lux//program-args inputs) + (with-vars [head tail] + ($_ _.then + (_.; (_.set tail ..none)) + (<| (_.for-each (_.array-reverse/1 inputs) head) + (_.; (_.set tail (..some (_.array/* (list head tail)))))) + (_.return tail)))) + +(def: runtime//lux + Statement + ($_ _.then + @lux//try + @lux//program-args)) + +(runtime: (io//throw! message) + ($_ _.then + (_.throw (_.new (_.constant "Exception") (list message))) + (_.return ..unit))) + +(def: runtime//io + Statement + ($_ _.then + @io//throw!)) + +(def: tuple-size + _.count/1) + +(def: last-index + (|>> ..tuple-size (_.- (_.int +1)))) + +(with-expansions [ (as-is ($_ _.then + (_.; (_.set lefts (_.- last-index-right lefts))) + (_.; (_.set tuple (_.nth last-index-right tuple)))))] + (runtime: (tuple//left lefts tuple) + (with-vars [last-index-right] + (<| (_.while (_.bool true)) + ($_ _.then + (_.; (_.set last-index-right (..last-index tuple))) + (_.if (_.> lefts last-index-right) + ## No need for recursion + (_.return (_.nth lefts tuple)) + ## Needs recursion + ))))) + + (runtime: (tuple//right lefts tuple) + (with-vars [last-index-right right-index] + (<| (_.while (_.bool true)) + ($_ _.then + (_.; (_.set last-index-right (..last-index tuple))) + (_.; (_.set right-index (_.+ (_.int +1) lefts))) + (_.cond (list [(_.= right-index last-index-right) + (_.return (_.nth right-index tuple))] + [(_.> right-index last-index-right) + ## Needs recursion. + ]) + (_.return (_.array-slice/2 [tuple right-index]))) + ))))) + +(runtime: (sum//get sum wantsLast wantedTag) + (let [no-match! (_.return _.null) + sum-tag (_.nth (_.string ..variant-tag-field) sum) + ## sum-tag (_.nth (_.int +0) sum) + sum-flag (_.nth (_.string ..variant-flag-field) sum) + ## sum-flag (_.nth (_.int +1) sum) + sum-value (_.nth (_.string ..variant-value-field) sum) + ## sum-value (_.nth (_.int +2) sum) + is-last? (_.= (_.string "") sum-flag) + test-recursion! (_.if is-last? + ## Must recurse. + (_.return (sum//get sum-value (_.- sum-tag wantedTag) wantsLast)) + no-match!)] + ($_ _.then + (_.echo (_.string "sum//get ")) (_.echo (_.count/1 sum)) + (_.echo (_.string " ")) (_.echo (_.apply/1 [sum] (_.constant "gettype"))) + (_.echo (_.string " ")) (_.echo sum-tag) + (_.echo (_.string " ")) (_.echo wantedTag) + (_.echo (_.string text.new-line)) + (_.cond (list [(_.= sum-tag wantedTag) + (_.if (_.= wantsLast sum-flag) + (_.return sum-value) + test-recursion!)] + + [(_.> sum-tag wantedTag) + test-recursion!] + + [(_.and (_.< sum-tag wantedTag) + (_.= (_.string "") wantsLast)) + (_.return (variant' (_.- wantedTag sum-tag) sum-flag sum-value))]) + no-match!) + ))) + +(def: runtime//adt + Statement + ($_ _.then + @tuple//left + @tuple//right + @sum//get)) + +(runtime: (i64//logic-right-shift param subject) + (let [mask (|> (_.int +1) + (_.bit-shl (_.- param (_.int +64))) + (_.- (_.int +1)))] + (_.return (|> subject + (_.bit-shr param) + (_.bit-and mask))))) + +(def: runtime//i64 + Statement + ($_ _.then + @i64//logic-right-shift + )) + +(runtime: (text//index subject param start) + (with-vars [idx] + ($_ _.then + (_.; (_.set idx (_.strpos/3 [subject param start]))) + (_.if (_.= (_.bool false) idx) + (_.return ..none) + (_.return (..some idx)))))) + +(def: runtime//text + Statement + ($_ _.then + @text//index + )) + +(def: check-necessary-conditions! + Statement + (let [condition (_.= (_.int +8) + (_.constant "PHP_INT_SIZE")) + error-message (_.string (format "Cannot run program!" text.new-line + "Lux/PHP programs require 64-bit PHP builds!"))] + (_.when (_.not condition) + (_.throw (_.new (_.constant "Exception") (list error-message)))))) + +(def: runtime + Statement + ($_ _.then + check-necessary-conditions! + runtime//lux + runtime//adt + runtime//i64 + runtime//text + runtime//io + )) + +(def: #export artifact ..prefix) + +(def: #export generate + (Operation Any) + (///.with-buffer + (do ////.monad + [_ (///.save! true ["" ..prefix] ..runtime)] + (///.save-buffer! ..artifact)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/php/structure.lux b/stdlib/source/lux/tool/compiler/phase/generation/php/structure.lux new file mode 100644 index 000000000..7bc675d7e --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/php/structure.lux @@ -0,0 +1,36 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [host + ["_" php (#+ Expression)]]] + ["." // #_ + ["#." runtime (#+ Operation Phase)] + ["#." primitive] + ["#//" /// + ["#/" // #_ + [analysis (#+ Variant Tuple)] + ["#." synthesis (#+ Synthesis)]]]]) + +(def: #export (tuple generate elemsS+) + (-> Phase (Tuple Synthesis) (Operation (Expression Any))) + (case elemsS+ + #.Nil + (:: ////.monad wrap (//primitive.text /////synthesis.unit)) + + (#.Cons singletonS #.Nil) + (generate singletonS) + + _ + (|> elemsS+ + (monad.map ////.monad generate) + (:: ////.monad map _.array/*)))) + +(def: #export (variant generate [lefts right? valueS]) + (-> Phase (Variant Synthesis) (Operation (Expression Any))) + (:: ////.monad map + (//runtime.variant (if right? + (inc lefts) + lefts) + right?) + (generate valueS))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux index adec09fa3..1113ec3b6 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux @@ -41,6 +41,17 @@ (bundle.install "-" (binary (product.uncurry _.-))) ))) +(def: int-procs + Bundle + (<| (bundle.prefix "int") + (|> bundle.empty + (bundle.install "<" (binary (product.uncurry _.<))) + (bundle.install "*" (binary (product.uncurry _.*))) + (bundle.install "/" (binary (product.uncurry _./))) + (bundle.install "%" (binary (product.uncurry _.%))) + (bundle.install "frac" (unary _.float/1)) + (bundle.install "char" (unary _.chr/1))))) + (import: #long java/lang/Double (#static MIN_VALUE Double) (#static MAX_VALUE Double)) @@ -55,17 +66,6 @@ [frac//max (java/lang/Double::MAX_VALUE)] ) -(def: int-procs - Bundle - (<| (bundle.prefix "int") - (|> bundle.empty - (bundle.install "<" (binary (product.uncurry _.<))) - (bundle.install "*" (binary (product.uncurry _.*))) - (bundle.install "/" (binary (product.uncurry _./))) - (bundle.install "%" (binary (product.uncurry _.%))) - (bundle.install "frac" (unary _.float/1)) - (bundle.install "char" (unary _.chr/1))))) - (def: frac-procs Bundle (<| (bundle.prefix "frac") @@ -84,10 +84,6 @@ (bundle.install "encode" (unary _.repr/1)) (bundle.install "decode" (unary ///runtime.frac//decode))))) -(def: (text//char [subjectO paramO]) - (Binary (Expression Any)) - (///runtime.text//char subjectO paramO)) - (def: (text//clip [paramO extraO subjectO]) (Trinary (Expression Any)) (///runtime.text//clip subjectO paramO extraO)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/ruby/runtime.lux b/stdlib/source/lux/tool/compiler/phase/generation/ruby/runtime.lux index 81bdc8702..8858e9d4f 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/ruby/runtime.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/ruby/runtime.lux @@ -274,34 +274,6 @@ @text//clip @text//char)) -(runtime: (array//get array idx) - (with-vars [temp] - ($_ _.then - (_.set (list temp) (_.nth idx array)) - (_.if (_.= _.nil temp) - (_.return ..none) - (_.return (..some temp)))))) - -(runtime: (array//put array idx value) - ($_ _.then - (_.set (list (_.nth idx array)) value) - (_.return array))) - -(def: runtime//array - (Statement Any) - ($_ _.then - @array//get - @array//put)) - -(runtime: (box//write value box) - ($_ _.then - (_.set (list (_.nth (_.int +0) box)) value) - (_.return ..unit))) - -(def: runtime//box - (Statement Any) - @box//write) - (def: runtime (Statement Any) ($_ _.then @@ -310,8 +282,6 @@ runtime//i64 runtime//f64 runtime//text - runtime//array - runtime//box )) (def: #export artifact ..prefix) diff --git a/stdlib/source/program/compositor.lux b/stdlib/source/program/compositor.lux index a92aea013..5dd2fd1ba 100644 --- a/stdlib/source/program/compositor.lux +++ b/stdlib/source/program/compositor.lux @@ -4,8 +4,9 @@ [abstract [monad (#+ do)]] [control - [cli (#+ program:)] ["." io (#+ IO io)] + [parser + [cli (#+ program:)]] [security ["!" capability]]] [data diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index f62a071ae..5c5051a2c 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -40,6 +40,7 @@ [python (#+)] [lua (#+)] [ruby (#+)] + [php (#+)] [scheme (#+)]] [tool [compiler @@ -53,6 +54,8 @@ ] [ruby (#+) ] + [php (#+) + ] [scheme (#+) ]]]]] ## [control -- cgit v1.2.3