e0/src/parser.lalrpop

96 lines
2.2 KiB
Text
Raw Normal View History

2022-04-06 02:33:16 +00:00
use crate::ast::*;
grammar;
2022-04-06 11:20:47 +00:00
pub Program: Vec<Decl<()>> = Decl* => <>;
2022-04-06 02:33:16 +00:00
2022-04-06 11:20:47 +00:00
Decl: Decl<()> = {
2022-04-06 04:32:37 +00:00
Func => Decl::Func(<>),
2022-04-06 02:33:16 +00:00
};
2022-04-06 11:20:47 +00:00
Func: Func<()> = {
2022-04-28 16:33:26 +00:00
"fn" <name:Ident> "(" <args:Args> ")" "->" <return_ty:Type> "{" <stmts:Stmt*> "}" =>
Func { name, args, return_ty, stmts, ty: (), },
2022-04-06 02:33:16 +00:00
};
2022-04-28 16:33:26 +00:00
Args: Vec<Arg> = Punct<",", Arg>? => <>.unwrap_or_else(|| Vec::new());
Arg: Arg = <name:Ident> ":" <ty:Type> => Arg { name, ty };
2022-04-06 11:20:47 +00:00
Stmt: Stmt<()> = {
"let" <name:Ident> <ty:ColonType?> "=" <expr:Expr> ";" =>
2022-04-06 04:32:37 +00:00
Stmt::Let(name, ty, expr),
"return" <expr:Expr?> ";" => Stmt::Return(expr),
2022-04-06 11:20:47 +00:00
IfElse => Stmt::IfElse(<>),
2022-04-06 02:33:16 +00:00
};
2022-04-06 11:20:47 +00:00
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),
2022-04-06 02:33:16 +00:00
};
2022-04-06 11:20:47 +00:00
Expr: Expr<()> = {
#[precedence(level = "0")]
2022-04-06 04:32:37 +00:00
"(" <expr:Expr> ")" => expr,
2022-04-06 11:20:47 +00:00
#[precedence(level = "0")]
r"[0-9]+" => Expr { kind: ExprKind::Int(<>.parse::<i64>().unwrap()), ty: () },
#[precedence(level = "0")]
Ident => Expr { kind: ExprKind::Var(<>), ty: () },
2022-04-13 07:09:56 +00:00
#[precedence(level = "2")]
<func:Ident> "(" <args:Punct<",", Expr>?> ")" =>
Expr { kind: ExprKind::Call(func, args.unwrap_or_else(|| vec![])), ty: () },
2022-04-13 07:09:56 +00:00
2022-04-28 16:33:26 +00:00
#[precedence(level = "8")]
#[assoc(side = "left")]
<left:Expr> <op:AddOp> <right:Expr> => Expr {
kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)),
ty: (),
},
2022-04-06 11:20:47 +00:00
#[precedence(level = "13")]
#[assoc(side = "none")]
<left:Expr> <op:CompareOp> <right:Expr> => Expr {
kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)),
ty: (),
},
};
2022-04-28 16:33:26 +00:00
AddOp: Op = {
"+" => Op::Plus,
};
2022-04-06 11:20:47 +00:00
CompareOp: Op = {
"<" => Op::LessThan,
">" => Op::GreaterThan,
2022-04-06 02:33:16 +00:00
};
Type: Type = {
2022-04-06 04:32:37 +00:00
"int" => Type::Int,
2022-04-06 02:33:16 +00:00
};
Ident: String = r"([A-Za-z][A-Za-z0-9_]*)|(_[A-Za-z0-9_]+)" => <>.to_string();
2022-04-13 07:09:56 +00:00
Punct<P, T>: Vec<T> = {
P => vec![],
<first:T> <rest:(P Punct<P, T>)?> => {
match rest {
Some(rest) => {
let (_, mut vec) = rest;
vec.insert(0, first);
vec
}
None => vec![first],
}
},
};