From 3a8992ab84837bf96d41e1c9af79b3c30f8f2e31 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 Jun 2015 11:00:15 -0400 Subject: [PATCH] macro expansion compiles now --- src/grammar/parse_tree.rs | 14 ++++++++++- src/main.rs | 5 ++-- src/normalize/macro_expand.rs | 47 +++++++++++++++++++---------------- src/normalize/mod.rs | 5 +--- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/grammar/parse_tree.rs b/src/grammar/parse_tree.rs index f3722bb..de66eb8 100644 --- a/src/grammar/parse_tree.rs +++ b/src/grammar/parse_tree.rs @@ -198,7 +198,7 @@ impl Display for Symbol { Symbol::Nonterminal(ref s) => write!(fmt, "{}", s), Symbol::Macro(ref m) => - write!(fmt, "{}<{}>", m.name, Sep(", ", &m.args)), + write!(fmt, "{}", m), Symbol::Plus(ref s) => write!(fmt, "{}+", s), Symbol::Question(ref s) => @@ -213,6 +213,18 @@ impl Display for Symbol { } } +impl MacroSymbol { + pub fn canonical_form(&self) -> String { + format!("{}", self) + } +} + +impl Display for MacroSymbol { + fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> { + write!(fmt, "{}<{}>", self.name, Sep(", ", &self.args)) + } +} + struct Sep(&'static str, S); impl<'a,S:Display> Display for Sep<&'a Vec> { diff --git a/src/main.rs b/src/main.rs index 31f326c..768fb9d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,9 +3,10 @@ extern crate rusty_peg; extern crate regex; -mod intern; -mod parser; mod grammar; +mod intern; +mod normalize; +mod parser; fn main() { println!("Hello, world!"); diff --git a/src/normalize/macro_expand.rs b/src/normalize/macro_expand.rs index 938dab9..06a0d94 100644 --- a/src/normalize/macro_expand.rs +++ b/src/normalize/macro_expand.rs @@ -1,7 +1,8 @@ -use std::collections::HashMap; +use std::collections::HashSet; +use intern::{intern, InternedString}; use grammar::parse_tree::{Grammar, GrammarItem, MacroSymbol, Symbol}; -pub fn expand_macros(input: pt::Grammar) { +pub fn expand_macros(input: Grammar) { let Grammar { type_name, items } = input; let mut expander = MacroExpander::new(); } @@ -12,8 +13,8 @@ struct MacroExpander { } impl MacroExpander { - fn new(items: Vec) -> MacroExpander { - MacroExpander { items: items, expansion_stack: Vec::new(), expansion_set: HashSet::new() } + fn new() -> MacroExpander { + MacroExpander { expansion_stack: Vec::new(), expansion_set: HashSet::new() } } fn expand(&mut self, items: &mut Vec) { @@ -22,7 +23,7 @@ impl MacroExpander { // Find any macro uses in items added since last round and // replace them in place with the expanded version: for item in &mut items[counter..] { - self.replace(item); + self.replace_item(item); } counter = items.len(); @@ -33,7 +34,7 @@ impl MacroExpander { fn replace_item(&mut self, item: &mut GrammarItem) { match *item { GrammarItem::TokenType(..) => { } - GrammarItem::Nonterminal(ref data) => { + GrammarItem::Nonterminal(ref mut data) => { // Ignore macro definitions. They will be expanded in // due course. if !data.args.is_empty() { @@ -41,31 +42,31 @@ impl MacroExpander { } for alternative in &mut data.alternatives { - self.replace_symbol(&mut alternative.symbol); + self.replace_symbols(&mut alternative.expr); } } } } + fn replace_symbols(&mut self, symbols: &mut [Symbol]) { + for symbol in symbols { + self.replace_symbol(symbol); + } + } + fn replace_symbol(&mut self, symbol: &mut Symbol) { let key; match *symbol { - Symbol::Macro(ref mut macro) => { - for sym in &mut macro.args { - self.replace(sym); - } - - key = symbol.canonical_form(); - if self.expansion_set.insert(key) { - self.expansion_stack.push(macro.clone()); - } - } - Symbol::Expr(ref mut syms) => { - for sym in syms { + Symbol::Macro(ref mut m) => { + for sym in &mut m.args { self.replace_symbol(sym); } - return; + + key = intern(&m.canonical_form()); + if self.expansion_set.insert(key) { + self.expansion_stack.push(m.clone()); + } } Symbol::Terminal(_) | Symbol::Nonterminal(_) => { @@ -79,9 +80,13 @@ impl MacroExpander { self.replace_symbol(sym); return; } + Symbol::Expr(ref mut syms) => { + self.replace_symbols(syms); + return; + } } // we only get here if this is a macro expansion - *symbol = Symbol::Nonterminal(intern(key)); + *symbol = Symbol::Nonterminal(key); } } diff --git a/src/normalize/mod.rs b/src/normalize/mod.rs index b227358..4280ca0 100644 --- a/src/normalize/mod.rs +++ b/src/normalize/mod.rs @@ -6,9 +6,6 @@ use grammar::parse_tree as pt; -pub fn normalize(input: pt::Grammar) -> Result { -} - // These are executed *IN ORDER*: // Expands macros @@ -22,7 +19,7 @@ pub fn normalize(input: pt::Grammar) -> Result { // // AFTER THIS POINT: No more macros, macro references, or guarded // alternatives, though type indirections may occur. -// mod macro_expand; +mod macro_expand; // Computes types where the user omitted them (or // from macro byproducts).