aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
authorEduardo Julian2022-06-12 20:05:43 -0400
committerEduardo Julian2022-06-12 20:05:43 -0400
commit1643be20cb10baf3cabcab502f0013b7faebe322 (patch)
tree4b4f4619921bf5749e404e7f644e5dfe30d69055 /stdlib
parent94c0bc5d12ed44540543bd6772d357baeb32bb45 (diff)
Generalized macro-let.
Diffstat (limited to 'stdlib')
-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
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!)))
+ ))))
))))