Rewrite if expression stuff

This commit is contained in:
Chris Wong 2015-03-01 19:34:08 -05:00
parent b1e0647192
commit ef1e305468
3 changed files with 33 additions and 21 deletions
maud_macros

View file

@ -146,7 +146,8 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
} }
fn if_expr(&mut self, sp: Span) { fn if_expr(&mut self, sp: Span) {
let mut cond = vec![]; // Parse the initial if
let mut cond_tts = vec![];
let if_body; let if_body;
loop { match self.input { loop { match self.input {
[TtDelimited(sp, ref d), ..] if d.delim == DelimToken::Brace => { [TtDelimited(sp, ref d), ..] if d.delim == DelimToken::Brace => {
@ -156,28 +157,39 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
}, },
[ref tt, ..] => { [ref tt, ..] => {
self.shift(1); self.shift(1);
cond.push(tt.clone()); cond_tts.push(tt.clone());
}, },
[] => self.render.cx.span_fatal(sp, "expected body for this $if"), [] => self.render.cx.span_fatal(sp, "expected body for this `if`"),
}} }}
let cond = self.new_rust_parser(cond).parse_expr(); let if_cond = self.new_rust_parser(cond_tts).parse_expr();
// Parse the (optional) else
let else_body = match self.input { let else_body = match self.input {
[dollar!(), ident!(name), ..] if name.as_str() == "else" => { [dollar!(), ident!(else_), ..] if else_.as_str() == "else" => {
self.shift(2); self.shift(2);
let else_body = { match self.input {
// Parse a single markup, but capture the result rather [ident!(sp, if_), ..] if if_.as_str() == "if" => {
// than emitting it right away self.shift(1);
let mut render = self.render.fork(); let else_body = {
mem::swap(&mut self.render, &mut render); // Parse an if expression, but capture the result
self.markup(); // rather than emitting it right away
mem::swap(&mut self.render, &mut render); let mut render = self.render.fork();
render.into_stmts() mem::swap(&mut self.render, &mut render);
}; self.if_expr(sp);
Some(else_body) mem::swap(&mut self.render, &mut render);
render.into_stmts()
};
Some(else_body)
},
[TtDelimited(sp, ref d), ..] if d.delim == DelimToken::Brace => {
self.shift(1);
Some(self.block(sp, &d.tts))
},
_ => self.render.cx.span_fatal(sp, "invalid syntax"),
}
}, },
_ => None, _ => None,
}; };
self.render.emit_if(cond, if_body, else_body); self.render.emit_if(if_cond, if_body, else_body);
} }
fn splice(&mut self, sp: Span) -> P<Expr> { fn splice(&mut self, sp: Span) -> P<Expr> {

View file

@ -126,12 +126,12 @@ impl<'cx, 's> Renderer<'cx, 's> {
self.write(">"); self.write(">");
} }
pub fn emit_if(&mut self, cond: P<Expr>, if_body: Vec<P<Stmt>>, pub fn emit_if(&mut self, if_cond: P<Expr>, if_body: Vec<P<Stmt>>,
else_body: Option<Vec<P<Stmt>>>) { else_body: Option<Vec<P<Stmt>>>) {
let stmt = match else_body { let stmt = match else_body {
None => quote_stmt!(self.cx, if $cond { $if_body }), None => quote_stmt!(self.cx, if $if_cond { $if_body }),
Some(else_body) => Some(else_body) =>
quote_stmt!(self.cx, if $cond { $if_body } else { $else_body }), quote_stmt!(self.cx, if $if_cond { $if_body } else { $else_body }),
}; };
self.stmts.push(stmt); self.stmts.push(stmt);
} }

View file

@ -190,9 +190,9 @@ mod control {
let s = html! { let s = html! {
$if number == 1 { $if number == 1 {
"one" "one"
} $else $if number == 2 { } $else if number == 2 {
"two" "two"
} $else $if number == 3 { } $else if number == 3 {
"three" "three"
} $else { } $else {
"oh noes" "oh noes"