diff --git a/Cargo.lock b/Cargo.lock index 3b71da9..13b6e31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,6 +558,33 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2 1.0.30", + "quote 1.0.10", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + [[package]] name = "phf" version = "0.7.24" @@ -895,6 +922,7 @@ dependencies = [ "ena", "failure", "itertools", + "peg", "pretty_assertions", "radix_trie", "schala-lang-codegen", diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index 7c68af6..d1dd07f 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -1,8 +1,72 @@ use crate::ast::*; peg::parser! { - grammar yolo() for str { - rule number() -> + 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); + */ + + } + +}