Began implementing fully isomorphic macros

Like Rust's Proc macros. Now we have preprocessor recursion to worry about. I also made a cool macro for enums
This commit is contained in:
2024-10-14 00:13:09 +02:00
parent 84cbcdd4fe
commit 3a3ae98aff
66 changed files with 2302 additions and 1164 deletions

45
notes/new_macro_model.md Normal file
View File

@@ -0,0 +1,45 @@
# Code sample for the new macro system
```
macro (
rule match ...$expr { ...$body } => \recurse. '(
fn::pass (...$expr) \match::value. ...$(
fn::pass (quote::split body ';) \cases.
fn::pass (list::map cases \x. (
fn::pass (quote::split_once x '=>) \pair.
tuple::destr pair 2 \req. \handler.
fn::pass (recurse '(match::request (...$key))) \match_res.
quote::match '(match::response $decoder (...$bindings)) match_res \match_res_match.
fn::pass (option::expect match_res_match "Invalid pattern ${key}") \res_parts.
fn::pass (map::get_unwrap res_parts "decoder") \decoder.
fn::pass (map::get_unwrap res_parts "bindings") \bindings.
fn::pass (quote::to_list bindings) \binding_names.
fn::pass (list::rfold handler \tail. \name. '( \ $name . $tail )) \success.
'( $decoder $success )
)) \case_fns.
list::append case_fns '( panic "No cases match" )
)
)
)
--[
Macros are run from the top down.
For every token
1. If it's a name token, test all macros starting with that name
2. If none match and this is the first token in a list, test all macros starting with vectorials
Test all in a set of macros
1. Take the first rule that matches in each block
2. If there are multiple matches across blocks, raise an ambiguity error
3. If the single match is in the recursion stack, raise a recursion error
4. Add the matching rule to the recursion stack, then execute the body.
]--
--[
1. Macro patterns are held in the host, they don't contain atoms, and atoms are never considered equal, so the matcher doesn't have to call an extension.
2. The body of macros may be defined in Rust. If it isn't, the entire interpreter will recurse on the macro to calculate the output.
]--
--[
1. if the rule body uses the same macro, fail with the rule
2. if the rule explicitly recursively invokes the same macro, fail with the first match
]--