diff options
author | Eduardo Julian | 2022-06-12 20:05:43 -0400 |
---|---|---|
committer | Eduardo Julian | 2022-06-12 20:05:43 -0400 |
commit | 1643be20cb10baf3cabcab502f0013b7faebe322 (patch) | |
tree | 4b4f4619921bf5749e404e7f644e5dfe30d69055 /stdlib | |
parent | 94c0bc5d12ed44540543bd6772d357baeb32bb45 (diff) |
Generalized macro-let.
Diffstat (limited to 'stdlib')
15 files changed, 99 insertions, 24 deletions
diff --git a/stdlib/source/library/lux/macro/local.lux b/stdlib/source/library/lux/macro/local.lux index a921afee1..5a07b4a48 100644 --- a/stdlib/source/library/lux/macro/local.lux +++ b/stdlib/source/library/lux/macro/local.lux @@ -1,12 +1,14 @@ (.using [library - [lux (.except) + [lux (.except with let) ["[0]" meta] [abstract ["[0]" monad (.only do)]] [control ["[0]" try (.only Try)] - ["[0]" exception (.only exception:)]] + ["[0]" exception (.only exception:)] + ["<>" parser (.only) + ["<[0]>" code]]] [data ["[0]" product] ["[0]" text] @@ -15,6 +17,7 @@ [dictionary ["[0]" plist (.only PList)]]]]]] ["[0]" // (.only) + [syntax (.only syntax)] ["[1][0]" code]]) (exception: .public (unknown_module [module Text]) @@ -102,7 +105,41 @@ [_ (monad.each meta.monad ..push_one macros) seed meta.seed g!pop (//.symbol "pop") - _ (let [g!pop (is Symbol - ["" (//code.format g!pop)])] + _ (.let [g!pop (is Symbol + ["" (//code.format g!pop)])] (..push_one [g!pop (..pop_all (list#each product.left macros) g!pop)]))] (in (` ((~ g!pop)))))) + +(def: .public (with macros body) + (-> (List [Symbol Macro]) Code (Meta (List Code))) + (do [! meta.monad] + [expression? (is (Meta Bit) + (function (_ lux) + {try.#Success [lux (case (the .#expected lux) + {.#None} + false + + {.#Some _} + true)]})) + g!pop (..push macros)] + (.if expression? + (//.with_symbols [g!body] + (in (list (` (.let [(~ g!body) (~ body)] + (exec + (~ g!pop) + (~ g!body))))))) + (in (list body + g!pop))))) + +(def: .public let + (syntax (_ [locals (<code>.tuple (<>.some (<>.and <code>.local <code>.any))) + body <code>.any]) + (do [! meta.monad] + [here_name meta.current_module_name + locals (monad.each ! (function (_ [name value]) + (|> value + (meta.eval .Macro) + (at ! each (|>> (as .Macro) + [[here_name name]])))) + locals)] + (..with locals body)))) diff --git a/stdlib/source/library/lux/macro/template.lux b/stdlib/source/library/lux/macro/template.lux index 439c99a3a..2251051d5 100644 --- a/stdlib/source/library/lux/macro/template.lux +++ b/stdlib/source/library/lux/macro/template.lux @@ -157,6 +157,7 @@ #parameters parameters #template template]))) +... TODO: Get rid of this (and any local definitions it depends on) once the bootstrapping compiler is gone. (def: .public let (syntax (_ [locals (<code>.tuple (<>.some ..local)) body <code>.any]) diff --git a/stdlib/source/library/lux/target/jvm/type/parser.lux b/stdlib/source/library/lux/target/jvm/type/parser.lux index 53bd29aa0..aa64e4334 100644 --- a/stdlib/source/library/lux/target/jvm/type/parser.lux +++ b/stdlib/source/library/lux/target/jvm/type/parser.lux @@ -18,7 +18,7 @@ [category (.only Void Value Return Method Primitive Object Class Array Var Parameter Declaration)] ["[1][0]" signature] ["[1][0]" descriptor] - ["[0]" // (.only) + [// [encoding ["[1][0]" name (.only External)]]]]) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/js.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/js.lux index d477f443e..8342ce912 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/js.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/js.lux @@ -5,16 +5,16 @@ [abstract ["[0]" monad (.only do)]] [control - ["<>" parser + ["<>" parser (.only) ["<[0]>" code (.only Parser)]]] [data [collection ["[0]" array] ["[0]" dictionary] ["[0]" list]]] - ["[0]" type + ["[0]" type (.only) ["[0]" check]] - ["@" target + ["@" target (.only) ["_" js]]]] [// ["/" lux (.only custom)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux index 428ea1068..fa08d5be0 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux @@ -5,16 +5,16 @@ [abstract ["[0]" monad (.only do)]] [control - ["<>" parser + ["<>" parser (.only) ["<[0]>" code (.only Parser)]]] [data [collection ["[0]" array] ["[0]" dictionary] ["[0]" list]]] - ["[0]" type + ["[0]" type (.only) ["[0]" check]] - ["@" target + ["@" target (.only) ["_" lua]]]] [// ["/" lux (.only custom)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/python.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/python.lux index 3defef9c9..aa2944967 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/python.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/python.lux @@ -5,16 +5,16 @@ [abstract ["[0]" monad (.only do)]] [control - ["<>" parser + ["<>" parser (.only) ["<[0]>" code (.only Parser)]]] [data [collection ["[0]" array] ["[0]" dictionary] ["[0]" list]]] - ["[0]" type + ["[0]" type (.only) ["[0]" check]] - ["@" target + ["@" target (.only) ["_" python]]]] [// ["/" lux (.only custom)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux index 4678fe9e1..01895a3e7 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux @@ -5,16 +5,16 @@ [abstract ["[0]" monad (.only do)]] [control - ["<>" parser + ["<>" parser (.only) ["<[0]>" code (.only Parser)]]] [data [collection ["[0]" array] ["[0]" dictionary] ["[0]" list]]] - ["[0]" type + ["[0]" type (.only) ["[0]" check]] - ["@" target + ["@" target (.only) ["_" ruby]]]] [// ["/" lux (.only custom)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/case.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/case.lux index e96a88889..3ab3c67f7 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/case.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/case.lux @@ -35,7 +35,7 @@ [access ["[0]" member (.only Member)]]] [/// - ["[0]" phase ("operation#[0]" monad)] + ["[0]" phase (.open: "operation#[0]" monad)] [reference [variable (.only Register)]]]]]) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/function.lux index e9f9b5800..3de519160 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/function.lux @@ -1,6 +1,6 @@ (.using [library - [lux (.except Type Label) + [lux (.except Type Label with) [abstract ["[0]" monad (.only do)]] [data diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux index 7f6ade8c6..21b5a57b4 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux @@ -20,7 +20,7 @@ [// ["[0]" generation] [/// - ["[1]" phase ("operation#[0]" monad)] + ["[1]" phase (.open: "operation#[0]" monad)] [reference ["[0]" variable (.only Register Variable)]] [meta diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua.lux index e14772296..669e1667b 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua.lux @@ -20,7 +20,7 @@ ["/[1]" // ["[1][0]" reference] ["/[1]" // - ["[1][0]" extension + ["[1][0]" extension (.only) [generation [lua ["[1]/[0]" common]]]] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux index 503638aeb..8898da66d 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux @@ -1,6 +1,6 @@ (.using [library - [lux (.except Label Location) + [lux (.except Label Location left right) ["[0]" meta] [abstract ["[0]" monad (.only do)]] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python.lux index 054e84344..a0c15f71e 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python.lux @@ -20,7 +20,7 @@ ["/[1]" // ["[1][0]" reference] ["/[1]" // - ["[1][0]" extension + ["[1][0]" extension (.only) [generation [python ["[1]/[0]" common]]]] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux index 12d1f65c7..c0101452a 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux @@ -1,6 +1,6 @@ (.using [library - [lux (.except ++) + [lux (.except ++ left right) [abstract ["[0]" monad (.only do)]] [control diff --git a/stdlib/source/test/lux/macro/local.lux b/stdlib/source/test/lux/macro/local.lux index de1073f55..bb03574a1 100644 --- a/stdlib/source/test/lux/macro/local.lux +++ b/stdlib/source/test/lux/macro/local.lux @@ -27,6 +27,12 @@ [\\library ["[0]" /]]) +(/.let [!pow/2 (template (_ <scalar>) + [(n.* <scalar> <scalar>)])] + (def: pow/2 + (-> Nat Nat) + (|>> !pow/2))) + (def: macro_error (syntax (_ [macro <code>.any]) (function (_ compiler) @@ -90,4 +96,35 @@ (<| ..macro_error (..with ["" "actual"] expected #1) (n.= expected (..actual))))) + (do ! + [scalar random.nat] + (_.coverage [/.let] + (let [can_use_with_statements! + (n.= (all n.* scalar scalar) + (..pow/2 scalar))] + (and can_use_with_statements! + (/.let [pow/3 (template (_ <scalar>) + [(all n.* <scalar> <scalar> <scalar>)]) + pow/9 (template (_ <scalar>) + [(pow/3 (pow/3 <scalar>))])] + (let [can_use_with_expressions! + (n.= (all n.* scalar scalar scalar) + (pow/3 scalar)) + + can_refer! + (n.= (all n.* + scalar scalar scalar + scalar scalar scalar + scalar scalar scalar) + (pow/9 scalar)) + + can_shadow! + (let [pow/3 (function (_ scalar) + (all n.+ scalar scalar scalar))] + (n.= (all n.+ scalar scalar scalar) + (pow/3 scalar)))] + (and can_use_with_expressions! + can_refer! + can_shadow!))) + )))) )))) |