Implement for
expressions
This commit is contained in:
parent
4da1e369cd
commit
a530d73d25
3 changed files with 59 additions and 1 deletions
|
@ -102,6 +102,11 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
|
|||
self.shift(2);
|
||||
self.if_expr(sp);
|
||||
},
|
||||
// For
|
||||
[dollar!(), ident!(sp, name), ..] if name.as_str() == "for" => {
|
||||
self.shift(2);
|
||||
self.for_expr(sp);
|
||||
},
|
||||
// Splice
|
||||
[ref tt @ dollar!(), dollar!(), ..] => {
|
||||
self.shift(2);
|
||||
|
@ -192,6 +197,38 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
|
|||
self.render.emit_if(if_cond, if_body, else_body);
|
||||
}
|
||||
|
||||
fn for_expr(&mut self, sp: Span) {
|
||||
let mut pattern = vec![];
|
||||
loop { match self.input {
|
||||
[ident!(in_), ..] if in_.as_str() == "in" => {
|
||||
self.shift(1);
|
||||
break;
|
||||
},
|
||||
[ref tt, ..] => {
|
||||
self.shift(1);
|
||||
pattern.push(tt.clone());
|
||||
},
|
||||
_ => self.render.cx.span_fatal(sp, "invalid $for"),
|
||||
}}
|
||||
let pattern = self.new_rust_parser(pattern).parse_pat();
|
||||
let mut iterable = vec![];
|
||||
let body;
|
||||
loop { match self.input {
|
||||
[TtDelimited(sp, ref d), ..] if d.delim == DelimToken::Brace => {
|
||||
self.shift(1);
|
||||
body = self.block(sp, &d.tts);
|
||||
break;
|
||||
},
|
||||
[ref tt, ..] => {
|
||||
self.shift(1);
|
||||
iterable.push(tt.clone());
|
||||
},
|
||||
_ => self.render.cx.span_fatal(sp, "invalid $for"),
|
||||
}}
|
||||
let iterable = self.new_rust_parser(iterable).parse_expr();
|
||||
self.render.emit_for(pattern, iterable, body);
|
||||
}
|
||||
|
||||
fn splice(&mut self, sp: Span) -> P<Expr> {
|
||||
let mut tts = vec![];
|
||||
// First, munch a single token tree
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use syntax::ast::{Expr, Ident, Stmt};
|
||||
use syntax::ast::{Expr, Ident, Pat, Stmt};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::parse::token;
|
||||
|
@ -135,4 +135,9 @@ impl<'cx, 's> Renderer<'cx, 's> {
|
|||
};
|
||||
self.stmts.push(stmt);
|
||||
}
|
||||
|
||||
pub fn emit_for(&mut self, pattern: P<Pat>, iterable: P<Expr>, body: Vec<P<Stmt>>) {
|
||||
let stmt = quote_stmt!(self.cx, for $pattern in $iterable { $body });
|
||||
self.stmts.push(stmt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,4 +201,20 @@ mod control {
|
|||
assert_eq!(s, name);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_expr() {
|
||||
let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"];
|
||||
let s = html! {
|
||||
ul $for pony in &ponies {
|
||||
li $pony
|
||||
}
|
||||
}.to_string();
|
||||
assert_eq!(s, concat!(
|
||||
"<ul>",
|
||||
"<li>Apple Bloom</li>",
|
||||
"<li>Scootaloo</li>",
|
||||
"<li>Sweetie Belle</li>",
|
||||
"</ul>"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue