diff --git a/src/grammar.pest b/src/grammar.pest index 186a81f..9422476 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -1 +1,19 @@ file = { "hello world" } + +literal = { string | number | boolean } + +string = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" } + +number = _{ byte | float | integer } + +integer = @{ "-"? ~ ASCII_DIGIT+ } + +float = @{ + "-"? ~ (ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT* | ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+) +} + +byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} } + +boolean = @{ "true" | "false" } + +WHITESPACE = _{ " " | "\t" | "\r" | "\n" } diff --git a/src/lib.rs b/src/lib.rs index a5c0a96..10938b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,97 @@ pub fn parse<'a>(src: &'a str) -> Result, pest::error::Error( + rule: Rule, + src: &'a str, +) -> Result, pest::error::Error> { + SnekParser::parse(rule, src) +} + #[cfg(test)] mod test { - use crate::parse; + + use pest::iterators::Pair; + + use crate::{parse, parse_rule, Rule}; + + fn parse_token<'a>(rule: Rule, src: &'a str) -> Pair<'a, Rule> { + let mut pairs = parse_rule(rule, src).unwrap(); + pairs.next().unwrap() + } + + fn parse_inner_token<'a>(rule: Rule, src: &'a str) -> Pair<'a, Rule> { + parse_token(rule, src).into_inner().next().unwrap() + } #[test] fn it_parses() { parse("hello world").unwrap(); } + + #[test] + fn it_parses_numbers() { + assert_eq!( + parse_inner_token(Rule::literal, "0").as_rule(), + Rule::integer + ); + assert_eq!( + parse_inner_token(Rule::literal, "100").as_rule(), + Rule::integer + ); + } + + #[test] + fn it_parses_floats() { + assert_eq!( + parse_inner_token(Rule::literal, "0.").as_rule(), + Rule::float + ); + assert_eq!( + parse_inner_token(Rule::literal, ".5").as_rule(), + Rule::float + ); + assert_eq!( + parse_inner_token(Rule::literal, "11.15").as_rule(), + Rule::float + ); + } + + #[test] + fn it_parses_bytes() { + assert_eq!( + parse_inner_token(Rule::literal, "0xFF").as_rule(), + Rule::byte + ); + assert_eq!( + parse_inner_token(Rule::literal, "0b0010").as_rule(), + Rule::byte + ); + } + + #[test] + fn it_parses_strings() { + assert_eq!( + parse_inner_token(Rule::literal, r#""Hello world""#).as_rule(), + Rule::string + ); + assert_eq!( + parse_inner_token(Rule::literal, r#""""#).as_rule(), + Rule::string + ); + } + + #[test] + fn it_parses_booleans() { + assert_eq!( + parse_inner_token(Rule::literal, "true").as_rule(), + Rule::boolean + ); + assert_eq!(parse_inner_token(Rule::literal, "true").as_str(), "true"); + assert_eq!( + parse_inner_token(Rule::literal, "false").as_rule(), + Rule::boolean + ); + assert_eq!(parse_inner_token(Rule::literal, "false").as_str(), "false"); + } }