use crate::lexer;
use crate::location;
use crate::src::SrcExpr;
use crate::src::SrcItem;
use crate::src::SrcModule;
use crate::src::SrcType;
use crate::src::SrcIdent;
use crate::src::SrcStmt;
grammar;
pub Expr: Box<SrcExpr> = {
<int_literal> => Box::new(SrcExpr::IntegerLiteral(<>.parse::<i64>().unwrap())),
<string_literal> => Box::new(SrcExpr::StringLiteral(<>)),
"(" <Expr> ")" => Box::new(SrcExpr::ParenExpr(<>)),
};
pub Ident: SrcIdent = {
<ident> => SrcIdent(<>)
}
Comma<T>: Vec<T> = {
<v:(<T> ",")*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
}
Decl: (SrcIdent, SrcType) = {
<v:Ident> ":" <t:Type> => (v, t)
}
pub Block: SrcStmt = {
"{" <Stmt*> "}" => SrcStmt::BlockStmt(<>),
}
pub Stmt: Box<SrcStmt> = {
<Block> => Box::new(<>),
<Expr> ";" => Box::new(SrcStmt::ExprStmt(<>)),
}
pub Item: SrcItem = {
"def" <f:Ident> "(" <xs:Comma<Decl>> ")" ":" <r:Type> <b:Block> =>
SrcItem::Def(
f,
None,
Some(SrcExpr::FunctionExpr(xs, r, b))
),
}
pub Module: SrcModule = {
<Item+> => SrcModule(<>),
}
pub Type: SrcType = {
<Ident> => SrcType::NamedType(<>),
}
extern {
type Location = location::Location;
type Error = lexer::LexicalError;
enum lexer::Tok {
"def" => lexer::Tok::Def,
";" => lexer::Tok::Semi,
":" => lexer::Tok::Colon,
"(" => lexer::Tok::LeftParen,
")" => lexer::Tok::RightParen,
"-" => lexer::Tok::Minus,
"+" => lexer::Tok::Plus,
"," => lexer::Tok::Comma,
"{" => lexer::Tok::LeftBracket,
"}" => lexer::Tok::RightBracket,
ident => lexer::Tok::Ident(<String>),
string_literal => lexer::Tok::Str(<String>),
int_literal => lexer::Tok::Int(<String>),
}
}