diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-09 13:14:02 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-09 13:14:02 +0800 |
commit | f4492fe0363ec0aee12391219559d616f75f662e (patch) | |
tree | b3e3ce13e907b6e2db65cfc38869e3e7639a9ae5 | |
parent | 00662f7843b658eceb85b2fb182212cacc5615cc (diff) | |
download | mrust-f4492fe0363ec0aee12391219559d616f75f662e.tar.gz |
Notes - Planning another rewrite of macro_rules! handling
-rw-r--r-- | Notes/MacroRules.md | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/Notes/MacroRules.md b/Notes/MacroRules.md new file mode 100644 index 00000000..062b448a --- /dev/null +++ b/Notes/MacroRules.md @@ -0,0 +1,72 @@ +% `macro_rules!` rework #2 + +Problem Cases +============= + +libcollections `vec!` +--------------------- + +``` +( $e:expr ; $n:expr ) +( $($e:expr),* ) +( $($e:expr , )* ) +``` + +Problems: +- All arms begin with $e:expr (or none) +- Two arms follow the same pattern until the end. (where one terminates with no comma) + +Parsing Ruleset +- if empty, ARM 2 +- expect `:expr` +- if `;` + - expect `:expr` + - ARM 1 +- LOOP + - if empty, ARM 2 + - expect `,` + - if empty, ARM 3 + - expect `:expr` + + + +Rule Generation Algorithm +========================= +- For each arm, convert into a set of decision rules + - `LOOP` - Contains a continuable loop + - `IF [NOT] pat, BREAK` - Compare the next token and break out of the current loop if it matches (non-consuming) + - `EXPECT pat` - Error if the current token isn't as expected (consumes token) + - `COMPLETE` - Complete the current arm early +- Combine rules from arms into a more complex ruleset as above + - IF pat, COMPLETE + - IF pat, SUBTREE + - EXPECT pat + - COMPLETE + - LOOP +- + +Example Application: `vec!` +--------------------------- + +Arm rulesets +- arm 1 + - EXPECT `:expr` , EXPECT `;` , EXPECT `:expr` , COMPLETE +- arm 2 + - IF `:expr` { LOOP { EXPECT `:expr` , IF NOT `,` BREAK , EXPECT `,` } } +- arm 2 + - IF `:expr` { LOOP { EXPECT `:expr` , EXPECT `,` IF empty BREAK } } + +Merging +- "EXPECT `:expr` , EXPECT `;` , EXPECT `:expr` , COMPLETE 1" +- "EXPECT `:expr`" + (2) "IF `:expr` { ... } COMPLETE" + - insert "IF NOT `:expr` COMPLETE 2" at start +- "EXPECT `:expr`" + (2) "LOOP { ... }" + - Recurse into loop + - "EXPECT `:expr`" + (2) "EXPECT `:expr`" + - "EXPECT `:expr`" + - "EXPECT `;`" + "IF NOT `,` BREAK" + - TODO TODO TODO + +Problem: Generating LOOP +------------------------ +Looping is ideally handled by a loop sub-tree as in the example ruleset, but generating that sub-tree from an overlapping set of rules may be non-trivial. |