use crate::ast::*; peg::parser! { grammar schala_parser() for str { pub rule program() -> AST = n:(statement() ** delimiter() ) { AST { id: Default::default(), statements: n.into() } } rule delimiter() = ";" / "\n" rule statement() -> Statement = expr:expression() { Statement { id: Default::default(), location: Default::default(), kind: StatementKind::Expression(expr) } } pub rule expression() -> Expression = kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } } rule expression_kind() -> ExpressionKind = primary() rule primary() -> ExpressionKind = float_literal() / nat_literal() rule nat_literal() -> ExpressionKind = ("0x" / "0b")? digits:digits() { ExpressionKind::NatLiteral(digits.parse().unwrap()) } rule float_literal() -> ExpressionKind = ds:$( digits() "." digits()? / "." digits() ) { ExpressionKind::FloatLiteral(ds.parse().unwrap()) } rule digits() -> &'input str = $((digit_group() "_"*)+) rule digit_group() -> &'input str = $(['0'..='9']+) } } #[cfg(test)] mod test { use super::*; #[test] fn new_parser() { let parsed = schala_parser::expression("4"); assert_eq!(parsed.unwrap(), Expression { id: Default::default(), type_anno: None, kind: ExpressionKind::NatLiteral(4) }); let parsed = schala_parser::program("56.1"); if let Err(ref err) = parsed { println!("{}", err); } assert_eq!(parsed.unwrap(), AST { id: Default::default(), statements: vec![ Statement { id: Default::default(), location: Default::default(), kind: StatementKind::Expression(Expression { id: Default::default(), type_anno: None, kind: ExpressionKind::FloatLiteral(56.1) }) } ].into() }); /* let parsed = schala_parser::expression("quincy"); println!("{:?}", parsed.unwrap_err()); assert_eq!(1, 2); */ } }