Make the renderer owned instead of borrowed

This commit is contained in:
Chris Wong 2015-02-07 17:48:09 +13:00
parent 8be631411c
commit 1c0d5e9c31
3 changed files with 29 additions and 15 deletions

View file

@ -1,6 +1,6 @@
#![crate_type = "dylib"] #![crate_type = "dylib"]
#![feature(plugin_registrar, quote)] #![feature(plugin_registrar, quote)]
#![feature(core, rustc_private)] #![feature(collections, core, rustc_private)]
extern crate syntax; extern crate syntax;
extern crate rustc; extern crate rustc;

View file

@ -1,4 +1,4 @@
use syntax::ast::{Expr, Lit, TokenTree, TtDelimited, TtToken}; use syntax::ast::{Expr, Lit, Stmt, TokenTree, TtDelimited, TtToken};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt; use syntax::ext::base::ExtCtxt;
use syntax::parse; use syntax::parse;
@ -41,24 +41,30 @@ macro_rules! ident {
} }
pub fn parse(cx: &ExtCtxt, input: &[TokenTree], sp: Span) -> P<Expr> { pub fn parse(cx: &ExtCtxt, input: &[TokenTree], sp: Span) -> P<Expr> {
let mut render = Renderer::new(cx); let mut parser = Parser {
Parser {
in_attr: false, in_attr: false,
input: input, input: input,
span: sp, span: sp,
render: &mut render, render: Renderer::new(cx),
}.markups(); };
render.into_expr() parser.markups();
parser.into_render().into_expr()
} }
struct Parser<'cx: 'r, 's: 'cx, 'i, 'r> { struct Parser<'cx, 's: 'cx, 'i> {
in_attr: bool, in_attr: bool,
input: &'i [TokenTree], input: &'i [TokenTree],
span: Span, span: Span,
render: &'r mut Renderer<'cx, 's>, render: Renderer<'cx, 's>,
} }
impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> { impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
/// Finalize the `Parser`, returning the `Renderer` underneath.
fn into_render(self) -> Renderer<'cx, 's> {
let Parser { render, .. } = self;
render
}
/// Consume `n` items from the input. /// Consume `n` items from the input.
fn shift(&mut self, n: usize) { fn shift(&mut self, n: usize) {
self.input = &self.input[n..]; self.input = &self.input[n..];
@ -109,7 +115,8 @@ impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> {
// Block // Block
[TtDelimited(sp, ref d), ..] if d.delim == token::DelimToken::Brace => { [TtDelimited(sp, ref d), ..] if d.delim == token::DelimToken::Brace => {
self.shift(1); self.shift(1);
self.block(sp, &d.tts) let stmts = self.block(sp, &d.tts);
self.render.push_stmts(stmts);
}, },
// ??? // ???
_ => { _ => {
@ -210,13 +217,15 @@ impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> {
}} }}
} }
fn block(&mut self, sp: Span, tts: &[TokenTree]) { fn block(&mut self, sp: Span, tts: &[TokenTree]) -> Vec<P<Stmt>> {
Parser { let mut parse = Parser {
in_attr: self.in_attr, in_attr: self.in_attr,
input: tts, input: tts,
span: sp, span: sp,
render: self.render, render: Renderer::new(self.render.cx),
}.markups(); };
parse.markups();
parse.into_render().into_stmts()
} }
} }

View file

@ -54,6 +54,11 @@ impl<'cx, 's> Renderer<'cx, 's> {
stmts stmts
} }
/// Append the list of statements to the output.
pub fn push_stmts(&mut self, mut stmts: Vec<P<Stmt>>) {
self.stmts.append(&mut stmts);
}
/// Push an expression statement, also wrapping it with `try!`. /// Push an expression statement, also wrapping it with `try!`.
fn push_try(&mut self, expr: P<Expr>) { fn push_try(&mut self, expr: P<Expr>) {
let stmt = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr)); let stmt = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr));