From c593e4c87229b643ad5337164ff46d2c9536c94e Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 17 Nov 2022 10:56:59 +0100 Subject: [PATCH] Parse simple number literal --- Cargo.lock | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 13 ++++++-- src/parser.rs | 37 ++++++++++++++++++++++ 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/parser.rs diff --git a/Cargo.lock b/Cargo.lock index 7723933..f954e52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" +dependencies = [ + "const-random", +] + [[package]] name = "anyhow" version = "1.0.66" @@ -25,6 +34,21 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chumsky" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4" +dependencies = [ + "ahash", +] + [[package]] name = "clap" version = "4.0.26" @@ -62,6 +86,45 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "const-random" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +dependencies = [ + "getrandom", + "once_cell", + "proc-macro-hack", + "tiny-keccak", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.4.0" @@ -119,6 +182,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.47" @@ -159,6 +228,7 @@ name = "tada" version = "0.0.0" dependencies = [ "anyhow", + "chumsky", "clap", ] @@ -171,6 +241,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "unicode-ident" version = "1.0.5" @@ -183,6 +262,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index ba6b4c2..43fe296 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,5 @@ edition = "2021" [dependencies] anyhow = "1.0.66" +chumsky = "0.8.0" clap = { version = "4.0.26", features = ["derive", "deprecated"] } diff --git a/src/main.rs b/src/main.rs index a3aa5f8..795507f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ use std::fs; use std::path::PathBuf; +use chumsky::Parser as _; use clap::Parser; mod builtin; +mod parser; mod table; mod value; @@ -25,9 +27,14 @@ fn main() -> anyhow::Result<()> { match args.command { Command::Parse { file } => { let content = fs::read_to_string(&file)?; - print!("{content}"); - if !content.ends_with('\n') { - println!(); + match parser::parser().parse(&content as &str) { + Ok(lit) => println!("Successful parse: {lit:#?}"), + Err(errs) => { + println!("Parsing failed"); + for err in errs { + println!("{err:?}"); + } + } } } } diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000..ef5948f --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,37 @@ +use chumsky::prelude::*; + +#[derive(Debug)] +pub enum Lit { + Num(i64), +} + +fn lit_num() -> impl Parser> { + let sign = just('+') + .or(just('-')) + .or_not() + .map(|s| if s == Some('-') { -1_i128 } else { 1_i128 }); + + let digits = text::int(10); + + sign.then(digits).try_map(|(sign, digits), span| { + // u64::MIN and u32::MAX have 19 digits in base 10 + if digits.len() > 19 { + return Err(Simple::custom(span, "number out of range")); + } + + let number = sign * digits.parse::().unwrap(); + if number < i64::MIN.into() || number > u64::MAX.into() { + return Err(Simple::custom(span, "number out of range")); + } + + Ok(number as i64) + }) +} + +fn lit() -> impl Parser> { + lit_num().map(Lit::Num) +} + +pub fn parser() -> impl Parser> { + lit().padded().then_ignore(end()) +}