use rust;
use rust::Token as rtok;
use rust::{TokenAndSpan, Span};
pub fn generate_rust_code<'a, 'b>(cx: &'a rust::ExtCtxt<'b>, tokens: Vec<TokenAndSpan>)
-> Box<rust::MacResult + 'a>
{
let reader = Box::new(TokenAndSpanArray::new(
&cx.parse_sess().span_diagnostic,
tokens));
let mut parser = rust::Parser::new(cx.parse_sess(), cx.cfg(), reader);
let expr = parser.parse_expr().unwrap();
cx.parse_sess.span_diagnostic.note_without_error(
&rust::expr_to_string(&expr));
rust::MacEager::expr(expr)
}
struct TokenAndSpanArray<'a>
{
sp_diag: &'a rust::Handler,
tokens: Vec<TokenAndSpan>,
current_idx: usize
}
impl<'a> TokenAndSpanArray<'a> {
fn new(sp_diag: &'a rust::Handler, tokens: Vec<TokenAndSpan>)
-> TokenAndSpanArray<'a>
{
TokenAndSpanArray {
sp_diag: sp_diag,
tokens: tokens,
current_idx: 0
}
}
fn current(&self) -> TokenAndSpan {
self.tokens[self.current_idx].clone()
}
fn current_span(&self) -> Span {
self.current().sp
}
}
impl<'a> rust::lexer::Reader for TokenAndSpanArray<'a> {
fn is_eof(&self) -> bool {
self.current().tok == rtok::Eof
}
fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
Ok(self.next_token())
}
fn next_token(&mut self) -> TokenAndSpan {
let cur = self.current();
self.current_idx = self.current_idx + 1;
cur
}
fn fatal(&self, m: &str) -> rust::FatalError {
self.sp_diag.span_fatal(self.current_span(), m)
}
fn emit_fatal_errors(&mut self) {}
fn err(&self, m: &str) {
self.sp_diag.span_err(self.current_span(), m);
}
fn peek(&self) -> TokenAndSpan {
self.current()
}
}