e0/src/parser.lalrpop

63 lines
1.4 KiB
Plaintext

use crate::ast::*;
grammar;
pub Program: Vec<Decl<()>> = Decl* => <>;
Decl: Decl<()> = {
Func => Decl::Func(<>),
};
Func: Func<()> = {
"fn" <name:Ident> "(" ")" "->" <return_ty:Type> "{" <stmts:Stmt*> "}" =>
Func { name, return_ty, stmts },
};
Stmt: Stmt<()> = {
"let" <name:Ident> <ty:ColonType?> "=" <expr:Expr> ";" =>
Stmt::Let(name, ty, expr),
"return" <expr:Expr?> ";" => Stmt::Return(expr),
IfElse => Stmt::IfElse(<>),
};
ColonType: Type = ":" <ty:Type> => ty;
IfElse: IfElse<()> =
"if" <cond:Expr> "{" <body:Stmt*> "}" <else_clause:Else?> =>
IfElse { cond, body, else_clause };
Else: ElseClause<()> = "else" <else_clause:Else_> => else_clause;
Else_: ElseClause<()> = {
IfElse => ElseClause::If(Box::new(<>)),
"{" <body:Stmt*> "}" => ElseClause::Body(body),
};
Expr: Expr<()> = {
#[precedence(level = "0")]
"(" <expr:Expr> ")" => expr,
#[precedence(level = "0")]
r"[0-9]+" => Expr { kind: ExprKind::Int(<>.parse::<i64>().unwrap()), ty: () },
#[precedence(level = "0")]
Ident => Expr { kind: ExprKind::Var(<>), ty: () },
#[precedence(level = "13")]
#[assoc(side = "none")]
<left:Expr> <op:CompareOp> <right:Expr> => Expr {
kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)),
ty: (),
},
};
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();