diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index 5e729d6bcd..d85ae87331 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -830,6 +830,56 @@ fn parse_table( ) } +fn parse_int(lite_arg: &Spanned) -> (SpannedExpression, Option) { + if lite_arg.item.starts_with("0x") { + if let Ok(v) = i64::from_str_radix(&lite_arg.item[2..], 16) { + ( + SpannedExpression::new(Expression::integer(v), lite_arg.span), + None, + ) + } else { + ( + garbage(lite_arg.span), + Some(ParseError::mismatch("int", lite_arg.clone())), + ) + } + } else if lite_arg.item.starts_with("0b") { + if let Ok(v) = i64::from_str_radix(&lite_arg.item[2..], 2) { + ( + SpannedExpression::new(Expression::integer(v), lite_arg.span), + None, + ) + } else { + ( + garbage(lite_arg.span), + Some(ParseError::mismatch("int", lite_arg.clone())), + ) + } + } else if lite_arg.item.starts_with("0o") { + if let Ok(v) = i64::from_str_radix(&lite_arg.item[2..], 8) { + ( + SpannedExpression::new(Expression::integer(v), lite_arg.span), + None, + ) + } else { + ( + garbage(lite_arg.span), + Some(ParseError::mismatch("int", lite_arg.clone())), + ) + } + } else if let Ok(x) = lite_arg.item.parse::() { + ( + SpannedExpression::new(Expression::integer(x), lite_arg.span), + None, + ) + } else { + ( + garbage(lite_arg.span), + Some(ParseError::mismatch("int", 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, @@ -850,11 +900,8 @@ fn parse_arg( match expected_type { SyntaxShape::Number => { - if let Ok(x) = lite_arg.item.parse::() { - ( - SpannedExpression::new(Expression::integer(x), lite_arg.span), - None, - ) + if let (x, None) = parse_int(lite_arg) { + (x, None) } else if let Ok(x) = lite_arg.item.parse::() { ( SpannedExpression::new(Expression::big_integer(x), lite_arg.span), diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index ce370d9347..2ddda4b9df 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -529,6 +529,39 @@ fn block_params_override_correct() { assert_eq!(actual.out, "[1,2,3]"); } +#[test] +fn hex_number() { + let actual = nu!( + cwd: ".", + r#" + 0x10 + "# + ); + assert_eq!(actual.out, "16"); +} + +#[test] +fn binary_number() { + let actual = nu!( + cwd: ".", + r#" + 0b10 + "# + ); + assert_eq!(actual.out, "2"); +} + +#[test] +fn octal_number() { + let actual = nu!( + cwd: ".", + r#" + 0o10 + "# + ); + assert_eq!(actual.out, "8"); +} + #[test] fn run_dynamic_blocks() { let actual = nu!(