use crate::ast::*; grammar; pub Program: Vec> = Decl* => <>; Decl: Decl<()> = { Func => Decl::Func(<>), }; Func: Func<()> = { "fn" "(" ")" "->" "{" "}" => Func { name, args, return_ty, stmts, ty: (), }, }; Args: Vec = Punct<",", Arg>? => <>.unwrap_or_else(|| Vec::new()); Arg: Arg = ":" => Arg { name, ty }; Stmt: Stmt<()> = { "let" "=" ";" => Stmt::Let(name, ty, expr), "return" ";" => Stmt::Return(expr), IfElse => Stmt::IfElse(<>), }; ColonType: Type = ":" => ty; IfElse: IfElse<()> = "if" "{" "}" => IfElse { cond, body, else_clause }; Else: ElseClause<()> = "else" => else_clause; Else_: ElseClause<()> = { IfElse => ElseClause::If(Box::new(<>)), "{" "}" => ElseClause::Body(body), }; Expr: Expr<()> = { #[precedence(level = "0")] "(" ")" => expr, #[precedence(level = "0")] r"[0-9]+" => Expr { kind: ExprKind::Int(<>.parse::().unwrap()), ty: () }, #[precedence(level = "0")] Ident => Expr { kind: ExprKind::Var(<>), ty: () }, #[precedence(level = "2")] "(" ?> ")" => Expr { kind: ExprKind::Call(func, args.unwrap_or_else(|| vec![])), ty: () }, #[precedence(level = "8")] #[assoc(side = "left")] => Expr { kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)), ty: (), }, #[precedence(level = "13")] #[assoc(side = "none")] => Expr { kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)), ty: (), }, }; AddOp: Op = { "+" => Op::Plus, }; CompareOp: Op = { "<" => Op::LessThan, ">" => Op::GreaterThan, }; Type: Type = { "int" => Type::Int, }; Ident: String = r"([A-Za-z][A-Za-z0-9_]*)|(_[A-Za-z0-9_]+)" => <>.to_string(); Punct: Vec = { P => vec![], )?> => { match rest { Some(rest) => { let (_, mut vec) = rest; vec.insert(0, first); vec } None => vec![first], } }, };