use crate::lex::Token; #[derive(Debug)] pub struct Assignment<'s> { pub name: &'s str, pub value: Expr<'s>, } #[derive(Debug)] pub struct DoExpr<'s> { pub assignments: Vec>, pub value: Box>, } #[derive(Debug)] pub enum Expr<'s> { Do(DoExpr<'s>), Name(&'s str), Num(u64), } #[derive(Debug)] pub struct Ast<'s> { pub main_expr: Expr<'s>, } pub fn parse<'s>(tokens: &[Token<'s>]) -> Ast<'s> { ast_parser::ast(tokens).expect("parsing failed, sorry :(") } peg::parser! { grammar ast_parser<'s>() for [Token<'s>] { use Token::*; pub rule ast() -> Ast<'s> = [Ident("main")] [Colon] [Ident("I32")] [Ident("main")] [Equals] e:expr() { Ast { main_expr: e } } rule expr() -> Expr<'s> = e:do() { Expr::Do(e) } / [Ident(i)] { Expr::Name(i) } / [Num(n)] { Expr::Num(n) } rule do() -> DoExpr<'s> = [Do] [LBrace] assignments:assignment()* value:expr() [RBrace] { DoExpr { assignments, value: Box::new(value) } } rule assignment() -> Assignment<'s> = [Ident(name)] [Equals] value:expr() [SemiColon] { Assignment { name, value } } } }