diff --git a/Cargo.lock b/Cargo.lock index f061451..31941ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,12 +17,6 @@ version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.4.1" @@ -35,26 +29,30 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chainchomp" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d2a1245e6c4de8678a7db17ee514a9781876a53a8fb800e6424664bf8b23595" +checksum = "c052190a3d3b181b6b73aa4d26ac3185447fa7cd8033a19ac0f21914136cf155" [[package]] name = "clipboard-win" -version = "4.5.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" dependencies = [ "error-code", - "str-buf", - "winapi", ] [[package]] name = "csc" -version = "0.1.8" +version = "0.1.9" dependencies = [ "anyhow", "chainchomp", @@ -83,28 +81,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "error-code" -version = "2.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" -dependencies = [ - "libc", - "str-buf", -] +checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" [[package]] name = "fd-lock" -version = "3.0.13" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" +checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" dependencies = [ "cfg-if", "rustix", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -113,7 +107,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -124,9 +118,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linux-raw-sys" @@ -157,12 +151,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if", + "cfg_aliases", "libc", ] @@ -221,20 +216,20 @@ version = "0.38.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" dependencies = [ - "bitflags 2.4.1", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustyline" -version = "12.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "994eca4bca05c87e86e15d90fc7a91d1be64b4482b38cb2d27474568fe7c9db9" +checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" dependencies = [ - "bitflags 2.4.1", + "bitflags", "cfg-if", "clipboard-win", "fd-lock", @@ -244,31 +239,18 @@ dependencies = [ "memchr", "nix", "radix_trie", - "scopeguard", "unicode-segmentation", "unicode-width", "utf8parse", - "winapi", + "windows-sys 0.52.0", ] -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "smallvec" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" -[[package]] -name = "str-buf" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" - [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -288,34 +270,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets 0.48.5", ] -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.4", ] [[package]] @@ -324,13 +293,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -339,42 +323,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + [[package]] name = "yansi" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 6d06a2e..0ae712c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "csc" -version = "0.1.8" +version = "0.1.9" edition = "2021" authors = ["Zahash "] description = "Command Line Scientific Calculator" @@ -11,8 +11,8 @@ repository = "https://github.com/zahash/csc" anyhow = "1" regex = { version = "1" } lazy_static = { version = "1" } -rustyline = { version = "12" } -chainchomp = { version = "0.1" } +rustyline = { version = "14" } +chainchomp = { version = "0.2.1" } [dev-dependencies] pretty_assertions = { version = "1" } diff --git a/src/parse.rs b/src/parse.rs index 54a172a..8c3a84b 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,6 +1,6 @@ use std::fmt::{self, Display, Formatter}; -use chainchomp::ctx_free::many_delimited; +use chainchomp::many_delimited; use crate::lex::Token; @@ -12,7 +12,7 @@ pub enum ParseError { } pub fn parse<'text>(tokens: &[Token<'text>]) -> Result, ParseError> { - let (expr, pos) = parse_expr(&tokens, 0)?; + let (expr, pos) = parse_expr(&tokens, 0, &mut ())?; match pos < tokens.len() { true => Err(ParseError::IncompleteParse(pos).into()), false => Ok(expr), @@ -24,8 +24,9 @@ pub type Expr<'text> = AssignmentExpr<'text>; fn parse_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(Expr<'text>, usize), ParseError> { - parse_assignment_expr(tokens, pos) + parse_assignment_expr(tokens, pos, ctx) } #[derive(Debug, PartialEq, Clone)] @@ -42,42 +43,43 @@ pub enum AssignmentExpr<'text> { fn parse_assignment_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(AssignmentExpr<'text>, usize), ParseError> { if let Some(Token::Ident(ident)) = tokens.get(pos) { if let Some(op) = tokens.get(pos + 1) { if op == &Token::Symbol("=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::Assign(ident, Box::new(rhs)), pos)); } if op == &Token::Symbol("*=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::MulAssign(ident, Box::new(rhs)), pos)); } if op == &Token::Symbol("/=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::DivAssign(ident, Box::new(rhs)), pos)); } if op == &Token::Symbol("%=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::ModAssign(ident, Box::new(rhs)), pos)); } if op == &Token::Symbol("+=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::AddAssign(ident, Box::new(rhs)), pos)); } if op == &Token::Symbol("-=") { - let (rhs, pos) = parse_assignment_expr(tokens, pos + 2)?; + let (rhs, pos) = parse_assignment_expr(tokens, pos + 2, ctx)?; return Ok((AssignmentExpr::SubAssign(ident, Box::new(rhs)), pos)); } } } - let (expr, pos) = parse_additive_expr(tokens, pos)?; + let (expr, pos) = parse_additive_expr(tokens, pos, ctx)?; Ok((expr.into(), pos)) } @@ -91,18 +93,19 @@ pub enum AdditiveExpr<'text> { fn parse_additive_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(AdditiveExpr<'text>, usize), ParseError> { - let (lhs, mut pos) = parse_multiplicative_expr(tokens, pos)?; + let (lhs, mut pos) = parse_multiplicative_expr(tokens, pos, ctx)?; let mut lhs = lhs.into(); while let Some(token) = tokens.get(pos) { match token { Token::Symbol("+") => { - let (rhs, next_pos) = parse_multiplicative_expr(tokens, pos + 1)?; + let (rhs, next_pos) = parse_multiplicative_expr(tokens, pos + 1, ctx)?; pos = next_pos; lhs = AdditiveExpr::Add(Box::new(lhs), rhs); } Token::Symbol("-") => { - let (rhs, next_pos) = parse_multiplicative_expr(tokens, pos + 1)?; + let (rhs, next_pos) = parse_multiplicative_expr(tokens, pos + 1, ctx)?; pos = next_pos; lhs = AdditiveExpr::Sub(Box::new(lhs), rhs); } @@ -123,23 +126,24 @@ pub enum MultiplicativeExpr<'text> { fn parse_multiplicative_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(MultiplicativeExpr<'text>, usize), ParseError> { - let (lhs, mut pos) = parse_exponential_expr(tokens, pos)?; + let (lhs, mut pos) = parse_exponential_expr(tokens, pos, ctx)?; let mut lhs = lhs.into(); while let Some(token) = tokens.get(pos) { match token { Token::Symbol("*") => { - let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1)?; + let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1, ctx)?; pos = next_pos; lhs = MultiplicativeExpr::Mul(Box::new(lhs), rhs); } Token::Symbol("/") => { - let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1)?; + let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1, ctx)?; pos = next_pos; lhs = MultiplicativeExpr::Div(Box::new(lhs), rhs); } Token::Symbol("%") => { - let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1)?; + let (rhs, next_pos) = parse_exponential_expr(tokens, pos + 1, ctx)?; pos = next_pos; lhs = MultiplicativeExpr::Mod(Box::new(lhs), rhs); } @@ -158,11 +162,12 @@ pub enum ExponentialExpr<'ident> { fn parse_exponential_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(ExponentialExpr<'text>, usize), ParseError> { - let (lhs, pos) = parse_unary_expr(tokens, pos)?; + let (lhs, pos) = parse_unary_expr(tokens, pos, ctx)?; if let Some(token) = tokens.get(pos) { if token == &Token::Symbol("^") { - let (rhs, pos) = parse_exponential_expr(tokens, pos + 1)?; + let (rhs, pos) = parse_exponential_expr(tokens, pos + 1, ctx)?; return Ok((ExponentialExpr::Pow(lhs, Box::new(rhs)), pos)); } } @@ -179,18 +184,19 @@ pub enum UnaryExpr<'text> { fn parse_unary_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(UnaryExpr<'text>, usize), ParseError> { match tokens.get(pos) { Some(Token::Symbol("+")) => { - let (expr, pos) = parse_unary_expr(tokens, pos + 1)?; + let (expr, pos) = parse_unary_expr(tokens, pos + 1, ctx)?; Ok((UnaryExpr::UnaryAdd(Box::new(expr)), pos)) } Some(Token::Symbol("-")) => { - let (expr, pos) = parse_unary_expr(tokens, pos + 1)?; + let (expr, pos) = parse_unary_expr(tokens, pos + 1, ctx)?; Ok((UnaryExpr::UnarySub(Box::new(expr)), pos)) } _ => { - let (expr, pos) = parse_postfix_expr(tokens, pos)?; + let (expr, pos) = parse_postfix_expr(tokens, pos, ctx)?; Ok((expr.into(), pos)) } } @@ -205,11 +211,17 @@ pub enum PostfixExpr<'text> { fn parse_postfix_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(PostfixExpr<'text>, usize), ParseError> { if let Some(Token::Ident(name)) = tokens.get(pos) { if let Some(Token::Symbol("(")) = tokens.get(pos + 1) { - let (args, pos) = - many_delimited(tokens, pos + 2, parse_assignment_expr, &Token::Symbol(",")); + let (args, pos) = many_delimited( + tokens, + pos + 2, + ctx, + parse_assignment_expr, + &Token::Symbol(","), + ); let Some(Token::Symbol(")")) = tokens.get(pos) else { return Err(ParseError::Expected(Token::Symbol(")"), pos)); @@ -219,7 +231,7 @@ fn parse_postfix_expr<'text>( } } - let (expr, pos) = parse_primary_expr(tokens, pos)?; + let (expr, pos) = parse_primary_expr(tokens, pos, ctx)?; Ok((expr.into(), pos)) } @@ -233,12 +245,13 @@ pub enum Primary<'text> { fn parse_primary_expr<'text>( tokens: &[Token<'text>], pos: usize, + ctx: &mut (), ) -> Result<(Primary<'text>, usize), ParseError> { match tokens.get(pos) { Some(Token::Ident(ident)) => Ok((Primary::Ident(ident), pos + 1)), Some(Token::Decimal(n)) => Ok((Primary::Float(*n), pos + 1)), Some(Token::Symbol("(")) => { - let (expr, pos) = parse_expr(tokens, pos + 1, )?; + let (expr, pos) = parse_expr(tokens, pos + 1, ctx)?; match tokens.get(pos) { Some(Token::Symbol(")")) => Ok((Primary::Parens(Box::new(expr)), pos + 1)), _ => Err(ParseError::Expected(Token::Symbol(")"), pos)), @@ -399,7 +412,7 @@ mod tests { macro_rules! check { ($f:ident, $src:expr, $expected:expr) => { let tokens = lex($src).expect("** LEX ERROR"); - let (stmt, pos) = $f(&tokens, 0).expect("** Unable to parse statement"); + let (stmt, pos) = $f(&tokens, 0, &mut ()).expect("** Unable to parse statement"); assert_eq!(pos, tokens.len(), "** Unable to parse all Tokens\n{}", stmt); let stmt = format!("{}", stmt); assert_eq!($expected, stmt);