summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-09 13:14:02 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-09 13:14:02 +0800
commitf4492fe0363ec0aee12391219559d616f75f662e (patch)
treeb3e3ce13e907b6e2db65cfc38869e3e7639a9ae5
parent00662f7843b658eceb85b2fb182212cacc5615cc (diff)
downloadmrust-f4492fe0363ec0aee12391219559d616f75f662e.tar.gz
Notes - Planning another rewrite of macro_rules! handling
-rw-r--r--Notes/MacroRules.md72
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.