Compiler experimentation.
1use crate::lex::Token;
2
3#[derive(Debug)]
4pub struct Assignment<'s> {
5 pub name: &'s str,
6 pub value: Expr<'s>,
7}
8
9#[derive(Debug)]
10pub struct DoExpr<'s> {
11 pub assignments: Vec<Assignment<'s>>,
12 pub value: Box<Expr<'s>>,
13}
14
15#[derive(Debug)]
16pub enum Expr<'s> {
17 Do(DoExpr<'s>),
18 Name(&'s str),
19 Num(u64),
20}
21
22#[derive(Debug)]
23pub struct Ast<'s> {
24 pub main_expr: Expr<'s>,
25}
26
27pub fn parse<'s>(tokens: &[Token<'s>]) -> Ast<'s> {
28 ast_parser::ast(tokens).expect("parsing failed, sorry :(")
29}
30
31peg::parser! {
32 grammar ast_parser<'s>() for [Token<'s>] {
33 use Token::*;
34
35 pub rule ast() -> Ast<'s> =
36 [Ident("main")] [Colon] [Ident("I32")]
37 [Ident("main")] [Equals] e:expr() {
38 Ast { main_expr: e }
39 }
40
41 rule expr() -> Expr<'s>
42 = e:do() { Expr::Do(e) }
43 / [Ident(i)] { Expr::Name(i) }
44 / [Num(n)] { Expr::Num(n) }
45
46 rule do() -> DoExpr<'s> = [Do] [LBrace] assignments:assignment()* value:expr() [RBrace] {
47 DoExpr { assignments, value: Box::new(value) }
48 }
49
50 rule assignment() -> Assignment<'s> = [Ident(name)] [Equals] value:expr() [SemiColon] {
51 Assignment { name, value }
52 }
53 }
54}