From 290de8ebcb7edc92877f2ccc333171214e5eae23 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 6 Feb 2022 03:15:39 -0400 Subject: Finishing the meta-compiler [Part 1] --- documentation/bookmark/3D.md | 4 - documentation/bookmark/graphic.md | 6 + documentation/bookmark/graphic/3D.md | 8 + documentation/bookmark/graphics.md | 6 - stdlib/source/library/lux.lux | 13 +- stdlib/source/library/lux/control/parser/code.lux | 121 +++++++----- .../library/lux/tool/compiler/default/platform.lux | 2 +- .../lux/tool/compiler/language/lux/analysis.lux | 51 +---- .../compiler/language/lux/analysis/evaluation.lux | 7 +- .../tool/compiler/language/lux/analysis/scope.lux | 194 +++++++++++++++++++ .../compiler/language/lux/phase/analysis/case.lux | 8 +- .../language/lux/phase/analysis/function.lux | 31 ++- .../language/lux/phase/analysis/reference.lux | 6 +- .../compiler/language/lux/phase/analysis/scope.lux | 208 --------------------- .../language/lux/phase/extension/analysis/jvm.lux | 36 ++-- .../language/lux/phase/extension/directive/jvm.lux | 5 +- .../language/lux/phase/extension/directive/lux.lux | 11 +- .../source/library/lux/tool/compiler/meta/cli.lux | 126 +++++++++---- .../lux/tool/compiler/meta/packager/ruby.lux | 8 +- stdlib/source/program/aedifex/command/build.lux | 86 ++++----- stdlib/source/program/aedifex/command/deps.lux | 2 +- stdlib/source/program/aedifex/format.lux | 51 +++-- stdlib/source/program/aedifex/parser.lux | 79 ++++---- stdlib/source/program/aedifex/profile.lux | 87 +++++---- stdlib/source/program/compositor.lux | 2 +- stdlib/source/test/lux/target/python.lux | 24 ++- .../lux/tool/compiler/language/lux/analysis.lux | 18 +- .../tool/compiler/language/lux/analysis/scope.lux | 203 ++++++++++++++++++++ .../tool/compiler/language/lux/analysis/type.lux | 2 +- .../language/lux/phase/analysis/complex.lux | 15 +- stdlib/source/test/lux/tool/compiler/meta/cli.lux | 35 +++- 31 files changed, 884 insertions(+), 571 deletions(-) delete mode 100644 documentation/bookmark/3D.md create mode 100644 documentation/bookmark/graphic.md create mode 100644 documentation/bookmark/graphic/3D.md delete mode 100644 documentation/bookmark/graphics.md create mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/analysis/scope.lux delete mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/scope.lux create mode 100644 stdlib/source/test/lux/tool/compiler/language/lux/analysis/scope.lux diff --git a/documentation/bookmark/3D.md b/documentation/bookmark/3D.md deleted file mode 100644 index a7020c3ef..000000000 --- a/documentation/bookmark/3D.md +++ /dev/null @@ -1,4 +0,0 @@ -# Three.js - -1. [Three.js Fundamentals](https://threejsfundamentals.org/) - diff --git a/documentation/bookmark/graphic.md b/documentation/bookmark/graphic.md new file mode 100644 index 000000000..5a1abe21c --- /dev/null +++ b/documentation/bookmark/graphic.md @@ -0,0 +1,6 @@ +# 2D + +1. [Einar Høst - Composition by Juxtaposition: A PostScript on Functional Geometry - Lambda Days 2020](https://www.youtube.com/watch?v=GvTh0MmVPQI) +1. [Functional geometry](https://dl.acm.org/doi/10.1145/800068.802148) +1. [Bresenham's Circle Drawing Algorithm](https://funloop.org/post/2021-03-15-bresenham-circle-drawing-algorithm.html) + diff --git a/documentation/bookmark/graphic/3D.md b/documentation/bookmark/graphic/3D.md new file mode 100644 index 000000000..a4d7702f0 --- /dev/null +++ b/documentation/bookmark/graphic/3D.md @@ -0,0 +1,8 @@ +# Reference + +0. [3D Graphics for Dummies - Chris Ryan - CppCon 2021](https://www.youtube.com/watch?v=EIijFV3VE1g) + +# Three.js + +0. [Three.js Fundamentals](https://threejsfundamentals.org/) + diff --git a/documentation/bookmark/graphics.md b/documentation/bookmark/graphics.md deleted file mode 100644 index 5a1abe21c..000000000 --- a/documentation/bookmark/graphics.md +++ /dev/null @@ -1,6 +0,0 @@ -# 2D - -1. [Einar Høst - Composition by Juxtaposition: A PostScript on Functional Geometry - Lambda Days 2020](https://www.youtube.com/watch?v=GvTh0MmVPQI) -1. [Functional geometry](https://dl.acm.org/doi/10.1145/800068.802148) -1. [Bresenham's Circle Drawing Algorithm](https://funloop.org/post/2021-03-15-bresenham-circle-drawing-algorithm.html) - diff --git a/stdlib/source/library/lux.lux b/stdlib/source/library/lux.lux index 4f14a2ada..e6a3e5e6f 100644 --- a/stdlib/source/library/lux.lux +++ b/stdlib/source/library/lux.lux @@ -427,13 +427,15 @@ ... {#Captured Nat}) ("lux def type tagged" Ref {#Named [..prelude_module "Ref"] - {#Sum ... Local + {#Sum + ... Local Nat ... Captured Nat}} {"#Local" "#Captured"} .public) +... TODO: Get rid of both #name & #inner ... (type: .public Scope ... (Record ... [#name (List Text) @@ -442,11 +444,14 @@ ... #captured (Bindings Text [Type Ref])])) ("lux def type tagged" Scope {#Named [..prelude_module "Scope"] - {#Product ... name + {#Product + ... name {#Apply Text List} - {#Product ... inner + {#Product + ... inner Nat - {#Product ... locals + {#Product + ... locals {#Apply {#Product Type Nat} {#Apply Text Bindings}} ... captured {#Apply {#Product Type Ref} {#Apply Text Bindings}}}}}} diff --git a/stdlib/source/library/lux/control/parser/code.lux b/stdlib/source/library/lux/control/parser/code.lux index f17a1551d..910d7f449 100644 --- a/stdlib/source/library/lux/control/parser/code.lux +++ b/stdlib/source/library/lux/control/parser/code.lux @@ -1,26 +1,26 @@ (.using - [library - [lux {"-" nat int rev local not symbol} - [abstract - ["[0]" monad {"+" do}]] - [control - ["[0]" try {"+" Try}]] - [data - ["[0]" bit] - ["[0]" text ("[1]#[0]" monoid)] - [collection - ["[0]" list ("[1]#[0]" functor)]]] - [macro - ["[0]" code ("[1]#[0]" equivalence)]] - [math - [number - ["[0]" nat] - ["[0]" int] - ["[0]" rev] - ["[0]" frac]]] - [meta - ["[0]" symbol]]]] - ["[0]" //]) + [library + [lux {"-" nat int rev local not symbol} + [abstract + ["[0]" monad {"+" do}]] + [control + ["[0]" try {"+" Try}]] + [data + ["[0]" bit] + ["[0]" text ("[1]#[0]" monoid)] + [collection + ["[0]" list ("[1]#[0]" functor)]]] + [macro + ["[0]" code ("[1]#[0]" equivalence)]] + [math + [number + ["[0]" nat] + ["[0]" int] + ["[0]" rev] + ["[0]" frac]]] + [meta + ["[0]" symbol]]]] + ["[0]" //]) (def: (un_paired pairs) (All (_ a) (-> (List [a a]) (List a))) @@ -103,32 +103,57 @@ _ {try.#Failure "There are no tokens to parse!"}))) -(template [ ] - [(with_expansions [ (as_is {try.#Failure ($_ text#composite "Cannot parse " (remaining_inputs tokens))})] - (def: .public - (Parser Text) - (function (_ tokens) - (case tokens - {.#Item [[_ { ["" x]}] tokens']} - {try.#Success [tokens' x]} - - _ - ))) - - (def: .public ( expected) - (-> Text (Parser Any)) - (function (_ tokens) - (case tokens - {.#Item [[_ { ["" actual]}] tokens']} - (if (# = expected actual) - {try.#Success [tokens' []]} - ) - - _ - ))))] - - [local_symbol local_symbol! .#Symbol text.equivalence "local symbol"] - ) +(with_expansions [ (as_is {try.#Failure ($_ text#composite "Cannot parse local symbol" (remaining_inputs tokens))})] + (def: .public local_symbol + (Parser Text) + (function (_ tokens) + (case tokens + {.#Item [[_ {.#Symbol ["" x]}] tokens']} + {try.#Success [tokens' x]} + + _ + ))) + + (def: .public (local_symbol! expected) + (-> Text (Parser Any)) + (function (_ tokens) + (case tokens + {.#Item [[_ {.#Symbol ["" actual]}] tokens']} + (if (# text.equivalence = expected actual) + {try.#Success [tokens' []]} + ) + + _ + )))) + +(with_expansions [ (as_is {try.#Failure ($_ text#composite "Cannot parse local symbol" (remaining_inputs tokens))})] + (def: .public global_symbol + (Parser Symbol) + (function (_ tokens) + (case tokens + {.#Item [[_ {.#Symbol ["" short]}] tokens']} + + + {.#Item [[_ {.#Symbol it}] tokens']} + {try.#Success [tokens' it]} + + _ + ))) + + (def: .public (global_symbol! expected) + (-> Symbol (Parser Any)) + (function (_ tokens) + (case tokens + {.#Item [[_ {.#Symbol ["" actual]}] tokens']} + + + {.#Item [[_ {.#Symbol it}] tokens']} + (if (# symbol.equivalence = expected it) + {try.#Success [tokens' []]} + ) + + _ + )))) (template [ ] [(def: .public ( p) diff --git a/stdlib/source/library/lux/tool/compiler/default/platform.lux b/stdlib/source/library/lux/tool/compiler/default/platform.lux index dc9ff4533..02b35d0e7 100644 --- a/stdlib/source/library/lux/tool/compiler/default/platform.lux +++ b/stdlib/source/library/lux/tool/compiler/default/platform.lux @@ -720,7 +720,7 @@ (def: .public (compile phase_wrapper import static expander platform compilation context) (All (_ ) (-> ///phase.Wrapper Import Static Expander Compilation )) - (let [[sources host_dependencies libraries target module] compilation + (let [[host_dependencies libraries compilers sources target module] compilation compiler (|> (..compiler phase_wrapper expander platform) (serial_compiler import static platform sources) (..parallel context))] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux b/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux index 643a1b428..116d84299 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux @@ -259,49 +259,6 @@ {try.#Failure error} {try.#Failure error})))) -(def: fresh_bindings - (All (_ k v) (Bindings k v)) - [.#counter 0 - .#mappings (list)]) - -(def: fresh_scope - Scope - [.#name (list) - .#inner 0 - .#locals fresh_bindings - .#captured fresh_bindings]) - -(def: .public (with_scope action) - (All (_ a) (-> (Operation a) (Operation [Scope a]))) - (function (_ [bundle state]) - (.case (action [bundle (revised@ .#scopes (|>> {.#Item fresh_scope}) state)]) - {try.#Success [[bundle' state'] output]} - (.case (value@ .#scopes state') - {.#Item head tail} - {try.#Success [[bundle' (with@ .#scopes tail state')] - [head output]]} - - {.#End} - {try.#Failure "Impossible error: Drained scopes!"}) - - {try.#Failure error} - {try.#Failure error}))) - -(def: scope_reset - (List Scope) - (list fresh_scope)) - -(def: .public (without_scopes action) - (All (_ a) (-> (Operation a) (Operation a))) - (function (_ [bundle state]) - (.case (action [bundle (with@ .#scopes ..scope_reset state)]) - {try.#Success [[bundle' state'] output]} - {try.#Success [[bundle' (with@ .#scopes (value@ .#scopes state) state')] - output]} - - {try.#Failure error} - {try.#Failure error}))) - (def: .public (with_current_module name) (All (_ a) (-> Text (Operation a) (Operation a))) (extension.localized (value@ .#current_module) @@ -347,12 +304,12 @@ (function (_ bundle,state) (.case (exception.with exception message (action bundle,state)) - {try.#Success output} - {try.#Success output} - {try.#Failure error} (let [[bundle state] bundle,state] - {try.#Failure (locate_error (value@ .#location state) error)})))) + {try.#Failure (locate_error (value@ .#location state) error)}) + + output + output))) (def: .public (install state) (-> .Lux (Operation Any)) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/analysis/evaluation.lux b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/evaluation.lux index 0a7138dca..d27d54fe7 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/analysis/evaluation.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/evaluation.lux @@ -14,8 +14,9 @@ ["n" nat] ["[0]" i64]]]]] ["[0]" // {"+" Operation} - ["[0]" type] [macro {"+" Expander}] + ["[1][0]" type] + ["[1][0]" scope] [// [phase ["[0]P" extension] @@ -44,8 +45,8 @@ (do phase.monad [count (extensionP.lifted meta.seed) - exprA (<| (type.expecting type) - //.without_scopes + exprA (<| (//type.expecting type) + //scope.reset (analyze archive exprC)) module (extensionP.lifted meta.current_module_name)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/analysis/scope.lux b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/scope.lux new file mode 100644 index 000000000..838c2c362 --- /dev/null +++ b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/scope.lux @@ -0,0 +1,194 @@ +(.using + [library + [lux {"-" local} + [abstract + monad] + [control + ["[0]" maybe ("[1]#[0]" monad)] + ["[0]" try] + ["[0]" exception {"+" exception:}]] + [data + ["[0]" text ("[1]#[0]" equivalence)] + ["[0]" product] + [collection + ["[0]" list ("[1]#[0]" functor mix monoid)] + [dictionary + ["[0]" plist]]]]]] + ["/" // {"+" Environment Operation Phase} + [// + [phase + ["[0]" extension]] + [/// + ["[0]" phase] + [reference + ["[0]" variable {"+" Register Variable}]]]]]) + +(type: Local + (Bindings Text [Type Register])) + +(type: Foreign + (Bindings Text [Type Variable])) + +(def: (local? name scope) + (-> Text Scope Bit) + (|> scope + (value@ [.#locals .#mappings]) + (plist.contains? name))) + +(def: (local name scope) + (-> Text Scope (Maybe [Type Variable])) + (|> scope + (value@ [.#locals .#mappings]) + (plist.value name) + (maybe#each (function (_ [type value]) + [type {variable.#Local value}])))) + +(def: (captured? name scope) + (-> Text Scope Bit) + (|> scope + (value@ [.#captured .#mappings]) + (plist.contains? name))) + +(def: (captured name scope) + (-> Text Scope (Maybe [Type Variable])) + (loop [idx 0 + mappings (value@ [.#captured .#mappings] scope)] + (case mappings + {.#Item [_name [_source_type _source_ref]] mappings'} + (if (text#= name _name) + {.#Some [_source_type {variable.#Foreign idx}]} + (again (++ idx) mappings')) + + {.#End} + {.#None}))) + +(def: (reference? name scope) + (-> Text Scope Bit) + (or (local? name scope) + (captured? name scope))) + +(def: (reference name scope) + (-> Text Scope (Maybe [Type Variable])) + (case (..local name scope) + {.#Some type} + {.#Some type} + + _ + (..captured name scope))) + +(def: .public (find name) + (-> Text (Operation (Maybe [Type Variable]))) + (extension.lifted + (function (_ state) + (let [[inner outer] (|> state + (value@ .#scopes) + (list.split_when (|>> (reference? name))))] + (case outer + {.#End} + {.#Right [state {.#None}]} + + {.#Item top_outer _} + (let [[ref_type init_ref] (maybe.else (undefined) + (..reference name top_outer)) + [ref inner'] (list#mix (: (-> Scope [Variable (List Scope)] [Variable (List Scope)]) + (function (_ scope ref+inner) + [{variable.#Foreign (value@ [.#captured .#counter] scope)} + {.#Item (revised@ .#captured + (: (-> Foreign Foreign) + (|>> (revised@ .#counter ++) + (revised@ .#mappings (plist.has name [ref_type (product.left ref+inner)])))) + scope) + (product.right ref+inner)}])) + [init_ref {.#End}] + (list.reversed inner)) + scopes (list#composite inner' outer)] + {.#Right [(with@ .#scopes scopes state) + {.#Some [ref_type ref]}]}) + ))))) + +(exception: .public no_scope) +(exception: .public drained) + +(def: .public (with_local [name type] action) + (All (_ a) (-> [Text Type] (Operation a) (Operation a))) + (function (_ [bundle state]) + (case (value@ .#scopes state) + {.#Item head tail} + (let [old_mappings (value@ [.#locals .#mappings] head) + new_var_id (value@ [.#locals .#counter] head) + new_head (revised@ .#locals + (: (-> Local Local) + (|>> (revised@ .#counter ++) + (revised@ .#mappings (plist.has name [type new_var_id])))) + head)] + (case (phase.result' [bundle (with@ .#scopes {.#Item new_head tail} state)] + action) + {try.#Success [[bundle' state'] output]} + (case (value@ .#scopes state') + {.#Item head' tail'} + (let [scopes' {.#Item (with@ .#locals (value@ .#locals head) head') + tail'}] + {try.#Success [[bundle' (with@ .#scopes scopes' state')] + output]}) + + _ + (exception.except ..drained [])) + + {try.#Failure error} + {try.#Failure error})) + + _ + (exception.except ..no_scope [])))) + +(def: empty + Scope + (let [bindings (: Bindings + [.#counter 0 + .#mappings (list)])] + [.#name (list) + .#inner 0 + .#locals bindings + .#captured bindings])) + +(def: .public (reset action) + (All (_ a) (-> (Operation a) (Operation a))) + (function (_ [bundle state]) + (case (action [bundle (with@ .#scopes (list ..empty) state)]) + {try.#Success [[bundle' state'] output]} + {try.#Success [[bundle' (with@ .#scopes (value@ .#scopes state) state')] + output]} + + failure + failure))) + +(def: .public (with action) + (All (_ a) (-> (Operation a) (Operation [Scope a]))) + (function (_ [bundle state]) + (case (action [bundle (revised@ .#scopes (|>> {.#Item ..empty}) state)]) + {try.#Success [[bundle' state'] output]} + (case (value@ .#scopes state') + {.#Item head tail} + {try.#Success [[bundle' (with@ .#scopes tail state')] + [head output]]} + + {.#End} + (exception.except ..drained [])) + + {try.#Failure error} + {try.#Failure error}))) + +(def: .public next + (Operation Register) + (extension.lifted + (function (_ state) + (case (value@ .#scopes state) + {.#Item top _} + {try.#Success [state (value@ [.#locals .#counter] top)]} + + {.#End} + (exception.except ..no_scope []))))) + +(def: .public environment + (-> Scope (Environment Variable)) + (|>> (value@ [.#captured .#mappings]) + (list#each (function (_ [_ [_ ref]]) ref)))) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux index 3eab189d4..e1b1a8c07 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux @@ -24,7 +24,6 @@ ["[0]" / "_" ["[1][0]" coverage {"+" Coverage}] ["/[1]" // "_" - ["[1][0]" scope] ["[1][0]" complex] ["/[1]" // "_" ["[1][0]" extension] @@ -33,7 +32,8 @@ ["[1][0]" simple] ["[1][0]" complex] ["[1][0]" pattern {"+" Pattern}] - ["[1][0]" type]] + ["[1][0]" type] + ["[1][0]" scope]] [/// ["[1]" phase]]]]]]) @@ -225,9 +225,9 @@ [location {.#Symbol ["" name]}] (/.with_location location (do ///.monad - [outputA (//scope.with_local [name inputT] + [outputA (/scope.with_local [name inputT] next) - idx //scope.next_local] + idx /scope.next] (in [{/pattern.#Bind idx} outputA]))) (^template [ ] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux index 5a2018656..63c315954 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux @@ -14,18 +14,17 @@ ["[0]" list ("[1]#[0]" monoid monad)]]] ["[0]" type ["[0]" check]]]] - ["[0]" // "_" - ["[1][0]" scope] - ["/[1]" // "_" - ["[1][0]" extension] - [// - ["/" analysis {"+" Analysis Operation Phase} - ["[1][0]" type] - ["[1][0]" inference]] - [/// - ["[1]" phase] - [reference {"+"} - [variable {"+"}]]]]]]) + ["[0]" /// "_" + ["[1][0]" extension] + [// + ["/" analysis {"+" Analysis Operation Phase} + ["[1][0]" type] + ["[1][0]" inference] + ["[1][0]" scope]] + [/// + ["[1]" phase] + [reference {"+"} + [variable {"+"}]]]]]) (exception: .public (cannot_analyse [expected Type function Text @@ -93,13 +92,13 @@ {.#Function inputT outputT} (<| (# ! each (.function (_ [scope bodyA]) {/.#Function (list#each (|>> /.variable) - (//scope.environment scope)) + (/scope.environment scope)) bodyA})) - /.with_scope + /scope.with ... Functions have access not only to their argument, but ... also to themselves, through a local variable. - (//scope.with_local [function_name expectedT]) - (//scope.with_local [arg_name inputT]) + (/scope.with_local [function_name expectedT]) + (/scope.with_local [arg_name inputT]) (/type.expecting outputT) (analyse archive body)) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/reference.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/reference.lux index 223f0c07f..8fdf78aa8 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/reference.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/reference.lux @@ -10,12 +10,12 @@ ["[0]" text ("[1]#[0]" equivalence) ["%" format {"+" format}]]]]] ["[0]" // "_" - ["[1][0]" scope] ["/[1]" // "_" ["[1][0]" extension] [// ["/" analysis {"+" Analysis Operation} - ["[1][0]" type]] + ["[1][0]" type] + ["[1][0]" scope]] [/// ["[1][0]" reference] ["[1]" phase]]]]]) @@ -84,7 +84,7 @@ (def: (variable var_name) (-> Text (Operation (Maybe Analysis))) (do [! ///.monad] - [?var (//scope.find var_name)] + [?var (/scope.find var_name)] (case ?var {.#Some [actualT ref]} (do ! diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/scope.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/scope.lux deleted file mode 100644 index 0d24cd44d..000000000 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/scope.lux +++ /dev/null @@ -1,208 +0,0 @@ -(.using - [library - [lux {"-" local} - [abstract - monad] - [control - ["[0]" maybe ("[1]#[0]" monad)] - ["[0]" try] - ["[0]" exception {"+" exception:}]] - [data - ["[0]" text ("[1]#[0]" equivalence)] - ["[0]" product] - [collection - ["[0]" list ("[1]#[0]" functor mix monoid)] - [dictionary - ["[0]" plist]]]]]] - ["[0]" /// "_" - ["[1][0]" extension] - [// - ["/" analysis {"+" Operation Phase}] - [/// - [reference - ["[0]" variable {"+" Register Variable}]] - ["[1]" phase]]]]) - -(type: Local - (Bindings Text [Type Register])) - -(type: Foreign - (Bindings Text [Type Variable])) - -(def: (local? name scope) - (-> Text Scope Bit) - (|> scope - (value@ [.#locals .#mappings]) - (plist.contains? name))) - -(def: (local name scope) - (-> Text Scope (Maybe [Type Variable])) - (|> scope - (value@ [.#locals .#mappings]) - (plist.value name) - (maybe#each (function (_ [type value]) - [type {variable.#Local value}])))) - -(def: (captured? name scope) - (-> Text Scope Bit) - (|> scope - (value@ [.#captured .#mappings]) - (plist.contains? name))) - -(def: (captured name scope) - (-> Text Scope (Maybe [Type Variable])) - (loop [idx 0 - mappings (value@ [.#captured .#mappings] scope)] - (case mappings - {.#Item [_name [_source_type _source_ref]] mappings'} - (if (text#= name _name) - {.#Some [_source_type {variable.#Foreign idx}]} - (again (++ idx) mappings')) - - {.#End} - {.#None}))) - -(def: (reference? name scope) - (-> Text Scope Bit) - (or (local? name scope) - (captured? name scope))) - -(def: (reference name scope) - (-> Text Scope (Maybe [Type Variable])) - (case (..local name scope) - {.#Some type} - {.#Some type} - - _ - (..captured name scope))) - -(def: .public (find name) - (-> Text (Operation (Maybe [Type Variable]))) - (///extension.lifted - (function (_ state) - (let [[inner outer] (|> state - (value@ .#scopes) - (list.split_when (|>> (reference? name))))] - (case outer - {.#End} - {.#Right [state {.#None}]} - - {.#Item top_outer _} - (let [[ref_type init_ref] (maybe.else (undefined) - (..reference name top_outer)) - [ref inner'] (list#mix (: (-> Scope [Variable (List Scope)] [Variable (List Scope)]) - (function (_ scope ref+inner) - [{variable.#Foreign (value@ [.#captured .#counter] scope)} - {.#Item (revised@ .#captured - (: (-> Foreign Foreign) - (|>> (revised@ .#counter ++) - (revised@ .#mappings (plist.has name [ref_type (product.left ref+inner)])))) - scope) - (product.right ref+inner)}])) - [init_ref {.#End}] - (list.reversed inner)) - scopes (list#composite inner' outer)] - {.#Right [(with@ .#scopes scopes state) - {.#Some [ref_type ref]}]}) - ))))) - -(exception: .public cannot_create_local_binding_without_a_scope) -(exception: .public invalid_scope_alteration) - -(def: .public (with_local [name type] action) - (All (_ a) (-> [Text Type] (Operation a) (Operation a))) - (function (_ [bundle state]) - (case (value@ .#scopes state) - {.#Item head tail} - (let [old_mappings (value@ [.#locals .#mappings] head) - new_var_id (value@ [.#locals .#counter] head) - new_head (revised@ .#locals - (: (-> Local Local) - (|>> (revised@ .#counter ++) - (revised@ .#mappings (plist.has name [type new_var_id])))) - head)] - (case (///.result' [bundle (with@ .#scopes {.#Item new_head tail} state)] - action) - {try.#Success [[bundle' state'] output]} - (case (value@ .#scopes state') - {.#Item head' tail'} - (let [scopes' {.#Item (with@ .#locals (value@ .#locals head) head') - tail'}] - {try.#Success [[bundle' (with@ .#scopes scopes' state')] - output]}) - - _ - (exception.except ..invalid_scope_alteration [])) - - {try.#Failure error} - {try.#Failure error})) - - _ - (exception.except ..cannot_create_local_binding_without_a_scope [])) - )) - -(template [ ] - [(def: - (Bindings Text [Type ]) - [.#counter 0 - .#mappings (list)])] - - [init_locals Nat] - [init_captured Variable] - ) - -(def: (scope parent_name child_name) - (-> (List Text) Text Scope) - [.#name (list& child_name parent_name) - .#inner 0 - .#locals init_locals - .#captured init_captured]) - -(def: .public (with_scope name action) - (All (_ a) (-> Text (Operation a) (Operation a))) - (function (_ [bundle state]) - (let [parent_name (case (value@ .#scopes state) - {.#End} - (list) - - {.#Item top _} - (value@ .#name top))] - (case (action [bundle (revised@ .#scopes - (|>> {.#Item (scope parent_name name)}) - state)]) - {try.#Success [[bundle' state'] output]} - {try.#Success [[bundle' (revised@ .#scopes - (|>> list.tail (maybe.else (list))) - state')] - output]} - - {try.#Failure error} - {try.#Failure error})))) - -(exception: .public cannot_get_next_reference_when_there_is_no_scope) - -(def: .public next_local - (Operation Register) - (///extension.lifted - (function (_ state) - (case (value@ .#scopes state) - {.#Item top _} - {try.#Success [state (value@ [.#locals .#counter] top)]} - - {.#End} - (exception.except ..cannot_get_next_reference_when_there_is_no_scope []))))) - -(def: (ref_variable ref) - (-> Ref Variable) - (case ref - {.#Local register} - {variable.#Local register} - - {.#Captured register} - {variable.#Foreign register})) - -(def: .public (environment scope) - (-> Scope (List Variable)) - (|> scope - (value@ [.#captured .#mappings]) - (list#each (function (_ [_ [_ ref]]) (ref_variable ref))))) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux index 4d6c7e712..21980f491 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux @@ -47,22 +47,20 @@ ["[1][0]" lux {"+" custom}] ["/[1]" // ["[1][0]" bundle] - ["/[1]" // "_" - [analysis + ["//[1]" /// "_" + ["[1][0]" synthesis] + ["[1][0]" analysis {"+" Analysis Operation Phase Handler Bundle} + ["[1]/[0]" complex] + ["[1]/[0]" pattern] + ["[0]A" type] + ["[0]A" inference] ["[0]" scope]] - ["/[1]" // "_" - ["[1][0]" analysis {"+" Analysis Operation Phase Handler Bundle} - ["[1]/[0]" complex] - ["[1]/[0]" pattern] - ["[0]A" type] - ["[0]A" inference]] - ["[1][0]" synthesis] - [/// - ["[0]" phase ("[1]#[0]" monad)] - [meta - [archive {"+" Archive} - [module - [descriptor {"+" Module}]]]]]]]]]) + [/// + ["[0]" phase ("[1]#[0]" monad)] + [meta + [archive {"+" Archive} + [module + [descriptor {"+" Module}]]]]]]]]) (import: java/lang/ClassLoader) @@ -1810,7 +1808,7 @@ list.reversed (list#mix scope.with_local (analyse archive body)) (typeA.expecting .Any) - /////analysis.with_scope)] + scope.with)] (in (/////analysis.tuple (list (/////analysis.text ..constructor_tag) (visibility_analysis visibility) (/////analysis.bit strict_fp?) @@ -1907,7 +1905,7 @@ list.reversed (list#mix scope.with_local (analyse archive body)) (typeA.expecting returnT) - /////analysis.with_scope)] + scope.with)] (in (/////analysis.tuple (list (/////analysis.text ..virtual_tag) (/////analysis.text method_name) (visibility_analysis visibility) @@ -1980,7 +1978,7 @@ list.reversed (list#mix scope.with_local (analyse archive body)) (typeA.expecting returnT) - /////analysis.with_scope)] + scope.with)] (in (/////analysis.tuple (list (/////analysis.text ..static_tag) (/////analysis.text method_name) (visibility_analysis visibility) @@ -2150,7 +2148,7 @@ list.reversed (list#mix scope.with_local (analyse archive body)) (typeA.expecting returnT) - /////analysis.with_scope)] + scope.with)] (in (/////analysis.tuple (list (/////analysis.text ..overriden_tag) (class_analysis parent_type) (/////analysis.text method_name) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux index 1e3b1eabc..5641140a4 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux @@ -67,10 +67,9 @@ ["[0]" generation] ["[0]" directive {"+" Handler Bundle}] ["[0]" analysis {"+" Analysis} - ["[0]A" type]] + ["[0]A" type] + ["[0]A" scope]] [phase - [analysis - ["[0]A" scope]] [generation [jvm ["[0]" runtime {"+" Anchor Definition Extender}] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux index 99bcd7e85..04006e52f 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux @@ -37,7 +37,8 @@ [macro {"+" Expander}] ["[1]/[0]" evaluation] ["[0]A" type] - ["[0]A" module]] + ["[0]A" module] + ["[0]" scope]] ["[1][0]" synthesis {"+" Synthesis}] ["[1][0]" generation] ["[1][0]" directive {"+" Import Requirements Phase Operation Handler Bundle}] @@ -100,7 +101,7 @@ synthesize (value@ [/////directive.#synthesis /////directive.#phase] state) generate (value@ [/////directive.#generation /////directive.#phase] state)] [_ codeA] (<| /////directive.lifted_analysis - /////analysis.with_scope + scope.with typeA.fresh (typeA.expecting type) (analyse archive codeC)) @@ -138,7 +139,7 @@ synthesize (value@ [/////directive.#synthesis /////directive.#phase] state) generate (value@ [/////directive.#generation /////directive.#phase] state)] [_ code//type codeA] (/////directive.lifted_analysis - (/////analysis.with_scope + (scope.with (typeA.fresh (case expected {.#None} @@ -191,7 +192,7 @@ synthesize (value@ [/////directive.#synthesis /////directive.#phase] state) generate (value@ [/////directive.#generation /////directive.#phase] state)] [_ codeA] (<| /////directive.lifted_analysis - /////analysis.with_scope + scope.with typeA.fresh (typeA.expecting codeT) (analyse archive codeC)) @@ -481,7 +482,7 @@ (Operation anchor expression directive Synthesis))) (do phase.monad [[_ programA] (<| /////directive.lifted_analysis - /////analysis.with_scope + scope.with typeA.fresh (typeA.expecting (type (-> (List Text) (IO Any)))) (analyse archive programC))] diff --git a/stdlib/source/library/lux/tool/compiler/meta/cli.lux b/stdlib/source/library/lux/tool/compiler/meta/cli.lux index c4d5eb819..eee8d719c 100644 --- a/stdlib/source/library/lux/tool/compiler/meta/cli.lux +++ b/stdlib/source/library/lux/tool/compiler/meta/cli.lux @@ -1,10 +1,24 @@ (.using [library [lux {"-" Module Source} + [abstract + [monad {"+" do}] + [equivalence {"+" Equivalence}]] [control [pipe {"+" case>}] ["<>" parser - ["<[0]>" cli {"+" Parser}]]] + ["<[0]>" cli {"+" Parser}] + ["<[0]>" text]]] + [data + ["[0]" product] + ["[0]" text + ["%" format]] + [collection + ["[0]" list ("[1]#[0]" functor)]]] + [math + [number {"+" hex}]] + [meta + ["[0]" symbol]] [tool [compiler [meta @@ -14,15 +28,57 @@ [world [file {"+" Path}]]]]) -(type: .public Source - Path) - (type: .public Host_Dependency Path) (type: .public Library Path) +(type: .public Compiler + (Record + [#definition Symbol + #parameters (List Text)])) + +(def: .public compiler_equivalence + (Equivalence Compiler) + ($_ product.equivalence + symbol.equivalence + (list.equivalence text.equivalence) + )) + +(template [ ] + [(def: + Text + (text.of_char (hex )))] + + ["02" parameter_start] + ["03" parameter_end] + ) + +(def: compiler_parameter + (-> Text Text) + (text.enclosed [..parameter_start ..parameter_end])) + +(def: .public (compiler_format [[module short] parameters]) + (%.Format Compiler) + (%.format (..compiler_parameter module) (..compiler_parameter short) + (text.together (list#each ..compiler_parameter parameters)))) + +(def: compiler_parser' + (.Parser Compiler) + (let [parameter (: (.Parser Text) + (<| (<>.after (.this ..parameter_start)) + (<>.before (.this ..parameter_end)) + (.slice (.many! (.none_of! ..parameter_end)))))] + (do <>.monad + [module parameter + short parameter + parameters (<>.some parameter)] + (in [[module short] parameters])))) + +(type: .public Source + Path) + (type: .public Target Path) @@ -31,9 +87,10 @@ (type: .public Compilation (Record - [#sources (List Source) - #host_dependencies (List Host_Dependency) + [#host_dependencies (List Host_Dependency) #libraries (List Library) + #compilers (List Compiler) + #sources (List Source) #target Target #module Module])) @@ -49,44 +106,43 @@ {#Interpretation Interpretation} {#Export Export})) -(template [ ] +(template [ ] [(def: (Parser ) - (.named .any))] + (.named ))] - [source_parser "--source" Source] - [host_dependency_parser "--host_dependency" Host_Dependency] - [library_parser "--library" Library] - [target_parser "--target" Target] - [module_parser "--module" Module] + [host_dependency_parser "--host_dependency" Host_Dependency .any] + [library_parser "--library" Library .any] + [compiler_parser "--compiler" Compiler (.then ..compiler_parser' .any)] + [source_parser "--source" Source .any] + [target_parser "--target" Target .any] + [module_parser "--module" Module .any] ) (def: .public service (Parser Service) - ($_ <>.or - (<>.after (.this "build") - ($_ <>.and - (<>.some ..source_parser) - (<>.some ..host_dependency_parser) - (<>.some ..library_parser) - ..target_parser - ..module_parser)) - (<>.after (.this "repl") - ($_ <>.and - (<>.some ..source_parser) - (<>.some ..host_dependency_parser) - (<>.some ..library_parser) - ..target_parser - ..module_parser)) - (<>.after (.this "export") - ($_ <>.and - (<>.some ..source_parser) - ..target_parser)) - )) + (let [compiler (: (Parser Compilation) + ($_ <>.and + (<>.some ..host_dependency_parser) + (<>.some ..library_parser) + (<>.some ..compiler_parser) + (<>.some ..source_parser) + ..target_parser + ..module_parser))] + ($_ <>.or + (<>.after (.this "build") + compiler) + (<>.after (.this "repl") + compiler) + (<>.after (.this "export") + ($_ <>.and + (<>.some ..source_parser) + ..target_parser)) + ))) (def: .public target (-> Service Target) - (|>> (case> (^or {#Compilation [sources host_dependencies libraries target module]} - {#Interpretation [sources host_dependencies libraries target module]} + (|>> (case> (^or {#Compilation [host_dependencies libraries compilers sources target module]} + {#Interpretation [host_dependencies libraries compilers sources target module]} {#Export [sources target]}) target))) diff --git a/stdlib/source/library/lux/tool/compiler/meta/packager/ruby.lux b/stdlib/source/library/lux/tool/compiler/meta/packager/ruby.lux index 658c0e886..1bfd062fe 100644 --- a/stdlib/source/library/lux/tool/compiler/meta/packager/ruby.lux +++ b/stdlib/source/library/lux/tool/compiler/meta/packager/ruby.lux @@ -33,10 +33,10 @@ ["[0]" archive {"+" Output} [registry {"+" Registry}] ["[0]" artifact] - ["[0]" module] - ["[0]" descriptor] - ["[0]" document {"+" Document}] - ["[0]" unit]] + ["[0]" unit] + ["[0]" module + ["[0]" descriptor] + ["[0]" document {"+" Document}]]] ["[0]" cache "_" ["[1]/[0]" module {"+" Order}] ["[1]/[0]" artifact]] diff --git a/stdlib/source/program/aedifex/command/build.lux b/stdlib/source/program/aedifex/command/build.lux index ba461d461..8570207be 100644 --- a/stdlib/source/program/aedifex/command/build.lux +++ b/stdlib/source/program/aedifex/command/build.lux @@ -1,6 +1,6 @@ (.using [library - [lux "*" + [lux {"-" Lux} ["[0]" ffi {"+" import:}] [abstract [order {"+" Order}] @@ -20,12 +20,13 @@ ["[0]" dictionary {"+" Dictionary}] ["[0]" set]]] [math - [number + [number {"+" hex} ["n" nat] ["i" int]]] [tool [compiler [meta + ["[0]" cli] ["[0]" packager ["[0]_[1]" ruby]]]]] [world @@ -68,17 +69,17 @@ Name )] - ["lux-jvm" jvm_compiler_name] - ["lux-js" js_compiler_name] - ["lux-python" python_compiler_name] - ["lux-lua" lua_compiler_name] - ["lux-ruby" ruby_compiler_name] + ["lux-jvm" jvm_lux_name] + ["lux-js" js_lux_name] + ["lux-python" python_lux_name] + ["lux-lua" lua_lux_name] + ["lux-ruby" ruby_lux_name] ) -(exception: .public no_available_compiler) +(exception: .public no_available_lux) (exception: .public no_specified_program) -(type: .public Compiler +(type: .public Lux (Variant {#JVM Dependency} {#JS Dependency} @@ -92,27 +93,27 @@ (list.only (|>> product.left (same? dependency) not)) (dictionary.of_list ///dependency.hash))) -(def: (compiler resolution compiler_dependency) - (-> Resolution Dependency (Try [Resolution Compiler])) - (let [[[compiler_group compiler_name compiler_version] compiler_type] compiler_dependency] - (case (..dependency_finder compiler_group compiler_name resolution) +(def: (lux resolution lux_dependency) + (-> Resolution Dependency (Try [Resolution Lux])) + (let [[[lux_group lux_name lux_version] lux_type] lux_dependency] + (case (..dependency_finder lux_group lux_name resolution) {.#Some dependency} - (case compiler_name + (case lux_name (^template [ ] [(^ (static )) {try.#Success [(..remove_dependency dependency resolution) { dependency}]}]) - ([#JVM ..jvm_compiler_name] - [#JS ..js_compiler_name] - [#Python ..python_compiler_name] - [#Lua ..lua_compiler_name] - [#Ruby ..ruby_compiler_name]) + ([#JVM ..jvm_lux_name] + [#JS ..js_lux_name] + [#Python ..python_lux_name] + [#Lua ..lua_lux_name] + [#Ruby ..ruby_lux_name]) _ - (exception.except ..no_available_compiler [])) + (exception.except ..no_available_lux [])) _ - (exception.except ..no_available_compiler [])))) + (exception.except ..no_available_lux [])))) (def: (path fs home dependency) (All (_ !) (-> (file.System !) Path Dependency Path)) @@ -266,7 +267,7 @@ runtime))) (def: .public (do! console program fs shell resolution) - (-> (Console Async) (Program Async) (file.System Async) (Shell Async) Resolution (Command [Exit Compiler Path])) + (-> (Console Async) (Program Async) (file.System Async) (Shell Async) Resolution (Command [Exit Lux Path])) (function (_ profile) (let [target (value@ ///.#target profile)] (case (value@ ///.#program profile) @@ -279,32 +280,33 @@ .let [home (# program home) working_directory (# program directory)]] (do ///action.monad - [[resolution compiler] (async#in (..compiler resolution (value@ ///.#compiler profile))) + [[resolution lux] (async#in (..lux resolution (value@ ///.#lux profile))) .let [host_dependencies (..host_dependencies fs home resolution) - [[command compiler_params] output] (case compiler - {#JVM dependency} - [(|> (value@ ///.#java profile) - (with@ ///runtime.#parameters (list "program._")) - (with_jvm_class_path {.#Item (..path fs home dependency) host_dependencies})) - "program.jar"] - - (^template [ ] - [{ dependency} - [(|> dependency - (..path fs home) - (///runtime.for (value@ profile))) - ]]) - ([#JS ///.#js "program.js"] - [#Python ///.#java "program.py"] - [#Lua ///.#java "program.lua"] - [#Ruby ///.#java (file.rooted fs "program" ruby_packager.main_file)])) + [[command lux_params] output] (case lux + {#JVM dependency} + [(|> (value@ ///.#java profile) + (with@ ///runtime.#parameters (list "program._")) + (with_jvm_class_path {.#Item (..path fs home dependency) host_dependencies})) + "program.jar"] + + (^template [ ] + [{ dependency} + [(|> dependency + (..path fs home) + (///runtime.for (value@ profile))) + ]]) + ([#JS ///.#js "program.js"] + [#Python ///.#java "program.py"] + [#Lua ///.#java "program.lua"] + [#Ruby ///.#java (file.rooted fs "program" ruby_packager.main_file)])) / (# fs separator) cache_directory (format working_directory / target)] _ (console.write_line ..start console) - .let [full_parameters (list.together (list compiler_params + .let [full_parameters (list.together (list lux_params (list "build") (..plural "--library" (..libraries fs home resolution)) (..plural "--host_dependency" host_dependencies) + (..plural "--compiler" (list#each cli.compiler_format (value@ ///.#compilers profile))) (..plural "--source" (set.list (value@ ///.#sources profile))) (..singular "--target" cache_directory) (..singular "--module" program_module)))] @@ -320,5 +322,5 @@ ..failure) console)] (in [exit - compiler + lux (format cache_directory / output)]))))))) diff --git a/stdlib/source/program/aedifex/command/deps.lux b/stdlib/source/program/aedifex/command/deps.lux index 4e32a73b1..85c6fbb57 100644 --- a/stdlib/source/program/aedifex/command/deps.lux +++ b/stdlib/source/program/aedifex/command/deps.lux @@ -42,7 +42,7 @@ (do async.monad [.let [dependencies (|> (value@ ///.#dependencies profile) set.list - {.#Item (value@ ///.#compiler profile)})] + {.#Item (value@ ///.#lux profile)})] [local_successes local_failures cache] (///dependency/resolution.all console (list local) new_repository diff --git a/stdlib/source/program/aedifex/format.lux b/stdlib/source/program/aedifex/format.lux index 8f3e63706..54e1ed57f 100644 --- a/stdlib/source/program/aedifex/format.lux +++ b/stdlib/source/program/aedifex/format.lux @@ -1,22 +1,26 @@ (.using - [library - [lux "*" - [data - ["[0]" text ("[1]#[0]" equivalence)] - [collection - ["[0]" dictionary {"+" Dictionary}] - ["[0]" list ("[1]#[0]" monad)] - ["[0]" set {"+" Set}]]] - [macro - ["[0]" code] - ["[0]" template]]]] - ["[0]" // "_" - ["/" profile] - ["[1][0]" runtime {"+" Runtime}] - ["[1][0]" project {"+" Project}] - ["[1][0]" dependency {"+" Dependency}] - ["[1][0]" artifact {"+" Artifact} - ["[1]/[0]" type]]]) + [library + [lux "*" + [data + ["[0]" text ("[1]#[0]" equivalence)] + [collection + ["[0]" dictionary {"+" Dictionary}] + ["[0]" list ("[1]#[0]" monad)] + ["[0]" set {"+" Set}]]] + [macro + ["[0]" code] + ["[0]" template]] + [tool + [compiler + [meta + [cli {"+" Compiler}]]]]]] + ["[0]" // "_" + ["/" profile] + ["[1][0]" runtime {"+" Runtime}] + ["[1][0]" project {"+" Project}] + ["[1][0]" dependency {"+" Dependency}] + ["[1][0]" artifact {"+" Artifact} + ["[1]/[0]" type]]]) (type: .public (Format a) (-> a Code)) @@ -141,6 +145,14 @@ (` [(~ (code.text program)) (~+ (list#each code.text parameters))])) +(def: (compiler [definition parameters]) + (Format Compiler) + (` [(~ (code.symbol definition)) + (~+ (list#each code.text parameters))])) + +(def: .public lux_compiler_label + "lux") + (def: (profile value) (Format /.Profile) (`` (|> ..empty @@ -149,7 +161,8 @@ (..on_maybe "info" (value@ /.#info value) ..info) (..on_set "repositories" (value@ /.#repositories value) code.text) (..on_set "dependencies" (value@ /.#dependencies value) ..dependency) - (dictionary.has "compiler" (..dependency (value@ /.#compiler value))) + (dictionary.has ..lux_compiler_label (..dependency (value@ /.#lux value))) + (..on_list "compilers" (value@ /.#compilers value) ..compiler) (..on_set "sources" (value@ /.#sources value) code.text) (dictionary.has "target" (code.text (value@ /.#target value))) (..on_maybe "program" (value@ /.#program value) code.text) diff --git a/stdlib/source/program/aedifex/parser.lux b/stdlib/source/program/aedifex/parser.lux index 44c16133f..52a9a292c 100644 --- a/stdlib/source/program/aedifex/parser.lux +++ b/stdlib/source/program/aedifex/parser.lux @@ -1,32 +1,35 @@ (.using - [library - [lux {"-" Module type} - [abstract - [monad {"+" do}]] - [control - ["<>" parser - ["<[0]>" code {"+" Parser}]]] - [data - ["[0]" text] - [collection - ["[0]" dictionary {"+" Dictionary}] - ["[0]" set {"+" Set}]]] - [tool - [compiler - [meta - [archive - [descriptor {"+" Module}]]]]] - [world - [net {"+" URL}]]]] - ["[0]" // "_" - ["/" profile] - ["[1][0]" runtime {"+" Runtime}] - ["[1][0]" project {"+" Project}] - ["[1][0]" dependency] - ["[1][0]" repository "_" - ["[1]" remote]] - ["[1][0]" artifact {"+" Artifact} - ["[1]/[0]" type]]]) + [library + [lux {"-" Module type} + [abstract + [monad {"+" do}]] + [control + ["<>" parser + ["<[0]>" code {"+" Parser}]]] + [data + ["[0]" text] + [collection + ["[0]" dictionary {"+" Dictionary}] + ["[0]" set {"+" Set}]]] + [tool + [compiler + [meta + [cli {"+" Compiler}] + [archive + [module + [descriptor {"+" Module}]]]]]] + [world + [net {"+" URL}]]]] + ["[0]" // "_" + ["/" profile] + ["[1][0]" runtime {"+" Runtime}] + ["[1][0]" project {"+" Project}] + ["[1][0]" dependency] + ["[1][0]" format] + ["[1][0]" repository "_" + ["[1]" remote]] + ["[1][0]" artifact {"+" Artifact} + ["[1]/[0]" type]]]) (def: (as_input input) (-> (Maybe Code) (List Code)) @@ -155,6 +158,14 @@ (<>.else //artifact/type.lux_library ..type) ))) +(def: compiler + (Parser Compiler) + (.tuple + ($_ <>.and + .global_symbol + (<>.some .text) + ))) + (def: source (Parser /.Source) .text) @@ -203,9 +214,12 @@ (|> (..plural input "dependencies" ..dependency) (# ! each (set.of_list //dependency.hash)) (<>.else (set.empty //dependency.hash)))) - ^compiler (|> ..dependency - (..singular input "compiler") - (<>.else /.default_compiler)) + ^lux (|> ..dependency + (..singular input //format.lux_compiler_label) + (<>.else /.default_compiler)) + ^compilers (|> ..compiler + (..plural input "compilers") + (<>.else (list))) ^sources (: (Parser (Set /.Source)) (|> (..plural input "sources" ..source) (# ! each (set.of_list text.hash)) @@ -245,7 +259,8 @@ ^info ^repositories ^dependencies - ^compiler + ^lux + ^compilers ^sources ^target ^program diff --git a/stdlib/source/program/aedifex/profile.lux b/stdlib/source/program/aedifex/profile.lux index cdcfd3af5..eeabf5f82 100644 --- a/stdlib/source/program/aedifex/profile.lux +++ b/stdlib/source/program/aedifex/profile.lux @@ -1,40 +1,44 @@ (.using - [library - [lux {"-" Info Source Module} - [abstract - [monoid {"+" Monoid}] - [equivalence {"+" Equivalence}]] - [control - ["[0]" maybe ("[1]#[0]" monoid)] - ["[0]" exception {"+" exception:}]] - [data - ["[0]" product] - ["[0]" text ("[1]#[0]" equivalence)] - [collection - ["[0]" dictionary {"+" Dictionary}] - ["[0]" list ("[1]#[0]" monoid)] - ["[0]" set {"+" Set}]]] - [macro - ["[0]" template]] - [world - [net {"+" URL}] - [file {"+" Path}]] - [tool - [compiler - [meta - [archive - [descriptor {"+" Module}]]]]]]] - [// - ["[0]" runtime {"+" Runtime} ("[1]#[0]" equivalence)] - ["[0]" dependency {"+" Dependency} ("[1]#[0]" equivalence)] - ["[0]" artifact {"+" Artifact} - ["[0]" type]] - [repository - [remote {"+" Address}]]]) + [library + [lux {"-" Info Source Module} + [abstract + [monoid {"+" Monoid}] + [equivalence {"+" Equivalence}]] + [control + ["[0]" maybe ("[1]#[0]" monoid)] + ["[0]" exception {"+" exception:}]] + [data + ["[0]" product] + ["[0]" text ("[1]#[0]" equivalence)] + [collection + ["[0]" dictionary {"+" Dictionary}] + ["[0]" list ("[1]#[0]" monoid)] + ["[0]" set {"+" Set}]]] + [macro + ["[0]" template]] + [meta + ["[0]" symbol]] + [world + [net {"+" URL}] + [file {"+" Path}]] + [tool + [compiler + [meta + ["[0]" cli {"+" Compiler}] + [archive + [module + [descriptor {"+" Module}]]]]]]]] + [// + ["[0]" runtime {"+" Runtime} ("[1]#[0]" equivalence)] + ["[0]" dependency {"+" Dependency} ("[1]#[0]" equivalence)] + ["[0]" artifact {"+" Artifact} + ["[0]" type]] + [repository + [remote {"+" Address}]]]) (def: .public default_compiler Dependency - [dependency.#artifact ["com.github.luxlang" "lux-jvm" "0.6.0"] + [dependency.#artifact ["com.github.luxlang" "lux-jvm" "0.6.5"] dependency.#type type.jvm_library]) (type: .public Distribution @@ -162,7 +166,8 @@ #info (Maybe Info) #repositories (Set Address) #dependencies (Set Dependency) - #compiler Dependency + #lux Dependency + #compilers (List Compiler) #sources (Set Source) #target Target #program (Maybe Module) @@ -187,8 +192,10 @@ set.equivalence ... #dependencies set.equivalence - ... #compiler + ... #lux dependency.equivalence + ... #compilers + (list.equivalence cli.compiler_equivalence) ... #sources set.equivalence ... #target @@ -219,7 +226,8 @@ #info {.#None} #repositories (set.empty text.hash) #dependencies (set.empty dependency.hash) - #compiler default_compiler + #lux default_compiler + #compilers (list) #sources (set.empty text.hash) #target ..default_target #program {.#None} @@ -241,9 +249,10 @@ #info (maybe#composite (value@ #info override) (value@ #info baseline)) #repositories (set.union (value@ #repositories baseline) (value@ #repositories override)) #dependencies (set.union (value@ #dependencies baseline) (value@ #dependencies override)) - #compiler (if (dependency#= ..default_compiler (value@ #compiler override)) - (value@ #compiler baseline) - (value@ #compiler override)) + #lux (if (dependency#= ..default_compiler (value@ #lux override)) + (value@ #lux baseline) + (value@ #lux override)) + #compilers (list#composite (value@ #compilers baseline) (value@ #compilers override)) #sources (set.union (value@ #sources baseline) (value@ #sources override)) #target (if (text#= ..default_target (value@ #target baseline)) (value@ #target override) diff --git a/stdlib/source/program/compositor.lux b/stdlib/source/program/compositor.lux index 0d90a15dc..b2a5f4d15 100644 --- a/stdlib/source/program/compositor.lux +++ b/stdlib/source/program/compositor.lux @@ -152,7 +152,7 @@ (<| (or_crash! "Compilation failed:") ..timed (do (try.with async.monad) - [.let [[compilation_sources compilation_host_dependencies compilation_libraries compilation_target compilation_module] compilation] + [.let [[compilation_host_dependencies compilation_libraries compilation_compilers compilation_sources compilation_target compilation_module] compilation] import (/import.import (value@ platform.#&file_system platform) compilation_libraries) [state archive phase_wrapper] (:sharing [] (Platform ) diff --git a/stdlib/source/test/lux/target/python.lux b/stdlib/source/test/lux/target/python.lux index e936ba850..dc4a3871f 100644 --- a/stdlib/source/test/lux/target/python.lux +++ b/stdlib/source/test/lux/target/python.lux @@ -5,7 +5,10 @@ ["[0]" ffi] [abstract [monad {"+" do}] - ["[0]" predicate]] + ["[0]" predicate] + [\\specification + ["$[0]" equivalence] + ["$[0]" hash]]] [control ["[0]" maybe ("[1]#[0]" functor)] ["[0]" try {"+" Try} ("[1]#[0]" functor)]] @@ -125,6 +128,12 @@ [/.>= f.>=] [/.= f.=] )) + (_.cover [/.float/1] + (expression (|>> (:as Frac) (f.= subject)) + (/.float/1 (/.string (%.frac subject))))) + (_.cover [/.repr/1] + (expression (|>> (:as Text) (text#= (text.replaced "+" "" (%.frac subject)))) + (/.repr/1 (/.float subject)))) )))) (def: int/16 @@ -163,6 +172,12 @@ (expression (|>> (:as Frac) f.int (i.= expected)) (/.bit_shr (/.int (.int shift)) (/.int i16))))) + (_.cover [/.int/1] + (expression (|>> (:as Int) (i.= left)) + (/.int/1 (/.string (%.int left))))) + (_.cover [/.str/1] + (expression (|>> (:as Text) (text#= (text.replaced "+" "" (%.int left)))) + (/.str/1 (/.int left)))) )))) (def: test|array @@ -301,10 +316,15 @@ (def: .public test Test (do [! random.monad] - [] + [.let [random (# ! each /.int random.int)]] (<| (_.covering /._) (_.for [/.Code /.code]) ($_ _.and + (_.for [/.equivalence] + ($equivalence.spec /.equivalence random)) + (_.for [/.hash] + ($hash.spec /.hash random)) + (_.for [/.Expression] ..test|expression) )))) diff --git a/stdlib/source/test/lux/tool/compiler/language/lux/analysis.lux b/stdlib/source/test/lux/tool/compiler/language/lux/analysis.lux index ccca4213f..135ac5840 100644 --- a/stdlib/source/test/lux/tool/compiler/language/lux/analysis.lux +++ b/stdlib/source/test/lux/tool/compiler/language/lux/analysis.lux @@ -24,13 +24,14 @@ [number ["f" frac]]]]] ["[0]" / "_" - ["[1][0]" simple] ["[1][0]" complex] - ["[1][0]" pattern] + ["[1][0]" inference] ["[1][0]" macro] - ["[1][0]" type] ["[1][0]" module] - ["[1][0]" inference] + ["[1][0]" pattern] + ["[1][0]" scope] + ["[1][0]" simple] + ["[1][0]" type] [//// ["[1][0]" reference ["[2][0]" variable]] @@ -437,11 +438,12 @@ (bit#= (# /.equivalence = left right) (text#= (/.format left) (/.format right)))) - /simple.test /complex.test - /pattern.test + /inference.test /macro.test - /type.test /module.test - /inference.test + /pattern.test + /scope.test + /simple.test + /type.test )))) diff --git a/stdlib/source/test/lux/tool/compiler/language/lux/analysis/scope.lux b/stdlib/source/test/lux/tool/compiler/language/lux/analysis/scope.lux new file mode 100644 index 000000000..dbd1f83de --- /dev/null +++ b/stdlib/source/test/lux/tool/compiler/language/lux/analysis/scope.lux @@ -0,0 +1,203 @@ +(.using + [library + [lux "*" + ["_" test {"+" Test}] + [abstract + [monad {"+" do}]] + [control + [pipe {"+" case>}] + ["[0]" maybe ("[1]#[0]" functor)] + ["[0]" try ("[1]#[0]" functor)] + ["[0]" exception]] + [data + ["[0]" product] + [collection + ["[0]" list]]] + [math + ["[0]" random {"+" Random}] + [number + ["n" nat]]] + ["[0]" type "_" + ["$[1]" \\test]]]] + [\\library + ["[0]" / + ["/[1]" // + [// + [phase + ["[1][0]" extension]] + [/// + ["[1][0]" phase ("[1]#[0]" monad)] + [reference + ["[1][0]" variable {"+" Register Variable}]]]]]]] + ["$[0]" // "_" + ["[1][0]" type]]) + +(template [ ] + [(def: ( expected_type expected_register [actual_type actual_var]) + (-> Type Register [Type Variable] Bit) + (and (same? expected_type actual_type) + (case actual_var + { actual_register} + (n.= expected_register actual_register) + + _ + false)))] + + [local? //variable.#Local] + [foreign? //variable.#Foreign] + ) + +(def: .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [lux $//type.random_state + .let [state [//extension.#bundle //extension.empty + //extension.#state lux]] + name/0 (random.ascii/lower 1) + name/1 (random.ascii/lower 2) + type/0 ($type.random 0) + type/1 ($type.random 0)] + ($_ _.and + (_.cover [/.find] + (|> (/.find name/0) + /.with + (//phase.result state) + (try#each (|>> product.right + (case> {.#None} true + {.#Some _} false))) + (try.else false))) + (_.cover [/.with_local] + (|> (/.with_local [name/0 type/0] + (/.find name/0)) + /.with + (//phase.result state) + (try#each (|>> product.right + (maybe#each (..local? type/0 0)) + (maybe.else false))) + (try.else false))) + (_.cover [/.next] + (|> (<| (do [! //phase.monad] + [register/0 /.next]) + (/.with_local [name/0 type/0]) + (do ! + [var/0 (/.find name/0)]) + (do ! + [register/1 /.next]) + (/.with_local [name/1 type/1]) + (do ! + [var/1 (/.find name/1)]) + (in (do maybe.monad + [var/0 var/0 + var/1 var/1] + (in [[register/0 var/0] [register/1 var/1]])))) + /.with + (//phase.result state) + (try#each (|>> product.right + (maybe#each (function (_ [[register/0 var/0] [register/1 var/1]]) + (and (..local? type/0 register/0 var/0) + (..local? type/1 register/1 var/1)))) + (maybe.else false))) + (try.else false))) + (_.cover [/.no_scope] + (and (|> (/.with_local [name/0 type/0] + (//phase#in false)) + (//phase.result state) + (exception.otherwise (exception.match? /.no_scope))) + (|> (do //phase.monad + [_ /.next] + (in false)) + (//phase.result state) + (exception.otherwise (exception.match? /.no_scope))))) + (_.cover [/.reset] + (and (|> /.next + (/.with_local [name/0 type/0]) + /.with + (//phase.result state) + (try#each (|>> product.right + (n.= 1))) + (try.else false)) + (|> /.next + /.reset + (/.with_local [name/0 type/0]) + /.with + (//phase.result state) + (try#each (|>> product.right + (n.= 0))) + (try.else false)))) + (_.cover [/.drained] + (|> (function (_ [bundle state]) + {try.#Success [[bundle (with@ .#scopes (list) state)] + false]}) + (/.with_local [name/0 type/0]) + /.with + (//phase#each product.right) + (//phase.result state) + (exception.otherwise (exception.match? /.drained)))) + (_.cover [/.with] + (|> (<| /.with + (/.with_local [name/0 type/0]) + (do //phase.monad + [var/0' (/.find name/0) + [scope/1 var/0''] (/.with (/.find name/0))] + (<| //phase.lifted + try.of_maybe + (do maybe.monad + [var/0' var/0' + var/0'' var/0''] + (in [var/0' scope/1 var/0'']))))) + (//phase.result state) + (try#each (function (_ [scope/0 var/0' scope/1 var/0'']) + (and (local? type/0 0 var/0') + (n.= 0 (list.size (value@ [.#locals .#mappings] scope/0))) + (n.= 0 (list.size (value@ [.#captured .#mappings] scope/0))) + + (foreign? type/0 0 var/0'') + (n.= 0 (list.size (value@ [.#locals .#mappings] scope/1))) + (n.= 1 (list.size (value@ [.#captured .#mappings] scope/1)))))) + (try.else false))) + (_.cover [/.environment] + (let [(^open "list#[0]") (list.equivalence //variable.equivalence)] + (and (|> (<| /.with + (/.with_local [name/0 type/0]) + (/.with_local [name/1 type/1]) + (do //phase.monad + [[scope/1 _] (/.with (in []))] + (in (/.environment scope/1)))) + (//phase.result state) + (try#each (|>> product.right + (list#= (list)))) + (try.else false)) + (|> (<| /.with + (do [! //phase.monad] + [register/0 /.next]) + (/.with_local [name/0 type/0]) + (/.with_local [name/1 type/1]) + (do ! + [[scope/1 _] (/.with (/.find name/0))] + (in [register/0 (/.environment scope/1)]))) + (//phase.result state) + (try#each (function (_ [_ [register/0 environment]]) + (list#= (list {//variable.#Local register/0}) + environment))) + (try.else false)) + (|> (<| /.with + (do [! //phase.monad] + [register/0 /.next]) + (/.with_local [name/0 type/0]) + (do [! //phase.monad] + [register/1 /.next]) + (/.with_local [name/1 type/1]) + (do [! //phase.monad] + [[scope/1 _] (/.with (do ! + [_ (/.find name/1) + _ (/.find name/0)] + (in [])))] + (in [register/0 register/1 (/.environment scope/1)]))) + (//phase.result state) + (try#each (function (_ [_ [register/0 register/1 environment]]) + (list#= (list {//variable.#Local register/1} + {//variable.#Local register/0}) + environment))) + (try.else false))))) + )))) diff --git a/stdlib/source/test/lux/tool/compiler/language/lux/analysis/type.lux b/stdlib/source/test/lux/tool/compiler/language/lux/analysis/type.lux index 781a7f38f..2e63f1bc8 100644 --- a/stdlib/source/test/lux/tool/compiler/language/lux/analysis/type.lux +++ b/stdlib/source/test/lux/tool/compiler/language/lux/analysis/type.lux @@ -22,7 +22,7 @@ [/// ["[2][0]" phase]]]]]]) -(def: random_state +(def: .public random_state (Random Lux) (do random.monad [version random.nat diff --git a/stdlib/source/test/lux/tool/compiler/language/lux/phase/analysis/complex.lux b/stdlib/source/test/lux/tool/compiler/language/lux/phase/analysis/complex.lux index 89c341c2a..fcf0a556e 100644 --- a/stdlib/source/test/lux/tool/compiler/language/lux/phase/analysis/complex.lux +++ b/stdlib/source/test/lux/tool/compiler/language/lux/phase/analysis/complex.lux @@ -42,7 +42,8 @@ ["[2][0]" macro] ["[2][0]" type] ["[2][0]" module] - ["[2][0]" complex]] + ["[2][0]" complex] + ["[2][0]" scope]] [/// ["[1][0]" phase ("[1]#[0]" monad)] [meta @@ -488,7 +489,7 @@ (//phase.result state) (case> {try.#Success {.#None}} true - + _ false))))) (_.cover [/.order] @@ -499,7 +500,7 @@ (|> (do //phase.monad [_ (//module.declare_labels true slots/0 false :record:)] (/.order pattern_matching? input)) - //analysis.with_scope + //scope.with (//module.with_module 0 module) (//phase#each (|>> product.right product.right)) (//phase.result state) @@ -554,7 +555,7 @@ (|> (do //phase.monad [_ (//module.declare_labels true slots/0 false :record:)] (/.order pattern_matching? input)) - //analysis.with_scope + //scope.with (//module.with_module 0 module) (//phase.result state) (..failure? /.record_size_mismatch))))] @@ -574,7 +575,7 @@ [_ (//module.declare_labels true slots/0 false :record:) _ (//module.declare_labels true slots/1 false :record:)] (/.order pattern_matching? input)) - //analysis.with_scope + //scope.with (//module.with_module 0 module) (//phase.result state) (..failure? /.slot_does_not_belong_to_record))))] @@ -589,7 +590,7 @@ [_ (//module.declare_labels true slots false type)] (/.record ..analysis archive.empty tuple)) (//type.expecting type) - //analysis.with_scope + //scope.with (//module.with_module 0 module) (//phase#each (|>> product.right product.right)) (//phase.result state) @@ -601,7 +602,7 @@ [_ (//module.declare_labels true slots/0 false :record:)] (//type.inferring (/.record ..analysis archive.empty record))) - //analysis.with_scope + //scope.with (//module.with_module 0 module) (//phase#each (|>> product.right product.right)) (//phase.result state) diff --git a/stdlib/source/test/lux/tool/compiler/meta/cli.lux b/stdlib/source/test/lux/tool/compiler/meta/cli.lux index 7c5f0266e..5a128b0ff 100644 --- a/stdlib/source/test/lux/tool/compiler/meta/cli.lux +++ b/stdlib/source/test/lux/tool/compiler/meta/cli.lux @@ -15,12 +15,23 @@ [collection ["[0]" list ("[1]#[0]" monoid monad)]]] [math - ["[0]" random] + ["[0]" random {"+" Random}] [number - ["n" nat]]]]] + ["n" nat]]] + [meta + ["[0]" symbol "_" + ["$[1]" \\test]]]]] [\\library ["[0]" /]]) +(def: random_compiler + (Random /.Compiler) + (do [! random.monad] + [definition ($symbol.random 1 1) + amount (# ! each (n.% 5) random.nat) + parameters (random.list amount (random.ascii/lower 2))] + (in [definition parameters]))) + (def: .public test Test (<| (_.covering /._) @@ -33,10 +44,12 @@ libraries (random.list amount (random.ascii/lower 3)) target (random.ascii/lower 4) module (random.ascii/lower 5) + compilers (random.list amount ..random_compiler) .let [compilation' ($_ list#composite - (list#conjoint (list#each (|>> (list "--source")) sources)) (list#conjoint (list#each (|>> (list "--host_dependency")) host_dependencies)) (list#conjoint (list#each (|>> (list "--library")) libraries)) + (list#conjoint (list#each (|>> /.compiler_format (list "--compiler")) compilers)) + (list#conjoint (list#each (|>> (list "--source")) sources)) (list "--target" target) (list "--module" module)) export ($_ list#composite @@ -58,9 +71,10 @@ false))) (try.else false)))] - [/.Source /.#sources (list#= sources)] [/.Host_Dependency /.#host_dependencies (list#= host_dependencies)] [/.Library /.#libraries (list#= libraries)] + [/.Compiler /.#compilers (# (list.equivalence /.compiler_equivalence) = compilers)] + [/.Source /.#sources (list#= sources)] [/.Target /.#target (same? target)] [/.Module /.#module (same? module)] )) @@ -78,9 +92,10 @@ false))) (try.else false))] - [/.#sources (list#= sources)] [/.#host_dependencies (list#= host_dependencies)] [/.#libraries (list#= libraries)] + [/.#compilers (# (list.equivalence /.compiler_equivalence) = compilers)] + [/.#sources (list#= sources)] [/.#target (same? target)] [/.#module (same? module)] ))))) @@ -104,14 +119,16 @@ (`` (and (~~ (template [] [(same? target (/.target ))] - [{/.#Compilation [/.#sources sources - /.#host_dependencies host_dependencies + [{/.#Compilation [/.#host_dependencies host_dependencies /.#libraries libraries + /.#compilers compilers + /.#sources sources /.#target target /.#module module]}] - [{/.#Interpretation [/.#sources sources - /.#host_dependencies host_dependencies + [{/.#Interpretation [/.#host_dependencies host_dependencies /.#libraries libraries + /.#compilers compilers + /.#sources sources /.#target target /.#module module]}] [{/.#Export [sources target]}] -- cgit v1.2.3