gust/src/grammar.lalrpop

68 lines
1.3 KiB
Plaintext

use crate::ast::*;
grammar;
pub Program: Program = <items:Item*> => Program {
items,
};
Item: Item = {
<left:@L> <kind:ItemKind> <right:@R> =>
Item { kind, loc: Loc::new(left, right) },
};
ItemKind: ItemKind = {
"fn" <funcdef:FuncDef> => ItemKind::FuncDef(funcdef),
};
FuncDef: FuncDef =
<left:@L> <ident:Ident> <body:BlockExpr> <right:@R> => FuncDef {
name: Some(ident),
body,
loc: Loc::new(left, right),
};
Expr: Expr =
<left:@L> <kind:ExprKind> <right:@R> => Expr {
kind,
loc: Loc::new(left, right),
};
ExprKind: ExprKind = {
<literal:Literal> => ExprKind::Literal(literal),
"(" <expr:Expr> ")" => ExprKind::Paren(Box::new(expr)),
};
BlockExpr: Expr =
<left:@L> "{" <stmts:StmtSemi*> <expr:Expr> "}" <right:@R> => Expr {
kind: ExprKind::Sequence(Sequence {
stmts,
inner: Box::new(expr),
}),
loc: Loc::new(left, right),
};
StmtSemi: Stmt =
<left:@L> <kind:StmtKind> <right:@R> ";" => Stmt {
kind,
loc: Loc::new(left, right),
};
StmtKind: StmtKind = {
<expr:Expr> => StmtKind::Expr(expr),
};
Literal: Literal =
<left:@L> <kind:LiteralKind> <right:@R> => Literal {
kind,
loc: Loc::new(left, right),
};
LiteralKind: LiteralKind = {
r"[0-9]+" => LiteralKind::Int(<>.parse().unwrap()),
};
// Random shit
Ident: String = r"[A-Za-z_]+" => <>.to_owned();