diff options
author | Eduardo Julian | 2019-06-15 19:45:32 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-06-15 19:45:32 -0400 |
commit | 0cc98bbe9cae3fd9fc50d8c78c1deaba7e557531 (patch) | |
tree | 4439100c5f036870282b6c93ac45e3731bcdf6fd /stdlib/source/lux/tool | |
parent | 7ee04017ee2ef5376c566b00750fd521c0ecac42 (diff) |
Array machinery for the JavaScript compiler.
Diffstat (limited to 'stdlib/source/lux/tool')
11 files changed, 340 insertions, 108 deletions
diff --git a/stdlib/source/lux/tool/compiler/default/init.lux b/stdlib/source/lux/tool/compiler/default/init.lux index 1f650634f..1a8d10474 100644 --- a/stdlib/source/lux/tool/compiler/default/init.lux +++ b/stdlib/source/lux/tool/compiler/default/init.lux @@ -19,7 +19,7 @@ ["." // ["#." syntax (#+ Aliases)] ["#." evaluation] - ["#/" // (#+ Instancer) + ["/#" // (#+ Instancer) ["#." analysis] ["#." synthesis] ["#." statement (#+ Requirements)] @@ -48,10 +48,11 @@ #.version //.version #.mode #.Build}) -(def: #export (state target expander host generate generation-bundle host-statement-bundle program) +(def: #export (state target expander host-analysis host generate generation-bundle host-statement-bundle program) (All [anchor expression statement] (-> Text Expander + ///analysis.Bundle (generation.Host expression statement) (generation.Phase anchor expression statement) (generation.Bundle anchor expression statement) @@ -61,8 +62,9 @@ (let [synthesis-state [synthesisE.bundle ///synthesis.init] generation-state [generation-bundle (generation.state host)] eval (//evaluation.evaluator expander synthesis-state generation-state generate) - analysis-state [(analysisE.bundle eval) (///analysis.state (..info target) host)]] - [(dictionary.merge (luxS.bundle expander program) + analysis-state [(analysisE.bundle eval host-analysis) + (///analysis.state (..info target) host)]] + [(dictionary.merge (luxS.bundle expander host-analysis program) host-statement-bundle) {#///statement.analysis {#///statement.state analysis-state #///statement.phase (analysisP.phase expander)} diff --git a/stdlib/source/lux/tool/compiler/default/platform.lux b/stdlib/source/lux/tool/compiler/default/platform.lux index 5dc5105f2..3e086e813 100644 --- a/stdlib/source/lux/tool/compiler/default/platform.lux +++ b/stdlib/source/lux/tool/compiler/default/platform.lux @@ -16,7 +16,7 @@ ["." // #_ ["#." init] ["#." syntax] - ["#/" // + ["/#" // ["#." analysis] ["#." statement] ["#." phase @@ -56,10 +56,11 @@ <State+> (as-is (///statement.State+ anchor expression statement)) <Bundle> (as-is (generation.Bundle anchor expression statement))] - (def: #export (initialize target expander platform generation-bundle host-statement-bundle program) + (def: #export (initialize target expander host-analysis platform generation-bundle host-statement-bundle program) (All <type-vars> (-> Text Expander + ///analysis.Bundle <Platform> <Bundle> (///statement.Bundle anchor expression statement) @@ -70,6 +71,7 @@ ///statement.lift-generation (///phase.run' (//init.state target expander + host-analysis (get@ #host platform) (get@ #phase platform) generation-bundle @@ -104,9 +106,9 @@ ## (io.fail error)) ) - (def: #export (compile expander platform configuration archive state) + (def: #export (compile partial-host-extension expander platform configuration archive state) (All <type-vars> - (-> Expander <Platform> Configuration Archive <State+> (! (Error [Archive <State+>])))) + (-> Text Expander <Platform> Configuration Archive <State+> (! (Error [Archive <State+>])))) (let [monad (get@ #&monad platform) source-module (get@ #cli.module configuration) compiler (:share [anchor expression statement] @@ -128,6 +130,7 @@ [input (context.read monad (get@ #&file-system platform) (get@ #cli.sources configuration) + partial-host-extension module) ## _ (&io.prepare-module target-dir (get@ #cli.module configuration)) ## _ (write-module target-dir file-name (get@ #cli.module configuration) module outputs) diff --git a/stdlib/source/lux/tool/compiler/meta/io/context.lux b/stdlib/source/lux/tool/compiler/meta/io/context.lux index bd1efd73b..454487cce 100644 --- a/stdlib/source/lux/tool/compiler/meta/io/context.lux +++ b/stdlib/source/lux/tool/compiler/meta/io/context.lux @@ -36,23 +36,6 @@ Extension ".lux") -(def: partial-host-extension - Extension - (`` (for {(~~ (static @.common-lisp)) ".cl" - (~~ (static @.js)) ".js" - (~~ (static @.old)) ".jvm" - (~~ (static @.jvm)) ".jvm" - (~~ (static @.lua)) ".lua" - (~~ (static @.php)) ".php" - (~~ (static @.python)) ".py" - (~~ (static @.r)) ".r" - (~~ (static @.ruby)) ".rb" - (~~ (static @.scheme)) ".scm"}))) - -(def: full-host-extension - Extension - (format partial-host-extension lux-extension)) - (def: #export (path system context module) (All [m] (-> (file.System m) Context Module Path)) (|> module @@ -78,22 +61,23 @@ (#error.Failure error) (find-source-file monad system contexts' module extension))))) -(def: #export (find-any-source-file monad system contexts module) +(def: #export (find-any-source-file monad system contexts partial-host-extension module) (All [!] - (-> (Monad !) (file.System !) (List Context) Module + (-> (Monad !) (file.System !) (List Context) Text Module (! (Error [Path (File !)])))) - (do monad - [outcome (find-source-file monad system contexts module ..full-host-extension)] - (case outcome - (#error.Success output) - (wrap outcome) + (let [full-host-extension (format partial-host-extension lux-extension)] + (do monad + [outcome (find-source-file monad system contexts module full-host-extension)] + (case outcome + (#error.Success output) + (wrap outcome) - (#error.Failure error) - (find-source-file monad system contexts module ..lux-extension)))) + (#error.Failure error) + (find-source-file monad system contexts module ..lux-extension))))) -(def: #export (read monad system contexts module) +(def: #export (read monad system contexts partial-host-extension module) (All [!] - (-> (Monad !) (file.System !) (List Context) Module + (-> (Monad !) (file.System !) (List Context) Text Module (! (Error Input)))) (do (error.with monad) [## TODO: Get rid of both ":share"s ASAP @@ -101,7 +85,7 @@ {(Monad !) monad} {(! (Error [Path (File !)])) - (find-any-source-file monad system contexts module)}) + (find-any-source-file monad system contexts partial-host-extension module)}) #let [[path file] (:share [!] {(Monad !) monad} diff --git a/stdlib/source/lux/tool/compiler/name.lux b/stdlib/source/lux/tool/compiler/name.lux index 252d57051..093d934cb 100644 --- a/stdlib/source/lux/tool/compiler/name.lux +++ b/stdlib/source/lux/tool/compiler/name.lux @@ -30,7 +30,8 @@ ["<"] "_LT" [">"] "_GT" ["~"] "_TI" - ["|"] "_PI"] + ["|"] "_PI" + [" "] "_SP"] (text.from-code char)))) (def: #export (normalize name) diff --git a/stdlib/source/lux/tool/compiler/phase/extension/analysis.lux b/stdlib/source/lux/tool/compiler/phase/extension/analysis.lux index 694f0345f..df378eebf 100644 --- a/stdlib/source/lux/tool/compiler/phase/extension/analysis.lux +++ b/stdlib/source/lux/tool/compiler/phase/extension/analysis.lux @@ -1,20 +1,16 @@ -(.`` (.module: - [lux #* - ["@" target] - [data - [collection - ["." dictionary]]]] - [//// - [default - [evaluation (#+ Eval)]] - [analysis (#+ Bundle)]] - ["." / #_ - ["#." lux] - ["#." (~~ (.for {"{old}" jvm - "JVM" jvm}))]])) +(.module: + [lux #* + [data + [collection + ["." dictionary]]]] + [//// + [default + [evaluation (#+ Eval)]] + [analysis (#+ Bundle)]] + ["." / #_ + ["#." lux]]) -(def: #export (bundle eval) - (-> Eval Bundle) - (dictionary.merge (`` (for {(~~ (static @.old)) /jvm.bundle - (~~ (static @.jvm)) /jvm.bundle})) +(def: #export (bundle eval host-specific) + (-> Eval Bundle Bundle) + (dictionary.merge host-specific (/lux.bundle eval))) diff --git a/stdlib/source/lux/tool/compiler/phase/extension/analysis/js.lux b/stdlib/source/lux/tool/compiler/phase/extension/analysis/js.lux new file mode 100644 index 000000000..d8285532b --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/extension/analysis/js.lux @@ -0,0 +1,146 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [control + ["<>" parser + ["<c>" code (#+ Parser)]] + pipe] + [data + [collection + ["." array (#+ Array)] + ["." dictionary]]] + [type + ["." check]] + [target + ["_" js]]] + ["." // #_ + ["#." lux (#+ custom)] + ["/#" // + ["#." bundle] + ["/#" // ("#@." monad) + [analysis + [".A" type]] + ["/#" // #_ + ["#." analysis (#+ Analysis Operation Phase Handler Bundle)]]]]]) + +(def: array::new + Handler + (custom + [<c>.any + (function (_ extension phase lengthC) + (do ////.monad + [lengthA (typeA.with-type Nat + (phase lengthC)) + [var-id varT] (typeA.with-env check.var) + _ (typeA.infer (type (Array varT)))] + (wrap (#/////analysis.Extension extension (list lengthA)))))])) + +(def: array::length + Handler + (custom + [<c>.any + (function (_ extension phase arrayC) + (do ////.monad + [[var-id varT] (typeA.with-env check.var) + arrayA (typeA.with-type (type (Array varT)) + (phase arrayC)) + _ (typeA.infer Nat)] + (wrap (#/////analysis.Extension extension (list arrayA)))))])) + +(def: array::read + Handler + (custom + [(<>.and <c>.any <c>.any) + (function (_ extension phase [indexC arrayC]) + (do ////.monad + [indexA (typeA.with-type Nat + (phase indexC)) + [var-id varT] (typeA.with-env check.var) + arrayA (typeA.with-type (type (Array varT)) + (phase arrayC)) + _ (typeA.infer varT)] + (wrap (#/////analysis.Extension extension (list indexA arrayA)))))])) + +(def: array::write + Handler + (custom + [($_ <>.and <c>.any <c>.any <c>.any) + (function (_ extension phase [indexC valueC arrayC]) + (do ////.monad + [indexA (typeA.with-type Nat + (phase indexC)) + [var-id varT] (typeA.with-env check.var) + valueA (typeA.with-type varT + (phase valueC)) + arrayA (typeA.with-type (type (Array varT)) + (phase arrayC)) + _ (typeA.infer (type (Array varT)))] + (wrap (#/////analysis.Extension extension (list indexA valueA arrayA)))))])) + +(def: array::delete + Handler + (custom + [($_ <>.and <c>.any <c>.any) + (function (_ extension phase [indexC arrayC]) + (do ////.monad + [indexA (typeA.with-type Nat + (phase indexC)) + [var-id varT] (typeA.with-env check.var) + arrayA (typeA.with-type (type (Array varT)) + (phase arrayC)) + _ (typeA.infer (type (Array varT)))] + (wrap (#/////analysis.Extension extension (list indexA arrayA)))))])) + +(def: bundle::array + Bundle + (<| (///bundle.prefix "array") + (|> ///bundle.empty + (///bundle.install "new" array::new) + (///bundle.install "length" array::length) + (///bundle.install "read" array::read) + (///bundle.install "write" array::write) + (///bundle.install "delete" array::delete) + ))) + +(def: js::constant + Handler + (custom + [<c>.text + (function (_ extension phase name) + (do ////.monad + [_ (typeA.infer Any)] + (wrap (#/////analysis.Extension extension (list (/////analysis.text name))))))])) + +(def: js::apply + Handler + (custom + [($_ <>.and <c>.any (<>.some <c>.any)) + (function (_ extension phase [abstractionC inputsC]) + (do ////.monad + [abstractionA (typeA.with-type Any + (phase abstractionC)) + inputsA (monad.map @ (|>> phase (typeA.with-type Any)) inputsC) + _ (typeA.infer Any)] + (wrap (#/////analysis.Extension extension (list& abstractionA inputsA)))))])) + +(def: js::undefined? + Handler + (custom + [<c>.any + (function (_ extension phase [valueC]) + (do ////.monad + [valueA (typeA.with-type Any + (phase valueC)) + _ (typeA.infer Bit)] + (wrap (#/////analysis.Extension extension (list valueA)))))])) + +(def: #export bundle + Bundle + (<| (///bundle.prefix "js") + (|> ///bundle.empty + (///bundle.install "constant" js::constant) + (///bundle.install "apply" js::apply) + (///bundle.install "undefined?" js::undefined?) + (dictionary.merge bundle::array) + ))) diff --git a/stdlib/source/lux/tool/compiler/phase/extension/analysis/lux.lux b/stdlib/source/lux/tool/compiler/phase/extension/analysis/lux.lux index 51402fad8..48401f0c6 100644 --- a/stdlib/source/lux/tool/compiler/phase/extension/analysis/lux.lux +++ b/stdlib/source/lux/tool/compiler/phase/extension/analysis/lux.lux @@ -90,31 +90,32 @@ _ (<>.fail (exception.construct ..char-text-must-be-size-1 [raw]))))) (def: lux::syntax-char-case! - (..custom [($_ <>.and - <c>.any - (<c>.tuple (<>.some (<>.and (<c>.tuple (<>.many ..text-char)) - <c>.any))) - <c>.any) - (function (_ extension-name phase [input conditionals else]) - (do ////.monad - [input (typeA.with-type text.Char - (phase input)) - expectedT (///.lift macro.expected-type) - conditionals (monad.map @ (function (_ [cases branch]) - (do @ - [branch (typeA.with-type expectedT - (phase branch))] - (wrap [cases branch]))) - conditionals) - else (typeA.with-type expectedT - (phase else))] - (wrap (|> conditionals - (list@map (function (_ [cases branch]) - (/////analysis.tuple - (list (/////analysis.tuple (list@map (|>> /////analysis.nat) cases)) - branch)))) - (list& input else) - (#/////analysis.Extension extension-name)))))]))) + (..custom + [($_ <>.and + <c>.any + (<c>.tuple (<>.some (<>.and (<c>.tuple (<>.many ..text-char)) + <c>.any))) + <c>.any) + (function (_ extension-name phase [input conditionals else]) + (do ////.monad + [input (typeA.with-type text.Char + (phase input)) + expectedT (///.lift macro.expected-type) + conditionals (monad.map @ (function (_ [cases branch]) + (do @ + [branch (typeA.with-type expectedT + (phase branch))] + (wrap [cases branch]))) + conditionals) + else (typeA.with-type expectedT + (phase else))] + (wrap (|> conditionals + (list@map (function (_ [cases branch]) + (/////analysis.tuple + (list (/////analysis.tuple (list@map (|>> /////analysis.nat) cases)) + branch)))) + (list& input else) + (#/////analysis.Extension extension-name)))))]))) ## "lux is" represents reference/pointer equality. (def: lux::is diff --git a/stdlib/source/lux/tool/compiler/phase/extension/statement/lux.lux b/stdlib/source/lux/tool/compiler/phase/extension/statement/lux.lux index 0ae210fa5..af49f8ee1 100644 --- a/stdlib/source/lux/tool/compiler/phase/extension/statement/lux.lux +++ b/stdlib/source/lux/tool/compiler/phase/extension/statement/lux.lux @@ -127,9 +127,9 @@ (synthesize codeA))] (definition' generate name code//type codeS))) -(def: (refresh expander) +(def: (refresh expander host-analysis) (All [anchor expression statement] - (-> Expander (Operation anchor expression statement Any))) + (-> Expander /////analysis.Bundle (Operation anchor expression statement Any))) (do ////.monad [[bundle state] ////.get-state #let [eval (/////evaluation.evaluator expander @@ -140,11 +140,11 @@ (update@ [#/////statement.analysis #/////statement.state] (: (-> /////analysis.State+ /////analysis.State+) (|>> product.right - [(///analysis.bundle eval)])) + [(///analysis.bundle eval host-analysis)])) state)]))) -(def: (lux::def expander) - (-> Expander Handler) +(def: (lux::def expander host-analysis) + (-> Expander /////analysis.Bundle Handler) (function (_ extension-name phase inputsC+) (case inputsC+ (^ (list [_ (#.Identifier ["" short-name])] valueC annotationsC [_ (#.Bit exported?)])) @@ -160,14 +160,14 @@ #let [_ (log! (format "Definition " (%name full-name)))] _ (/////statement.lift-generation (////generation.learn full-name valueN)) - _ (..refresh expander)] + _ (..refresh expander host-analysis)] (wrap /////statement.no-requirements)) _ (////.throw ///.invalid-syntax [extension-name %code inputsC+])))) -(def: (def::type-tagged expander) - (-> Expander Handler) +(def: (def::type-tagged expander host-analysis) + (-> Expander /////analysis.Bundle Handler) (..custom [($_ p.and s.local-identifier s.any s.any (s.tuple (p.some s.text)) s.bit) (function (_ extension-name phase [short-name valueC annotationsC tags exported?]) @@ -185,7 +185,7 @@ #let [_ (log! (format "Definition " (%name full-name)))] _ (/////statement.lift-generation (////generation.learn full-name valueN)) - _ (..refresh expander)] + _ (..refresh expander host-analysis)] (wrap /////statement.no-requirements)))])) (def: imports @@ -323,14 +323,14 @@ _ (////.throw ///.invalid-syntax [extension-name %code inputsC+])))) -(def: (bundle::def expander program) +(def: (bundle::def expander host-analysis program) (All [anchor expression statement] - (-> Expander (-> expression statement) (Bundle anchor expression statement))) + (-> Expander /////analysis.Bundle (-> expression statement) (Bundle anchor expression statement))) (<| (///bundle.prefix "def") (|> ///bundle.empty (dictionary.put "module" def::module) (dictionary.put "alias" def::alias) - (dictionary.put "type tagged" (def::type-tagged expander)) + (dictionary.put "type tagged" (def::type-tagged expander host-analysis)) (dictionary.put "analysis" def::analysis) (dictionary.put "synthesis" def::synthesis) (dictionary.put "generation" def::generation) @@ -338,10 +338,10 @@ (dictionary.put "program" (def::program program)) ))) -(def: #export (bundle expander program) +(def: #export (bundle expander host-analysis program) (All [anchor expression statement] - (-> Expander (-> expression statement) (Bundle anchor expression statement))) + (-> Expander /////analysis.Bundle (-> expression statement) (Bundle anchor expression statement))) (<| (///bundle.prefix "lux") (|> ///bundle.empty - (dictionary.put "def" (lux::def expander)) - (dictionary.merge (..bundle::def expander program))))) + (dictionary.put "def" (lux::def expander host-analysis)) + (dictionary.merge (..bundle::def expander host-analysis program))))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/extension.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/extension.lux index 3bc0a0887..71739bfc9 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/extension.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/extension.lux @@ -6,8 +6,10 @@ [// [runtime (#+ Bundle)]] [/ - ["." common]]) + ["." common] + ["." host]]) (def: #export bundle Bundle - common.bundle) + (dictionary.merge common.bundle + host.bundle)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux new file mode 100644 index 000000000..3cf3c6c07 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux @@ -0,0 +1,106 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [control + ["<>" parser + ["<s>" synthesis (#+ Parser)]]] + [data + ["." error] + [collection + ["." dictionary]]] + [target + ["_" js (#+ Expression)]]] + ["." // #_ + ["#." common] + ["/#" // #_ + ["#." runtime (#+ Operation Phase Handler Bundle + with-vars)] + ["#." primitive] + ["/#" // #_ + [extension (#+ Nullary Unary Binary Trinary + nullary unary binary trinary)] + ["/#" // + ["." extension + ["." bundle]] + [// + [synthesis (#+ %synthesis)]]]]]]) + +(def: #export (custom [parser handler]) + (All [s] + (-> [(Parser s) + (-> Text Phase s (Operation Expression))] + Handler)) + (function (_ extension-name phase input) + (case (<s>.run input parser) + (#error.Success input') + (handler extension-name phase input') + + (#error.Failure error) + (/////.throw extension.invalid-syntax [extension-name %synthesis input])))) + +(def: array::new + (Unary Expression) + (|>> ///runtime.i64//to-number list (_.new (_.var "Array")))) + +(def: array::length + (Unary Expression) + (|>> (_.the "length") ///runtime.i64//from-number)) + +(def: (array::read [indexG arrayG]) + (Binary Expression) + (_.at indexG arrayG)) + +(def: (array::write [indexG valueG arrayG]) + (Trinary Expression) + (///runtime.array//write indexG valueG arrayG)) + +(def: (array::delete [indexG arrayG]) + (Binary Expression) + (///runtime.array//delete indexG arrayG)) + +(def: array + Bundle + (<| (bundle.prefix "array") + (|> bundle.empty + (bundle.install "new" (unary array::new)) + (bundle.install "length" (unary array::length)) + (bundle.install "read" (binary array::read)) + (bundle.install "write" (trinary array::write)) + (bundle.install "delete" (binary array::delete)) + ))) + +(def: js::constant + (..custom + [<s>.text + (function (_ extension phase name) + (do /////.monad + [] + (wrap (_.var name))))])) + +(def: js::apply + (..custom + [($_ <>.and <s>.any (<>.some <s>.any)) + (function (_ extension phase [abstractionS inputsS]) + (do /////.monad + [abstractionG (phase abstractionS) + inputsG (monad.map @ phase inputsS)] + (wrap (_.apply/* abstractionG inputsG))))])) + +(def: js::undefined? + (..custom + [<s>.any + (function (_ extension phase valueS) + (|> valueS + phase + (:: /////.monad map (_.= _.undefined))))])) + +(def: #export bundle + Bundle + (<| (bundle.prefix "js") + (|> bundle.empty + (bundle.install "constant" js::constant) + (bundle.install "apply" js::apply) + (bundle.install "undefined?" js::undefined?) + (dictionary.merge ..array) + ))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux index 6892879b8..9be09d142 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux @@ -696,14 +696,6 @@ @js//delete )) -(runtime: (array//read idx array) - (with-vars [temp] - ($_ _.then - (_.define temp (_.at idx array)) - (_.if (_.= _.undefined temp) - (_.return ..none) - (_.return (..some temp)))))) - (runtime: (array//write idx value array) ($_ _.then (_.set (_.at idx array) value) @@ -717,7 +709,6 @@ (def: runtime//array Statement ($_ _.then - @array//read @array//write @array//delete)) |