2021-11-03 16:27:42 -07:00
|
|
|
use crate::ast::*;
|
|
|
|
|
|
|
|
peg::parser! {
|
2021-11-03 18:01:23 -07:00
|
|
|
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']+)
|
2021-11-03 16:27:42 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2021-11-03 18:01:23 -07:00
|
|
|
|
|
|
|
#[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);
|
|
|
|
*/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|