From 001123dbd61ac851108c76cc217c71ffdb04e1bf Mon Sep 17 00:00:00 2001 From: onthebridgetonowhere <71919805+onthebridgetonowhere@users.noreply.github.com> Date: Wed, 5 May 2021 23:00:55 +0200 Subject: [PATCH] Add first prototype of functionality to parse numbers in parantheses (#3209) * Add first prototype of functionality to parse numbers in parantheses (). Needs testing and more wide-testing+integration * Fix styling issue * Try something else by copying existing matching code * Fix formatting * Fix the parser to accept numbers in paranthesis. Not really happy with the code, but let's see * Refactor to only use once the parsing of strings into numbers * Remove errors that are not used * Fix formatting Co-authored-by: Stefan Stanciulescu --- crates/nu-parser/src/parse.rs | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index 5a364985fd..ab6949e69a 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -772,6 +772,65 @@ fn parse_table( ) } +/// Tries to parse a number in a paranthesis, e.g., (123) or (-123) +fn try_parse_number_in_paranthesis( + lite_arg: &Spanned, +) -> (SpannedExpression, Option) { + let mut chars = lite_arg.item.chars(); + + match (chars.next(), chars.next_back()) { + (Some('('), Some(')')) => { + match chars.as_str().trim().parse::() { + Ok(parsed_integer) => ( + SpannedExpression::new(Expression::integer(parsed_integer), lite_arg.span), + None, + ), + // we don't care if it does not manage to parse it, because then likely it is not a number + Err(_) => { + match chars.as_str().trim().parse::() { + Ok(parsed_decimal) => ( + SpannedExpression::new( + Expression::decimal(parsed_decimal), + lite_arg.span, + ), + None, + ), + // we don't care if it does not manage to parse it, because then likely it is not a number + Err(_) => ( + garbage(lite_arg.span), + Some(ParseError::mismatch( + "cannot parse number", + lite_arg.clone(), + )), + ), + } + } + } + } + (Some('('), _) => ( + garbage(lite_arg.span), + Some(ParseError::mismatch( + "missing closing bracket", + lite_arg.clone(), + )), + ), + (_, Some(')')) => ( + garbage(lite_arg.span), + Some(ParseError::mismatch( + "missing starting bracket", + lite_arg.clone(), + )), + ), + (_, _) => ( + garbage(lite_arg.span), + Some(ParseError::mismatch( + "number in paranthesis", + lite_arg.clone(), + )), + ), + } +} + /// Parses the given argument using the shape as a guide for how to correctly parse the argument fn parse_arg( expected_type: SyntaxShape, @@ -782,6 +841,14 @@ fn parse_arg( return parse_dollar_expr(&lite_arg, scope); } + // before anything else, try to see if this is a number in paranthesis + if lite_arg.item.starts_with('(') { + let (expr, err) = try_parse_number_in_paranthesis(lite_arg); + if err.is_none() { + return (expr, None); + } + } + match expected_type { SyntaxShape::Number => { if let Ok(x) = lite_arg.item.parse::() {