From feacd79496ae9c76492d5a12d30b78724b642654 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 26 Jul 2022 18:08:04 -0400 Subject: Made inlined functions into first-class macros. --- stdlib/commands.md | 2 +- stdlib/source/documentation/lux.lux | 2 +- stdlib/source/documentation/lux/ffi.js.lux | 10 +- stdlib/source/documentation/lux/ffi.py.lux | 8 +- stdlib/source/documentation/lux/meta/macro.lux | 101 ++-- stdlib/source/library/lux.lux | 621 +++++++++------------ .../source/library/lux/control/function/inline.lux | 63 ++- stdlib/source/library/lux/debug.lux | 8 +- stdlib/source/library/lux/ffi/export.js.lux | 7 +- stdlib/source/library/lux/ffi/export.lua.lux | 7 +- stdlib/source/library/lux/ffi/export.py.lux | 7 +- stdlib/source/library/lux/ffi/export.rb.lux | 7 +- stdlib/source/library/lux/ffi/node_js.js.lux | 2 +- .../language/lux/phase/extension/analysis/jvm.lux | 120 ++-- .../language/lux/phase/generation/js/runtime.lux | 8 +- .../language/lux/phase/generation/lua/runtime.lux | 8 +- .../language/lux/phase/generation/ruby/runtime.lux | 10 +- stdlib/source/library/lux/meta/macro/pattern.lux | 110 ++-- stdlib/source/test/lux/control/function/inline.lux | 7 +- stdlib/source/test/lux/meta/extension.lux | 8 +- stdlib/source/test/lux/meta/target/js.lux | 8 +- stdlib/source/unsafe/lux/data/binary.lux | 56 +- 22 files changed, 569 insertions(+), 611 deletions(-) (limited to 'stdlib') diff --git a/stdlib/commands.md b/stdlib/commands.md index 874ee070a..0dbd64e87 100644 --- a/stdlib/commands.md +++ b/stdlib/commands.md @@ -92,7 +92,7 @@ cd ~/lux/stdlib/ \ cd ~/lux/stdlib/ \ && lux clean \ && lux with ruby with scriptum build \ -&& RUBY_THREAD_VM_STACK_SIZE=15700000 ruby ~/lux/stdlib/target/program.rb | tee ~/lux/documentation/library/standard/ruby.md +&& RUBY_THREAD_VM_STACK_SIZE=15700000 ruby ~/lux/stdlib/target/program/main.rb | tee ~/lux/documentation/library/standard/ruby.md ``` --- diff --git a/stdlib/source/documentation/lux.lux b/stdlib/source/documentation/lux.lux index 947fec8a1..1ffc31a13 100644 --- a/stdlib/source/documentation/lux.lux +++ b/stdlib/source/documentation/lux.lux @@ -893,6 +893,6 @@ /test.documentation /world.documentation]))) -(def _ +(.def _ (program inputs (io.io (debug.log! ($.markdown ..documentation))))) diff --git a/stdlib/source/documentation/lux/ffi.js.lux b/stdlib/source/documentation/lux/ffi.js.lux index cc4a6a8b2..a0e8edaef 100644 --- a/stdlib/source/documentation/lux/ffi.js.lux +++ b/stdlib/source/documentation/lux/ffi.js.lux @@ -54,14 +54,14 @@ [(= "function" (type_of (function (_ value) value)))]) - ($.definition /.constant + ($.definition /.global "Allows using definitions from the JavaScript host platform." - [(constant .Frac [Math PI])]) + [(global .Frac [Math PI])]) - ($.definition /.closure + ($.definition /.function (format "Allows defining closures/anonymous-functions in the form that JavaScript expects." \n "This is useful for adapting Lux functions for usage by JavaScript code.") [(is /.Function - (closure [left right] - (do_something (as Foo left) (as Bar right))))])] + (function [left right] + (do_something (as Foo left) (as Bar right))))])] [])) diff --git a/stdlib/source/documentation/lux/ffi.py.lux b/stdlib/source/documentation/lux/ffi.py.lux index 2701c47a1..d2da39eff 100644 --- a/stdlib/source/documentation/lux/ffi.py.lux +++ b/stdlib/source/documentation/lux/ffi.py.lux @@ -45,11 +45,11 @@ ("static" getsize [String] "io" "try" Integer) ("static" getmtime [String] "io" "try" Float))]) - ($.definition /.lambda + ($.definition /.function (format "Allows defining closures/anonymous-functions in the form that Python expects." \n "This is useful for adapting Lux functions for usage by Python code.") [(is ..Function - (lambda [left right] - (do_something (as Foo left) - (as Bar right))))])] + (function [left right] + (do_something (as Foo left) + (as Bar right))))])] [])) diff --git a/stdlib/source/documentation/lux/meta/macro.lux b/stdlib/source/documentation/lux/meta/macro.lux index 6e2557f3f..204efdd8c 100644 --- a/stdlib/source/documentation/lux/meta/macro.lux +++ b/stdlib/source/documentation/lux/meta/macro.lux @@ -18,19 +18,19 @@ (.List $.Module) ($.module /._ "" - [($.definition /.single_expansion - (format "Given code that requires applying a macro, does it once and returns the result." - \n "Otherwise, returns the code as-is.") - [(single_expansion syntax)]) + [... ($.definition /.single_expansion + ... (format "Given code that requires applying a macro, does it once and returns the result." + ... \n "Otherwise, returns the code as-is.") + ... [(single_expansion syntax)]) - ($.definition /.expansion - (format "Given code that requires applying a macro, expands repeatedly until no more direct macro-calls are left." - \n "Otherwise, returns the code as-is.") - [(expansion syntax)]) + ... ($.definition /.expansion + ... (format "Given code that requires applying a macro, expands repeatedly until no more direct macro-calls are left." + ... \n "Otherwise, returns the code as-is.") + ... [(expansion syntax)]) - ($.definition /.full_expansion - "Expands all macro-calls everywhere recursively, until only primitive/base code remains." - [(full_expansion syntax)]) + ... ($.definition /.full_expansion + ... "Expands all macro-calls everywhere recursively, until only primitive/base code remains." + ... [(full_expansion syntax)]) ($.definition /.symbol (format "Generates a unique name as a Code node (ready to be used in code templates)." @@ -52,48 +52,49 @@ (, g!_) ("jvm monitorexit" (, g!lock))] (, g!body))))))))]) - ($.definition /.one_expansion - "Works just like expand, except that it ensures that the output is a single Code token." - [(one_expansion token)]) + ... ($.definition /.one_expansion + ... "Works just like expand, except that it ensures that the output is a single Code token." + ... [(one_expansion token)]) - ($.definition /.log_single_expansion! - (format "Performs a macro-expansion and logs the resulting code." - \n "You can either use the resulting code, or omit them." - \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") - [(log_single_expansion! - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz))) - (log_single_expansion! "omit" - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz)))]) + ... ($.definition /.log_single_expansion! + ... (format "Performs a macro-expansion and logs the resulting code." + ... \n "You can either use the resulting code, or omit them." + ... \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") + ... [(log_single_expansion! + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz))) + ... (log_single_expansion! "omit" + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz)))]) - ($.definition /.log_expansion! - (format "Performs a macro-expansion and logs the resulting code." - \n "You can either use the resulting code, or omit them." - \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") - [(log_expansion! - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz))) - (log_expansion! "omit" - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz)))]) + ... ($.definition /.log_expansion! + ... (format "Performs a macro-expansion and logs the resulting code." + ... \n "You can either use the resulting code, or omit them." + ... \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") + ... [(log_expansion! + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz))) + ... (log_expansion! "omit" + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz)))]) - ($.definition /.log_full_expansion! - (format "Performs a macro-expansion and logs the resulting code." - \n "You can either use the resulting code, or omit them." - \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") - [(log_full_expansion! - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz))) - (log_full_expansion! "omit" - (def (foo bar baz) - (-> Int Int Int) - (int.+ bar baz)))])] + ... ($.definition /.log_full_expansion! + ... (format "Performs a macro-expansion and logs the resulting code." + ... \n "You can either use the resulting code, or omit them." + ... \n "By omitting them, this macro produces nothing (just like the lux.comment macro).") + ... [(log_full_expansion! + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz))) + ... (log_full_expansion! "omit" + ... (def (foo bar baz) + ... (-> Int Int Int) + ... (int.+ bar baz)))]) + ] [/local.documentation /syntax.documentation /template.documentation])) diff --git a/stdlib/source/library/lux.lux b/stdlib/source/library/lux.lux index fa0108157..be2a9eb33 100644 --- a/stdlib/source/library/lux.lux +++ b/stdlib/source/library/lux.lux @@ -4884,62 +4884,61 @@ {#None} (failure (..wrong_syntax_error (symbol ..loop))))))) -(def (with_expansions' label tokens target) - (-> Text (List Code) Code (List Code)) - (case target - (pattern#or [_ {#Bit _}] - [_ {#Nat _}] - [_ {#Int _}] - [_ {#Rev _}] - [_ {#Frac _}] - [_ {#Text _}]) - (list target) - - [_ {#Symbol [module name]}] - (if (and (text#= "" module) - (text#= label name)) - tokens - (list target)) - - (with_template#pattern [] - [[location { elems}] - (list [location { (list#conjoint (list#each (with_expansions' label tokens) elems))}])]) - ([#Form] - [#Variant] - [#Tuple]))) - (def .public with_expansions - (macro (_ tokens) - (case (parsed (andP (tupleP (someP bindingP)) (someP anyP)) tokens) - {#Some [bindings bodies]} - (loop (again [bindings bindings - map (is (Property_List (List Code)) - (list))]) - (let [normal (is (-> Code (List Code)) - (function (_ it) - (list#mix (function (_ [binding expansion] it) - (list#conjoint (list#each (with_expansions' binding expansion) it))) - (list it) - map)))] - (case bindings - {#Item [var_name expr] &rest} - (do meta#monad - [expansion (case (normal expr) - (list expr) - (single_expansion expr) + (let [with_expansions' (is (-> Text (List Code) Code (List Code)) + (function (with_expansions' label tokens target) + (case target + (pattern#or [_ {#Bit _}] + [_ {#Nat _}] + [_ {#Int _}] + [_ {#Rev _}] + [_ {#Frac _}] + [_ {#Text _}]) + (list target) + + [_ {#Symbol [module name]}] + (if (and (text#= "" module) + (text#= label name)) + tokens + (list target)) + + (with_template#pattern [] + [[location { elems}] + (list [location { (list#conjoint (list#each (with_expansions' label tokens) elems))}])]) + ([#Form] + [#Variant] + [#Tuple]))))] + (macro (_ tokens) + (case (parsed (andP (tupleP (someP bindingP)) (someP anyP)) tokens) + {#Some [bindings bodies]} + (loop (again [bindings bindings + map (is (Property_List (List Code)) + (list))]) + (let [normal (is (-> Code (List Code)) + (function (_ it) + (list#mix (function (_ [binding expansion] it) + (list#conjoint (list#each (with_expansions' binding expansion) it))) + (list it) + map)))] + (case bindings + {#Item [var_name expr] &rest} + (do meta#monad + [expansion (case (normal expr) + (list expr) + (single_expansion expr) - _ - (failure (all text#composite - "Incorrect expansion in with_expansions" - " | Binding: " (text#encoded var_name) - " | Expression: " (code#encoded expr))))] - (again &rest (property#with var_name expansion map))) - - {#End} - (at meta#monad #in (list#conjoint (list#each normal bodies)))))) - - {#None} - (failure (..wrong_syntax_error (symbol ..with_expansions)))))) + _ + (failure (all text#composite + "Incorrect expansion in with_expansions" + " | Binding: " (text#encoded var_name) + " | Expression: " (code#encoded expr))))] + (again &rest (property#with var_name expansion map))) + + {#End} + (at meta#monad #in (list#conjoint (list#each normal bodies)))))) + + {#None} + (failure (..wrong_syntax_error (symbol ..with_expansions))))))) (def (flat_alias type) (-> Type Type) @@ -4960,136 +4959,58 @@ _ type)) -(def (static_simple_literal name) - (-> Symbol (Meta Code)) - (do meta#monad - [type+value (definition_value name) - .let [[type value] type+value]] - (case (flat_alias type) - (with_template#pattern [ ] - [{#Named ["library/lux" ] _} - (in ( (as value)))]) - (["Bit" Bit bit$] - ["Nat" Nat nat$] - ["Int" Int int$] - ["Rev" Rev rev$] - ["Frac" Frac frac$] - ["Text" Text text$]) - - _ - (failure (text#composite "Cannot anti-quote type: " (symbol#encoded name)))))) - -(def (static_literal token) - (-> Code (Meta Code)) - (case token - [_ {#Symbol [def_module def_name]}] - (if (text#= "" def_module) - (do meta#monad - [current_module current_module_name] - (static_simple_literal [current_module def_name])) - (static_simple_literal [def_module def_name])) - - (with_template#pattern [] - [[meta { parts}] - (do meta#monad - [=parts (monad#each meta#monad static_literal parts)] - (in [meta { =parts}]))]) - ([#Form] - [#Variant] - [#Tuple]) - - _ - (meta#in token) - ... TODO: Figure out why this doesn't work: - ... (at meta#monad in token) - )) - (def .public static - (macro (_ tokens) - (case tokens - (list pattern) - (do meta#monad - [pattern' (static_literal pattern)] - (in (list pattern'))) - - _ - (failure (..wrong_syntax_error (symbol ..static)))))) - -(type Multi_Level_Case - [Code (List [Code Code])]) - -(def (case_level^ level) - (-> Code (Meta [Code Code])) - (meta#in (case level - [_ {#Tuple (list expr binding)}] - [expr binding] - - _ - [level (` #1)]))) - -(def (multi_level_case^ levels) - (-> (List Code) (Meta Multi_Level_Case)) - (case levels - {#End} - (failure "Multi-level patterns cannot be empty.") - - {#Item init extras} - (do meta#monad - [extras' (monad#each meta#monad case_level^ extras)] - (in [init extras'])))) - -(def (multi_level_case$ g!_ [[init_pattern levels] body]) - (-> Code [Multi_Level_Case Code] (List Code)) - (let [inner_pattern_body (list#mix (function (_ [calculation pattern] success) - (let [bind? (case pattern - [_ {#Symbol _}] - #1 - - _ - #0)] - (` (case (, calculation) - (, pattern) - (, success) - - (,* (if bind? - (list) - (list g!_ (` {.#None})))))))) - (` {.#Some (, body)}) - (is (List [Code Code]) (list#reversed levels)))] - (list init_pattern inner_pattern_body))) - -(def pattern#multi - (pattern - (macro (_ tokens) - (case tokens - (list#partial [_meta {#Form levels}] body next_branches) - (do meta#monad - [mlc (multi_level_case^ levels) - .let [initial_bind? (case mlc - [[_ {#Symbol _}] _] - #1 + (let [simple_literal (is (-> Symbol (Meta Code)) + (function (simple_literal name) + (do meta#monad + [type+value (definition_value name) + .let [[type value] type+value]] + (case (flat_alias type) + (with_template#pattern [ ] + [{#Named ["library/lux" ] _} + (in ( (as value)))]) + (["Bit" Bit bit$] + ["Nat" Nat nat$] + ["Int" Int int$] + ["Rev" Rev rev$] + ["Frac" Frac frac$] + ["Text" Text text$]) + + _ + (failure (text#composite "Cannot anti-quote type: " (symbol#encoded name))))))) + literal (is (-> Code (Meta Code)) + (function (literal token) + (case token + [_ {#Symbol [def_module def_name]}] + (if (text#= "" def_module) + (do meta#monad + [current_module current_module_name] + (simple_literal [current_module def_name])) + (simple_literal [def_module def_name])) - _ - #0)] - expected ..expected_type - g!temp (..generated_symbol "temp")] - (in (list g!temp - (` ({{.#Some (, g!temp)} - (, g!temp) - - {.#None} - (case (, g!temp) - (,* next_branches))} - ("lux type check" {.#Apply (, (type_code expected)) Maybe} - (case (, g!temp) - (,* (multi_level_case$ g!temp [mlc body])) - - (,* (if initial_bind? - (list) - (list g!temp (` {.#None}))))))))))) - - _ - (failure (..wrong_syntax_error (symbol ..pattern#multi))))))) + (with_template#pattern [] + [[meta { parts}] + (do meta#monad + [=parts (monad#each meta#monad literal parts)] + (in [meta { =parts}]))]) + ([#Form] + [#Variant] + [#Tuple]) + + _ + (meta#in token) + ... TODO: Figure out why this doesn't work: + ... (at meta#monad in token) + )))] + (macro (_ tokens) + (case tokens + (list pattern) + (do meta#monad + [pattern' (literal pattern)] + (in (list pattern'))) + + _ + (failure (..wrong_syntax_error (symbol ..static))))))) (def .public (same? reference sample) (All (_ a) @@ -5107,24 +5028,22 @@ _ (failure (..wrong_syntax_error (symbol ..as_expected)))))) -(def location - (Meta Location) - (function (_ compiler) - {#Right [compiler (the #location compiler)]})) - (def .public undefined - (macro (_ tokens) - (case tokens - {#End} - (do meta#monad - [location ..location - .let [[module line column] location - location (all "lux text concat" (text#encoded module) "," (nat#encoded line) "," (nat#encoded column)) - message (all "lux text concat" "Undefined behavior @ " location)]] - (in (list (` (..panic! (, (text$ message))))))) - - _ - (failure (..wrong_syntax_error (symbol ..undefined)))))) + (let [location (is (Meta Location) + (function (_ compiler) + {#Right [compiler (the #location compiler)]}))] + (macro (_ tokens) + (case tokens + {#End} + (do meta#monad + [location location + .let [[module line column] location + location (all "lux text concat" (text#encoded module) "," (nat#encoded line) "," (nat#encoded column)) + message (all "lux text concat" "Undefined behavior @ " location)]] + (in (list (` (..panic! (, (text$ message))))))) + + _ + (failure (..wrong_syntax_error (symbol ..undefined))))))) (def .public type_of (macro (_ tokens) @@ -5143,42 +5062,43 @@ _ (failure (..wrong_syntax_error (symbol ..type_of)))))) -(def (templateP tokens) - (-> (List Code) (Maybe [Text (List Text) (List Code)])) - (do maybe#monad - [% (local_declarationP tokens) - .let' [[tokens [name parameters]] %] - % (tupleP (someP anyP) tokens) - .let' [[tokens templates] %] - _ (endP tokens)] - (in [name parameters templates]))) - (def .public template - (macro (_ tokens) - (case (templateP tokens) - {#Some [name args input_templates]} - (do meta#monad - [g!tokens (..generated_symbol "tokens") - g!compiler (..generated_symbol "compiler") - g!_ (..generated_symbol "_") - .let [rep_env (list#each (function (_ arg) - [arg (` ((,' ,) (, (local$ arg))))]) - args)] - this_module current_module_name] - (in (list (` (..macro ((, (local$ name)) (, g!tokens) (, g!compiler)) - (case (, g!tokens) - (list (,* (list#each local$ args))) - {.#Right [(, g!compiler) - (list (,* (list#each (function (_ template) - (` (`' (, (with_replacements rep_env - template))))) - input_templates)))]} - - (, g!_) - {.#Left "Invalid syntax."})))))) + (let [templateP (is (-> (List Code) (Maybe [Text (List Text) (List Code)])) + (function (_ tokens) + (do maybe#monad + [% (local_declarationP tokens) + .let' [[tokens [name parameters]] %] + % (tupleP (someP anyP) tokens) + .let' [[tokens templates] %] + _ (endP tokens)] + (in [name parameters templates])))) + simple_replacement_environment (is (-> (List Text) Replacement_Environment) + (list#each (function (_ arg) + [arg (` ((,' ,) (, (local$ arg))))]))) + instantiated_template (is (-> Replacement_Environment Code Code) + (function (_ replacement_environment template) + (` (`' (, (with_replacements replacement_environment + template))))))] + (macro (_ tokens) + (case (templateP tokens) + {#Some [name args input_templates]} + (do meta#monad + [g!tokens (..generated_symbol "tokens") + g!compiler (..generated_symbol "compiler") + g!_ (..generated_symbol "_") + this_module ..current_module_name] + (in (list (` (..macro ((, (local$ name)) (, g!tokens) (, g!compiler)) + (case (, g!tokens) + (list (,* (list#each local$ args))) + {.#Right [(, g!compiler) + (list (,* (list#each (instantiated_template (simple_replacement_environment args)) + input_templates)))]} + + (, g!_) + {.#Left "Invalid syntax."})))))) - {#None} - (failure (..wrong_syntax_error (symbol ..template)))))) + {#None} + (failure (..wrong_syntax_error (symbol ..template))))))) (with_template [ ] [(def .public @@ -5198,76 +5118,73 @@ (def .public char (macro (_ tokens compiler) (case tokens - (pattern#multi (list [_ {#Text input}]) - (|> input "lux text size" ("lux i64 =" 1))) - (|> input ("lux text char" 0) - nat$ list - [compiler] {#Right}) + (list [_ {#Text input}]) + (if (|> input "lux text size" ("lux i64 =" 1)) + (|> input ("lux text char" 0) + nat$ list + [compiler] {#Right}) + {#Left (..wrong_syntax_error (symbol ..char))}) _ {#Left (..wrong_syntax_error (symbol ..char))}))) -(def target - (Meta Text) - (function (_ compiler) - {#Right [compiler (the [#info #target] compiler)]})) - -(def (platform_name choice) - (-> Code (Meta Text)) - (case choice - [_ {#Text platform}] - (..meta#in platform) - - [_ {#Symbol symbol}] - (do meta#monad - [symbol (..global_symbol symbol) - type+value (..definition_value symbol) - .let [[type value] type+value]] - (case (..flat_alias type) - (pattern#or {#Primitive "#Text" {#End}} - {#Named ["library/lux" "Text"] {#Primitive "#Text" {#End}}}) - (in (as ..Text value)) - - _ - (failure (all text#composite - "Invalid target platform (must be a value of type Text): " (symbol#encoded symbol) - " : " (..code#encoded (..type_code type)))))) - - _ - (failure (all text#composite - "Invalid target platform syntax: " (..code#encoded choice) - \n "Must be either a text literal or a symbol.")))) - -(def (target_pick target options default) - (-> Text (List [Code Code]) (Maybe Code) (Meta (List Code))) - (case options - {#End} - (case default - {#None} - (failure (all text#composite "No code for target platform: " target)) - - {#Some default} - (meta#in (list default))) - - {#Item [key pick] options'} - (do meta#monad - [platform (..platform_name key)] - (if (text#= target platform) - (meta#in (list pick)) - (target_pick target options' default))))) - (def .public for - (macro (_ tokens) - (case (..parsed (..andP (..someP (..andP ..anyP ..anyP)) - (..maybeP ..anyP)) - tokens) - {.#Some [options default]} - (do meta#monad - [target ..target] - (target_pick target options default)) + (let [target (is (Meta Text) + (function (_ compiler) + {#Right [compiler (the [#info #target] compiler)]})) + platform_name (is (-> Code (Meta Text)) + (function (_ choice) + (case choice + [_ {#Text platform}] + (..meta#in platform) + + [_ {#Symbol symbol}] + (do meta#monad + [symbol (..global_symbol symbol) + type+value (..definition_value symbol) + .let [[type value] type+value]] + (case (..flat_alias type) + (pattern#or {#Primitive "#Text" {#End}} + {#Named ["library/lux" "Text"] {#Primitive "#Text" {#End}}}) + (in (as ..Text value)) - {.#None} - (failure (..wrong_syntax_error (symbol ..for)))))) + _ + (failure (all text#composite + "Invalid target platform (must be a value of type Text): " (symbol#encoded symbol) + " : " (..code#encoded (..type_code type)))))) + + _ + (failure (all text#composite + "Invalid target platform syntax: " (..code#encoded choice) + \n "Must be either a text literal or a symbol."))))) + target_pick (is (-> Text (List [Code Code]) (Maybe Code) (Meta (List Code))) + (function (target_pick target options default) + (case options + {#End} + (case default + {#None} + (failure (all text#composite "No code for target platform: " target)) + + {#Some default} + (meta#in (list default))) + + {#Item [key pick] options'} + (do meta#monad + [platform (platform_name key)] + (if (text#= target platform) + (meta#in (list pick)) + (target_pick target options' default))))))] + (macro (_ tokens) + (case (..parsed (..andP (..someP (..andP ..anyP ..anyP)) + (..maybeP ..anyP)) + tokens) + {.#Some [options default]} + (do meta#monad + [target target] + (target_pick target options default)) + + {.#None} + (failure (..wrong_syntax_error (symbol ..for))))))) ... TODO: Delete "scope_type_vars" (including the #scope_type_vars Lux state) and "parameter" ASAP. (for "{old}" (these (def (scope_type_vars state) @@ -5296,40 +5213,39 @@ (failure (..wrong_syntax_error (symbol ..$))))))) (these (def .public parameter ""))) -(def (refer_code imported_module alias referrals) - (-> Text Text (List Referral) Code) - (` (..refer (, (text$ imported_module)) - (, (text$ alias)) - (,* (list#each (function (_ [macro parameters]) - (` ((, (symbol$ macro)) (,* parameters)))) - referrals))))) - (def .public require - (macro (_ _imports) - (do meta#monad - [current_module ..current_module_name - imports (imports_parser #0 current_module {#End} _imports) - .let [=imports (|> imports - (list#each (is (-> Importation Code) - (function (_ [module_name m_alias =refer]) - (` [(, (text$ module_name)) (, (text$ (..maybe#else "" m_alias)))])))) - tuple$) - =refers (list#each (is (-> Importation Code) - (function (_ [module_name m_alias =refer]) - (refer_code module_name (..maybe#else "" m_alias) =refer))) - imports) - =module (` ("lux def module" (, =imports)))] - g!_ (..generated_symbol "")] - (in {#Item =module - (for "Python" - ... TODO: Remove this hack once Jython is no longer being used as the Python interpreter. - ... Without it, I get this strange error - ... {library/lux/tool/compiler/language/lux/generation.no_buffer_for_saving_code} - ... Artifact ID: 0 - ... Which only ever happens for the Python compiler. - (list#partial (` ("lux def" (, g!_) [] #0)) - =refers) - =refers)})))) + (let [refer_code (is (-> Text Text (List Referral) Code) + (function (_ imported_module alias referrals) + (` (..refer (, (text$ imported_module)) + (, (text$ alias)) + (,* (list#each (function (_ [macro parameters]) + (` ((, (symbol$ macro)) (,* parameters)))) + referrals))))))] + (macro (_ _imports) + (do meta#monad + [current_module ..current_module_name + imports (imports_parser #0 current_module {#End} _imports) + .let [=imports (|> imports + (list#each (is (-> Importation Code) + (function (_ [module_name m_alias =refer]) + (` [(, (text$ module_name)) (, (text$ (..maybe#else "" m_alias)))])))) + tuple$) + =refers (list#each (is (-> Importation Code) + (function (_ [module_name m_alias =refer]) + (refer_code module_name (..maybe#else "" m_alias) =refer))) + imports) + =module (` ("lux def module" (, =imports)))] + g!_ (..generated_symbol "")] + (in {#Item =module + (for "Python" + ... TODO: Remove this hack once Jython is no longer being used as the Python interpreter. + ... Without it, I get this strange error + ... {library/lux/tool/compiler/language/lux/generation.no_buffer_for_saving_code} + ... Artifact ID: 0 + ... Which only ever happens for the Python compiler. + (list#partial (` ("lux def" (, g!_) [] #0)) + =refers) + =refers)}))))) (type .public Immediate_UnQuote (Primitive "#Macro/Immediate_UnQuote")) @@ -5467,30 +5383,29 @@ {#None} (failure (..wrong_syntax_error (symbol ..Interface))))))) -(def (recursive_type g!self g!dummy name body) - (-> Code Code Text Code Code) - (` {.#Apply (..Primitive "") - (.All ((, g!self) (, g!dummy)) - (, (let$ (local$ name) (` {.#Apply (..Primitive "") (, g!self)}) - body)))})) - (def .public Rec - (macro (_ tokens) - (case tokens - (list [_ {#Symbol "" name}] body) - (do meta#monad - [body' (expansion body) - g!self (generated_symbol "g!self") - g!dummy (generated_symbol "g!dummy")] - (case body' - (list body' labels) - (in (list (..recursive_type g!self g!dummy name body') labels)) + (let [recursive_type (is (-> Code Code Text Code Code) + (function (recursive_type g!self g!dummy name body) + (` {.#Apply (..Primitive "") + (.All ((, g!self) (, g!dummy)) + (, (let$ (local$ name) (` {.#Apply (..Primitive "") (, g!self)}) + body)))})))] + (macro (_ tokens) + (case tokens + (list [_ {#Symbol "" name}] body) + (do meta#monad + [body' (expansion body) + g!self (generated_symbol "g!self") + g!dummy (generated_symbol "g!dummy")] + (case body' + (list body' labels) + (in (list (recursive_type g!self g!dummy name body') labels)) - (list body') - (in (list (..recursive_type g!self g!dummy name body'))) + (list body') + (in (list (recursive_type g!self g!dummy name body'))) - _ - (failure (..wrong_syntax_error (symbol ..Rec))))) + _ + (failure (..wrong_syntax_error (symbol ..Rec))))) - _ - (failure (..wrong_syntax_error (symbol ..Rec)))))) + _ + (failure (..wrong_syntax_error (symbol ..Rec))))))) diff --git a/stdlib/source/library/lux/control/function/inline.lux b/stdlib/source/library/lux/control/function/inline.lux index 6d5f3bebf..a06d2daf7 100644 --- a/stdlib/source/library/lux/control/function/inline.lux +++ b/stdlib/source/library/lux/control/function/inline.lux @@ -11,42 +11,43 @@ ["[0]" meta (.only) ["[0]" code (.only) ["<[1]>" \\parser (.only Parser)]] - ["[0]" macro (.only) - [syntax (.only syntax) - ["|[0]|" export]]]]]]) + ["[0]" macro (.only with_symbols) + [syntax (.only syntax)]]]]]) + +(type Declaration + [Text (List Code)]) (def declaration - (Parser [Text (List Code)]) + (Parser Declaration) (.form (<>.and .local (<>.some .any)))) (def inline - (Parser [Code [Text (List Code)] Code Code]) - (|export|.parser - (all <>.and - ..declaration - .any - .any - ))) + (Parser [Declaration Code Code]) + (all <>.and + ..declaration + .any + .any + )) (def .public inlined - (syntax (_ [[privacy [name parameters] type term] ..inline]) - (do [! meta.monad] - [@ meta.current_module_name - g!parameters (|> (macro.symbol "parameter") - (list.repeated (list.size parameters)) - (monad.all !)) - .let [inlined (` (("lux in-module" - (, (code.text @)) - (.is (, type) - (.function ((, (code.local name)) (,* parameters)) - (, term)))) - (,* (list#each (function (_ g!parameter) - (` ((,' ,) (, g!parameter)))) - g!parameters)))) - g!parameters (|> g!parameters - (list#each (function (_ parameter) - (list parameter (` .any)))) - list#conjoint)]] - (in (list (` (def (, privacy) (, (code.local name)) - (syntax ((, (code.local name)) [(,* g!parameters)]) + (syntax (_ [[[name parameters] type term] ..inline]) + (with_symbols [g!_] + (do [! meta.monad] + [@ meta.current_module_name + g!parameters (|> (macro.symbol "parameter") + (list.repeated (list.size parameters)) + (monad.all !)) + .let [inlined (` (("lux in-module" + (, (code.text @)) + (.is (, type) + (.function ((, (code.local name)) (,* parameters)) + (, term)))) + (,* (list#each (function (_ g!parameter) + (` ((,' ,) (, g!parameter)))) + g!parameters)))) + g!parameters (|> g!parameters + (list#each (function (_ parameter) + (list parameter (` .any)))) + list#conjoint)]] + (in (list (` (syntax ((, g!_) [(,* g!parameters)]) (.at meta.monad (,' in) (.list (.`' (, inlined)))))))))))) diff --git a/stdlib/source/library/lux/debug.lux b/stdlib/source/library/lux/debug.lux index a4866a106..ad5fa71fb 100644 --- a/stdlib/source/library/lux/debug.lux +++ b/stdlib/source/library/lux/debug.lux @@ -1,6 +1,6 @@ (.require [library - [lux (.except private) + [lux (.except private type) ["[0]" ffi (.only import)] [abstract ["[0]" monad (.only do)]] @@ -81,7 +81,7 @@ ("static" isArray [.Any] ffi.Boolean))) @.python - (these (type PyType + (these (.type PyType (Primitive "python_type")) (import (type [.Any] PyType)) @@ -385,7 +385,7 @@ (exception.report (list ["Type" (%.type type)]))) -(type Representation +(.type Representation (-> Any Text)) (def primitive_representation @@ -547,7 +547,7 @@ expectedT meta.expected_type] (function.constant (exception.except ..type_hole [location expectedT]))))) -(type Target +(.type Target [Text (Maybe Code)]) (def target diff --git a/stdlib/source/library/lux/ffi/export.js.lux b/stdlib/source/library/lux/ffi/export.js.lux index 66009f8ba..3f8561b78 100644 --- a/stdlib/source/library/lux/ffi/export.js.lux +++ b/stdlib/source/library/lux/ffi/export.js.lux @@ -18,8 +18,9 @@ ["[0]" static] ["[0]" code (.only) ["<[1]>" \\parser]] - ["[0]" macro (.only) - [syntax (.only syntax)]] + [macro + [syntax (.only syntax)] + ["[0]" expansion]] [target ["/" js]] [compiler @@ -88,7 +89,7 @@ (syntax (_ [exports (<>.many .any)]) (let [! meta.monad] (|> exports - (monad.each ! macro.expansion) + (monad.each ! expansion.complete) (at ! each (|>> list#conjoint (monad.each ! ..definition))) (at ! conjoint) diff --git a/stdlib/source/library/lux/ffi/export.lua.lux b/stdlib/source/library/lux/ffi/export.lua.lux index 30af57aa4..c00493f77 100644 --- a/stdlib/source/library/lux/ffi/export.lua.lux +++ b/stdlib/source/library/lux/ffi/export.lua.lux @@ -18,8 +18,9 @@ ["[0]" static] ["[0]" code (.only) ["<[1]>" \\parser]] - ["[0]" macro (.only) - [syntax (.only syntax)]] + [macro + [syntax (.only syntax)] + ["[0]" expansion]] [target ["/" lua]] [compiler @@ -104,7 +105,7 @@ (syntax (_ [exports (<>.many .any)]) (let [! meta.monad] (|> exports - (monad.each ! macro.expansion) + (monad.each ! expansion.complete) (at ! each (|>> list#conjoint (monad.each ! ..definition))) (at ! conjoint) diff --git a/stdlib/source/library/lux/ffi/export.py.lux b/stdlib/source/library/lux/ffi/export.py.lux index 370ed7a9d..7633ed73a 100644 --- a/stdlib/source/library/lux/ffi/export.py.lux +++ b/stdlib/source/library/lux/ffi/export.py.lux @@ -18,8 +18,9 @@ ["[0]" static] ["[0]" code (.only) ["<[1]>" \\parser]] - ["[0]" macro (.only) - [syntax (.only syntax)]] + [macro + [syntax (.only syntax)] + ["[0]" expansion]] [target ["/" python]] [compiler @@ -81,7 +82,7 @@ (syntax (_ [exports (<>.many .any)]) (let [! meta.monad] (|> exports - (monad.each ! macro.expansion) + (monad.each ! expansion.complete) (at ! each (|>> list#conjoint (monad.each ! ..definition))) (at ! conjoint) diff --git a/stdlib/source/library/lux/ffi/export.rb.lux b/stdlib/source/library/lux/ffi/export.rb.lux index 1558aad67..7a102720a 100644 --- a/stdlib/source/library/lux/ffi/export.rb.lux +++ b/stdlib/source/library/lux/ffi/export.rb.lux @@ -20,8 +20,9 @@ ["[0]" type] ["[0]" code (.only) ["<[1]>" \\parser]] - ["[0]" macro (.only) - [syntax (.only syntax)]] + [macro + [syntax (.only syntax)] + ["[0]" expansion]] [target ["/" ruby]] [compiler @@ -130,7 +131,7 @@ (syntax (_ [exports (<>.many .any)]) (let [! meta.monad] (|> exports - (monad.each ! macro.expansion) + (monad.each ! expansion.complete) (at ! each (|>> list#conjoint (monad.each ! ..definition))) (at ! conjoint) diff --git a/stdlib/source/library/lux/ffi/node_js.js.lux b/stdlib/source/library/lux/ffi/node_js.js.lux index 1f3f2fb4a..3ee4c8d33 100644 --- a/stdlib/source/library/lux/ffi/node_js.js.lux +++ b/stdlib/source/library/lux/ffi/node_js.js.lux @@ -1,6 +1,6 @@ (.require [library - [lux (.except) + [lux (.except require) ["[0]" ffi] [control ["[0]" function] diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/jvm.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/jvm.lux index 36047a0ed..09010717a 100644 --- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/jvm.lux +++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/jvm.lux @@ -57,7 +57,7 @@ ["[0]" parser] ["[0]" alias (.only Aliasing)] ["[0]T" lux (.only Mapping)]]]] - ["[0]" type (.only) + ["[0]" type (.use "[1]#[0]" equivalence) ["[0]" check (.only Check) (.use "[1]#[0]" monad)]]]]] ["[0]" // ["[1][0]" lux (.only custom)] @@ -92,7 +92,8 @@ (import java/lang/Object "[1]::[0]" - (equals [java/lang/Object] boolean)) + (equals [java/lang/Object] boolean) + (toString [] java/lang/String)) (import java/lang/reflect/Type "[1]::[0]") @@ -282,12 +283,12 @@ [too_many_candidates] ) -(exception .public (cannot_cast [from .Type - to .Type +(exception .public (cannot_cast [from (Type Value) + to (Type Value) value Code]) (exception.report - (list ["From" (%.type from)] - ["To" (%.type to)] + (list ["From" (..signature from)] + ["To" (..signature to)] ["Value" (%.code value)]))) (with_template [] @@ -935,11 +936,11 @@ (in {/////analysis.#Extension extension_name (list (/////analysis.text sub_class) objectA)}) (/////analysis.except cannot_possibly_be_an_instance (format sub_class " !<= " object_class)))))])) -(def (class_candidate_parents class_loader source_name fromT target_name target_class) +(def (class_candidate_parents class_loader from_name fromT to_name to_class) (-> java/lang/ClassLoader External .Type External (java/lang/Class java/lang/Object) (Operation (List [[Text .Type] Bit]))) (do [! phase.monad] - [source_class (phase.lifted (reflection!.load class_loader source_name)) - mapping (phase.lifted (reflection!.correspond source_class fromT))] + [from_class (phase.lifted (reflection!.load class_loader from_name)) + mapping (phase.lifted (reflection!.correspond from_class fromT))] (monad.each ! (function (_ superJT) (do ! @@ -947,32 +948,16 @@ .let [super_name (..reflection superJT)] super_class (phase.lifted (reflection!.load class_loader super_name)) superT (reflection_type mapping superJT)] - (in [[super_name superT] (java/lang/Class::isAssignableFrom super_class target_class)]))) - (case (java/lang/Class::getGenericSuperclass source_class) + (in [[super_name superT] (java/lang/Class::isAssignableFrom super_class to_class)]))) + (case (java/lang/Class::getGenericSuperclass from_class) {.#Some super} - (list.partial super (array.list {.#None} (java/lang/Class::getGenericInterfaces source_class))) + (list.partial super (array.list {.#None} (java/lang/Class::getGenericInterfaces from_class))) {.#None} - (if (java/lang/reflect/Modifier::isInterface (java/lang/Class::getModifiers source_class)) + (if (java/lang/reflect/Modifier::isInterface (java/lang/Class::getModifiers from_class)) {.#Item (as java/lang/reflect/Type (ffi.class_for java/lang/Object)) - (array.list {.#None} (java/lang/Class::getGenericInterfaces source_class))} - (array.list {.#None} (java/lang/Class::getGenericInterfaces source_class))))))) - -(def (inheritance_candidate_parents class_loader fromT target_class toT fromC) - (-> java/lang/ClassLoader .Type (java/lang/Class java/lang/Object) .Type Code (Operation (List [[Text .Type] Bit]))) - (case fromT - {.#Primitive _ (list.partial self_classT super_classT super_interfacesT+)} - (monad.each phase.monad - (function (_ superT) - (do [! phase.monad] - [super_name (at ! each ..reflection (check_jvm superT)) - super_class (phase.lifted (reflection!.load class_loader super_name))] - (in [[super_name superT] - (java/lang/Class::isAssignableFrom super_class target_class)]))) - (list.partial super_classT super_interfacesT+)) - - _ - (/////analysis.except ..cannot_cast [fromT toT fromC]))) + (array.list {.#None} (java/lang/Class::getGenericInterfaces from_class))} + (array.list {.#None} (java/lang/Class::getGenericInterfaces from_class))))))) (def (object::cast class_loader) (-> java/lang/ClassLoader Handler) @@ -981,18 +966,20 @@ (list fromC) (do [! phase.monad] [toT (///.lifted meta.expected_type) - target_name (at ! each ..reflection (check_jvm toT)) + toJT (check_jvm toT) [fromT fromA] (typeA.inferring (analyse archive fromC)) - source_name (at ! each ..reflection (check_jvm fromT)) + fromJT (check_jvm fromT) + .let [from_name (..reflection fromJT) + to_name (..reflection toJT)] can_cast? (is (Operation Bit) (`` (cond (,, (with_template [ ] [(let [=primitive (reflection.reflection )] - (or (and (text#= =primitive source_name) - (or (text#= target_name) - (text#= =primitive target_name))) - (and (text#= source_name) - (text#= =primitive target_name)))) + (or (and (text#= =primitive from_name) + (or (text#= to_name) + (text#= =primitive to_name))) + (and (text#= from_name) + (text#= =primitive to_name)))) (in true)] [reflection.boolean box.boolean] @@ -1006,34 +993,39 @@ ... else (do ! - [_ (phase.assertion ..primitives_are_not_objects [source_name] - (not (dictionary.key? ..boxes source_name))) - _ (phase.assertion ..primitives_are_not_objects [target_name] - (not (dictionary.key? ..boxes target_name))) - target_class (phase.lifted (reflection!.load class_loader target_name)) - _ (do ! - [source_class (phase.lifted (reflection!.load class_loader source_name))] - (phase.assertion ..cannot_cast [fromT toT fromC] - (java/lang/Class::isAssignableFrom source_class target_class)))] - (loop (again [[current_name currentT] [source_name fromT]]) - (if (text#= target_name current_name) - (in true) - (do ! - [candidate_parents (is (Operation (List [[Text .Type] Bit])) - (class_candidate_parents class_loader current_name currentT target_name target_class))] - (case (|> candidate_parents - (list.only product.right) - (list#each product.left)) - {.#Item [next_name nextT] _} - (again [next_name nextT]) - - {.#End} - (in false)))))))))] + [_ (phase.assertion ..primitives_are_not_objects [from_name] + (not (dictionary.key? ..boxes from_name))) + _ (phase.assertion ..primitives_are_not_objects [to_name] + (not (dictionary.key? ..boxes to_name))) + to_class (phase.lifted (reflection!.load class_loader to_name)) + from_class (phase.lifted (reflection!.load class_loader from_name))] + (if (java/lang/Class::isAssignableFrom from_class to_class) + (loop (again [[current_name currentT] [from_name fromT]]) + (if (text#= to_name current_name) + (in true) + (do ! + [candidate_parents (is (Operation (List [[Text .Type] Bit])) + (class_candidate_parents class_loader current_name currentT to_name to_class))] + (case (|> candidate_parents + (list.only product.right) + (list#each product.left)) + {.#Item [next_name nextT] _} + (again [next_name nextT]) + + {.#End} + (in false))))) + (in (case [(type#= java/lang/Object fromT) + (parser.array? toJT)] + [#1 {.#Some _}] + true + + _ + false)))))))] (if can_cast? - (in {/////analysis.#Extension extension_name (list (/////analysis.text source_name) - (/////analysis.text target_name) + (in {/////analysis.#Extension extension_name (list (/////analysis.text from_name) + (/////analysis.text to_name) fromA)}) - (/////analysis.except ..cannot_cast [fromT toT fromC]))) + (/////analysis.except ..cannot_cast [fromJT toJT fromC]))) _ (/////analysis.except ///.invalid_syntax [extension_name %.code args])))) diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/js/runtime.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/js/runtime.lux index 270ff3256..437f6624d 100644 --- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/js/runtime.lux +++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/js/runtime.lux @@ -796,7 +796,7 @@ @array//delete )) -(def runtime +(def full Statement (all _.then runtime//structure @@ -814,13 +814,13 @@ (def .public generate (Operation [Registry Output]) (do ///////phase.monad - [_ (/////generation.execute! ..runtime) - _ (/////generation.save! ..module_id {.#None} ..runtime)] + [_ (/////generation.execute! ..full) + _ (/////generation.save! ..module_id {.#None} ..full)] (in [(|> registry.empty (registry.resource true unit.none) product.right) (sequence.sequence [..module_id {.#None} - (|> ..runtime + (|> ..full _.code (at utf8.codec encoded))])]))) diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/lua/runtime.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/lua/runtime.lux index 8a124aadc..e8ba62726 100644 --- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/lua/runtime.lux +++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/lua/runtime.lux @@ -427,7 +427,7 @@ @array//write )) -(def runtime +(def full Statement (all _.then ..runtime//adt @@ -440,13 +440,13 @@ (def .public generate (Operation [Registry Output]) (do ///////phase.monad - [_ (/////generation.execute! ..runtime) - _ (/////generation.save! ..module_id {.#None} ..runtime)] + [_ (/////generation.execute! ..full) + _ (/////generation.save! ..module_id {.#None} ..full)] (in [(|> registry.empty (registry.resource true unit.none) product.right) (sequence.sequence [..module_id {.#None} - (|> ..runtime + (|> ..full _.code (at utf8.codec encoded))])]))) diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/ruby/runtime.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/ruby/runtime.lux index 194b97c7e..b193b5b84 100644 --- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/ruby/runtime.lux +++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/ruby/runtime.lux @@ -595,11 +595,11 @@ @array//write )) -(def runtime +(def full Statement (all _.then (_.when ..mruby? - ... We're in DragonRuby territory. + ... We're in mRuby/DragonRuby territory. (_.statement (_.do "class_eval" (list) {.#Some [(list (_.local "_")) (_.statement @@ -617,13 +617,13 @@ (def .public generate (Operation [Registry Output]) (do ///////phase.monad - [_ (/////generation.execute! ..runtime) - _ (/////generation.save! ..module_id {.#None} ..runtime)] + [_ (/////generation.execute! ..full) + _ (/////generation.save! ..module_id {.#None} ..full)] (in [(|> registry.empty (registry.resource true unit.none) product.right) (sequence.sequence [..module_id {.#None} - (|> ..runtime + (|> ..full _.code (at utf8.codec encoded))])]))) diff --git a/stdlib/source/library/lux/meta/macro/pattern.lux b/stdlib/source/library/lux/meta/macro/pattern.lux index 4c78c8c36..367c77bd4 100644 --- a/stdlib/source/library/lux/meta/macro/pattern.lux +++ b/stdlib/source/library/lux/meta/macro/pattern.lux @@ -11,8 +11,8 @@ ["[0]" try]] [data [collection - ["[0]" list (.use "[1]#[0]" monoid monad)]]]]] - ["[0]" // (.only) + ["[0]" list (.use "[1]#[0]" monoid monad mix)]]]]] + ["[0]" // (.only with_symbols) [vocabulary (.only vocabulary)] ["/[1]" // (.use "[1]#[0]" monad)]]) @@ -40,7 +40,6 @@ [tuple_list] [text$] - [generated_symbol] [type_definition] [record_slots] [text#composite] @@ -50,8 +49,6 @@ [tuple$] [zipped_2] - [multi_level_case^] - [multi_level_case$] [type_code] [expected_type] @@ -116,35 +113,81 @@ _ (///.failure (..wrong_syntax_error (symbol ..with_template))))))) +(type Level + [Code Code]) + +(def (level it) + (-> Code (Meta Level)) + (///#in (case it + [_ {.#Tuple (list expr binding)}] + [expr binding] + + _ + [it (.` #1)]))) + +(type Multi + [Code (List Level)]) + +(def (multiP levels) + (-> (List Code) (Meta Multi)) + (case levels + {.#End} + (///.failure "Multi-level patterns cannot be empty.") + + {.#Item init extras} + (do ///.monad + [extras' (monad.each ///.monad ..level extras)] + (in [init extras'])))) + +(def (multiG g!_ [[init_pattern levels] body]) + (-> Code [Multi Code] (List Code)) + (.let [inner_pattern_body (list#mix (function (_ [calculation pattern] success) + (.let [bind? (case pattern + [_ {.#Symbol _}] + #1 + + _ + #0)] + (.` (case (., calculation) + (., pattern) + (., success) + + (.,* (if bind? + (list) + (list g!_ (.` {.#None})))))))) + (.` {.#Some (., body)}) + (list.reversed levels))] + (list init_pattern inner_pattern_body))) + (def .public multi (pattern (macro (_ tokens) (case tokens (list.partial [_meta {.#Form levels}] body next_branches) - (do ///.monad - [mlc (multi_level_case^ levels) - .let [initial_bind? (case mlc - [[_ {.#Symbol _}] _] - #1 - - _ - #0)] - expected ..expected_type - g!temp (..generated_symbol "temp")] - (in (list g!temp - (.` ({{.#Some (., g!temp)} - (., g!temp) - - {.#None} - (.case (., g!temp) - (.,* next_branches))} - ("lux type check" {.#Apply (., (type_code expected)) Maybe} - (.case (., g!temp) - (.,* (multi_level_case$ g!temp [mlc body])) - - (.,* (if initial_bind? - (list) - (list g!temp (.` {.#None}))))))))))) + (with_symbols [g!temp] + (do ///.monad + [mlc (multiP levels) + .let [initial_bind? (case mlc + [[_ {.#Symbol _}] _] + #1 + + _ + #0)] + expected ..expected_type] + (in (list g!temp + (.` ({{.#Some (., g!temp)} + (., g!temp) + + {.#None} + (.case (., g!temp) + (.,* next_branches))} + ("lux type check" {.#Apply (., (type_code expected)) Maybe} + (.case (., g!temp) + (.,* (multiG g!temp [mlc body])) + + (.,* (if initial_bind? + (list) + (list g!temp (.` {.#None})))))))))))) _ (///.failure (..wrong_syntax_error (symbol ..multi))))))) @@ -237,12 +280,11 @@ (def (untemplated_pattern pattern) (-> Code (Meta Code)) - (do ///.monad - [g!meta (..generated_symbol "g!meta")] + (with_symbols [g!meta] (case pattern (..with_template [ ] [[_ { value}] - (in (.` [(., g!meta) { (., ( value))}]))]) + (///#in (.` [(., g!meta) { (., ( value))}]))]) ([.#Bit bit$] [.#Nat nat$] [.#Int int$] @@ -252,11 +294,11 @@ [.#Symbol name$]) [@composite {.#Form {.#Item [@global {.#Symbol global}] parameters}}] - (do ///.monad + (do [! ///.monad] [micro (///.try (..named_unquote global))] (case micro {try.#Success micro} - (do ///.monad + (do ! [[_ output] (..one_expansion ((//.function micro) parameters))] (in [@composite output])) diff --git a/stdlib/source/test/lux/control/function/inline.lux b/stdlib/source/test/lux/control/function/inline.lux index 441ddef3c..94a21ede2 100644 --- a/stdlib/source/test/lux/control/function/inline.lux +++ b/stdlib/source/test/lux/control/function/inline.lux @@ -15,9 +15,10 @@ (template (_ m0 m1) [(i.+ (i.* m0 m0) (i.* m1 m1))])) -(/.inlined .public (quadrance/2 m0 m1) - (-> Int Int Int) - (!quadrance/2 m0 m1)) +(def .public quadrance/2 + (/.inlined (_ m0 m1) + (-> Int Int Int) + (!quadrance/2 m0 m1))) (def .public test Test diff --git a/stdlib/source/test/lux/meta/extension.lux b/stdlib/source/test/lux/meta/extension.lux index 8be85f9c0..bfe11a0e0 100644 --- a/stdlib/source/test/lux/meta/extension.lux +++ b/stdlib/source/test/lux/meta/extension.lux @@ -33,13 +33,13 @@ ["[0]" ruby] ["[0]" php] ["[0]" scheme] - ["[0]" jvm - (.,, (.for "JVM" (.,, (.these ["[1]" bytecode] + (.,, (.for "JVM" (.,, (.these ["[0]" jvm + ["[1]" bytecode] ["[0]" class] ["[0]" version] [encoding - ["[0]" name]])) - (.,, (.these))))]] + ["[0]" name]]])) + (.,, (.these))))] [compiler ["[0]" phase] [meta diff --git a/stdlib/source/test/lux/meta/target/js.lux b/stdlib/source/test/lux/meta/target/js.lux index 9604b26b3..94fc0c470 100644 --- a/stdlib/source/test/lux/meta/target/js.lux +++ b/stdlib/source/test/lux/meta/target/js.lux @@ -3,13 +3,13 @@ [lux (.except) ["_" test (.only Test)] [abstract - [monad (.only do)] - ["[0]" predicate]] + [monad (.only do)]] [control ["[0]" pipe] - ["[0]" function] ["[0]" maybe (.use "[1]#[0]" functor)] - ["[0]" try (.only Try) (.use "[1]#[0]" functor)]] + ["[0]" try (.only Try) (.use "[1]#[0]" functor)] + ["[0]" function (.only) + ["[0]" predicate]]] [data ["[0]" bit (.use "[1]#[0]" equivalence)] ["[0]" text (.only \n) (.use "[1]#[0]" equivalence) diff --git a/stdlib/source/unsafe/lux/data/binary.lux b/stdlib/source/unsafe/lux/data/binary.lux index e90aa4b39..d3b824dfb 100644 --- a/stdlib/source/unsafe/lux/data/binary.lux +++ b/stdlib/source/unsafe/lux/data/binary.lux @@ -306,26 +306,27 @@ (again ("lux i64 +" 1 index))))))))])))) ... TODO: Turn into a template ASAP. -(`` (inlined .public (copy! bytes source_offset source target_offset target) - (-> .Nat .Nat ..Binary Nat ..Binary ..Binary) - (with_expansions [ (java/lang/System::arraycopy source (ffi.as_int (.int source_offset)) - target (ffi.as_int (.int target_offset)) - (ffi.as_int (.int bytes))) - (.exec - - target)] - (.for (,, (.static @.old)) - (,, (.static @.jvm)) - - ... Default - (.loop (again [index 0]) - (.if ("lux i64 <" (.int bytes) (.int index)) - (.exec - (..has_8! ("lux i64 +" target_offset index) - (..bits_8 ("lux i64 +" source_offset index) source) - target) - (again ("lux i64 +" 1 index))) - target)))))) +(`` (def .public copy! + (inlined (_ bytes source_offset source target_offset target) + (-> .Nat .Nat ..Binary Nat ..Binary ..Binary) + (with_expansions [ (java/lang/System::arraycopy source (ffi.as_int (.int source_offset)) + target (ffi.as_int (.int target_offset)) + (ffi.as_int (.int bytes))) + (.exec + + target)] + (.for (,, (.static @.old)) + (,, (.static @.jvm)) + + ... Default + (.loop (again [index 0]) + (.if ("lux i64 <" (.int bytes) (.int index)) + (.exec + (..has_8! ("lux i64 +" target_offset index) + (..bits_8 ("lux i64 +" source_offset index) source) + target) + (again ("lux i64 +" 1 index))) + target))))))) ... TODO: Turn into a template ASAP. (`` (with_expansions [ (java/util/Arrays::copyOfRange binary @@ -333,10 +334,11 @@ (ffi.as_int (.int limit))) (.let [limit ("lux i64 +" size offset)] )] - (inlined .public (slice offset size binary) - (-> .Nat .Nat ..Binary ..Binary) - (.for (,, (.static @.old)) - (,, (.static @.jvm)) - - ... Default - (..copy! size offset binary 0 (..empty size)))))) + (def .public slice + (inlined (_ offset size binary) + (-> .Nat .Nat ..Binary ..Binary) + (.for (,, (.static @.old)) + (,, (.static @.jvm)) + + ... Default + (..copy! size offset binary 0 (..empty size))))))) -- cgit v1.2.3