aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2022-06-12 20:05:43 -0400
committerEduardo Julian2022-06-12 20:05:43 -0400
commit1643be20cb10baf3cabcab502f0013b7faebe322 (patch)
tree4b4f4619921bf5749e404e7f644e5dfe30d69055
parent94c0bc5d12ed44540543bd6772d357baeb32bb45 (diff)
Generalized macro-let.
-rw-r--r--.gitignore5
-rw-r--r--lux-jvm/source/program.lux4
-rw-r--r--lux-lua/source/program.lux30
-rw-r--r--lux-python/source/program.lux6
-rw-r--r--lux-ruby/source/program.lux10
-rw-r--r--stdlib/source/library/lux/macro/local.lux45
-rw-r--r--stdlib/source/library/lux/macro/template.lux1
-rw-r--r--stdlib/source/library/lux/target/jvm/type/parser.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/js.lux6
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux6
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/python.lux6
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux6
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/case.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/function.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux2
-rw-r--r--stdlib/source/test/lux/macro/local.lux37
20 files changed, 127 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore
index 40d60ba10..606ff0d0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ aedifex.jar
/lux-jvm/source/unsafe
/lux-jvm/source/program
/lux-jvm/source/spec
+/lux-jvm/source/parser
/lux-js/RELEASE
/lux-js/target
@@ -32,6 +33,7 @@ aedifex.jar
/lux-js/source/unsafe
/lux-js/source/program
/lux-js/source/spec
+/lux-js/source/parser
/lux-js/node_based_compiler.js
/lux-js/lux.js
@@ -41,6 +43,7 @@ aedifex.jar
/lux-python/source/unsafe
/lux-python/source/program
/lux-python/source/spec
+/lux-python/source/parser
/lux-lua/RELEASE
/lux-lua/target
@@ -48,6 +51,7 @@ aedifex.jar
/lux-lua/source/unsafe
/lux-lua/source/program
/lux-lua/source/spec
+/lux-lua/source/parser
/lux-ruby/RELEASE
/lux-ruby/target
@@ -55,6 +59,7 @@ aedifex.jar
/lux-ruby/source/unsafe
/lux-ruby/source/program
/lux-ruby/source/spec
+/lux-ruby/source/parser
/stdlib/RELEASE
/stdlib/target
diff --git a/lux-jvm/source/program.lux b/lux-jvm/source/program.lux
index 82e5f400b..a22211aad 100644
--- a/lux-jvm/source/program.lux
+++ b/lux-jvm/source/program.lux
@@ -42,7 +42,7 @@
[analysis
[macro (.only Expander)]]
[phase
- ["[0]" extension
+ ["[0]" extension (.only)
["[0]" analysis
["[1]" jvm]]
["[0]" generation
@@ -50,7 +50,7 @@
["[0]" directive
["[1]" jvm]]]
[generation
- ["/" jvm
+ ["/" jvm (.only)
["[1][0]" runtime (.only Anchor Definition)]
["[1][0]" host]
["[1][0]" program]]]]]]]]]]
diff --git a/lux-lua/source/program.lux b/lux-lua/source/program.lux
index ab567ae31..b3af368bb 100644
--- a/lux-lua/source/program.lux
+++ b/lux-lua/source/program.lux
@@ -24,7 +24,7 @@
["[0]" list (.open: "[1]#[0]" monad)]]]
[macro
["^" pattern]
- ["[0]" template]
+ ["[0]" local]
["[0]" code]]
[math
[number (.only hex)
@@ -33,7 +33,7 @@
["[0]" world
["[0]" file]
["[1]/[0]" program]]
- ["@" target
+ ["@" target (.only)
["_" lua]]
[tool
["[0]" compiler
@@ -55,7 +55,7 @@
["[1]" lua]]]
[generation
["[0]" reference]
- ["[0]" lua
+ ["[0]" lua (.only)
["[0]" runtime]]]]]]
[default
["[0]" platform (.only Platform)]]
@@ -502,19 +502,17 @@
(with_expansions [<jvm> (these (with_expansions [$var_args (_.var "...")
$str_rel_to_abs (_.var "_utf8_str_rel_to_abs")
$decode (_.var "_utf8_decode")]
- (template.let [(!int <hex>)
- [(_.int (.int (hex <hex>)))]
-
- (!&| <or> <and> <raw>)
- [(|> <raw>
- (_.bit_and (!int <and>))
- (_.bit_or (!int <or>)))]
-
- (!&|< <or> <and> <shift> <raw>)
- [(|> <raw>
- (_.bit_shr (_.int <shift>))
- (_.bit_and (!int <and>))
- (_.bit_or (!int <or>)))]]
+ (local.let [!int (template (_ <hex>)
+ [(_.int (.int (hex <hex>)))])
+ !&| (template (_ <or> <and> <raw>)
+ [(|> <raw>
+ (_.bit_and (!int <and>))
+ (_.bit_or (!int <or>)))])
+ !&|< (template (_ <or> <and> <shift> <raw>)
+ [(|> <raw>
+ (_.bit_shr (_.int <shift>))
+ (_.bit_and (!int <and>))
+ (_.bit_or (!int <or>)))])]
(these (def: rembulan//char
(let [$buffer (_.var "buffer")
$k (_.var "k")
diff --git a/lux-python/source/program.lux b/lux-python/source/program.lux
index 64139ca38..2368323f7 100644
--- a/lux-python/source/program.lux
+++ b/lux-python/source/program.lux
@@ -24,7 +24,7 @@
[collection
["[0]" array (.only Array)]
["[0]" list (.open: "[1]#[0]" functor)]]]
- ["[0]" macro
+ [macro
["^" pattern]
["[0]" template]
["[0]" code]]
@@ -35,7 +35,7 @@
["[0]" world
["[0]" file]
["[1]/[0]" program]]
- ["@" target
+ ["@" target (.only)
["_" python]]
[tool
["[0]" compiler
@@ -58,7 +58,7 @@
["[1]" python]]]
[generation
["[0]" reference]
- ["[0]" python
+ ["[0]" python (.only)
["[0]" runtime]]]]]]
[default
["[0]" platform (.only Platform)]]
diff --git a/lux-ruby/source/program.lux b/lux-ruby/source/program.lux
index 5e06719fa..128e5d720 100644
--- a/lux-ruby/source/program.lux
+++ b/lux-ruby/source/program.lux
@@ -14,9 +14,7 @@
["[0]" io (.only IO io)]
["[0]" function]
[concurrency
- ["[0]" async (.only Async)]]
- ["<>" parser
- ["<[0]>" code]]]
+ ["[0]" async (.only Async)]]]
[data
["[0]" text (.open: "[1]#[0]" hash)
["%" format (.only format)]
@@ -25,7 +23,7 @@
[collection
["[0]" array (.only Array)]
["[0]" list (.open: "[1]#[0]" functor)]]]
- ["[0]" macro
+ [macro
["^" pattern]
["[0]" template]]
[math
@@ -36,7 +34,7 @@
["[0]" world
["[0]" file]
["[1]/[0]" program]]
- ["@" target
+ ["@" target (.only)
["_" ruby]]
[tool
["[0]" compiler
@@ -59,7 +57,7 @@
["[1]" ruby]]]
[generation
["[0]" reference]
- ["[0]" ruby
+ ["[0]" ruby (.only)
["[0]" runtime]]]]]]
[default
["[0]" platform (.only Platform)]]
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!)))
+ ))))
))))