use std::str::FromStr; use crate::ast; use crate::types; grammar; pub LiteralInt: ast::LiteralInt = { => ast::LiteralInt{value: i64::from_str(literal).unwrap()} }; pub Identifier: ast::Identifier = { => ast::Identifier{name: i.to_string()} }; pub FunctionCall: ast::FunctionCall = { > "(" >> ")" => ast::FunctionCall{name:i, arguments: args} } pub Expression: Box = { > "+" > => Box::new(ast::Expression::Op(ast::Operation{left: l, op: ast::Operator::Plus, right: r})), > "-" > => Box::new(ast::Expression::Op(ast::Operation{left: l, op: ast::Operator::Minus, right: r})), Factor, } pub Factor: Box = { > "*" > => Box::new(ast::Expression::Op(ast::Operation{left: l, op: ast::Operator::Mul, right: r})), > "/" > => Box::new(ast::Expression::Op(ast::Operation{left: l, op: ast::Operator::Div, right: r})), Term, } pub Term: Box = { Spanned => Box::new(ast::Expression::LiteralInt(<>)), Spanned => Box::new(ast::Expression::Identifier(<>)), Spanned => Box::new(ast::Expression::FunctionCall(<>)), "(" ")" => e } pub LetStatement: ast::Assignment = { //TODO: support destructuring with tuples, when they exist. //TODO: add mut, weak "let" > "=" > => ast::Assignment{name: n, type_usage: None, expression: e}, "let" > ":" > "=" > => ast::Assignment{name: n, type_usage: Some(t), expression: e}, } pub Statement: ast::Statement = { > => ast::Statement::Assignment(l), > => ast::Statement::Expression(e), } pub Block: ast::Block = { "{" >> "}" => ast::Block{statements: s} } pub TypeUsage: ast::TypeUsage = { > => ast::TypeUsage{name: n, ty: types::SpecifiedType::Unknown} } pub VariableDeclaration: ast::VariableDeclaration = { > ":" > => ast::VariableDeclaration{name: i, type_usage: t}, } pub Function: ast::Function = { "fn" > "(" > ")" > => ast::Function{name: n, arguments: args, block: b, return_type: rt} } pub Module: ast::Module = { => ast::Module{functions: fs} } // From https://lalrpop.github.io/lalrpop/tutorial/006_macros.html // Comma seperated list of T with optional trailing comma Comma: Vec = { ",")*> => match e { None => v, Some(e) => { let mut v = v; v.push(e); v } } }; LineDelimiter: Vec = { r"\n|;")*> => { let mut v = v; v.push(e); v } }; Spanned: ast::Spanned = { => ast::Spanned{span: ast::Span{left: l, right: r}, value: rule} };