62 lines
1.4 KiB
Text
62 lines
1.4 KiB
Text
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();
|