diff --git a/src/eval.rs b/src/eval.rs index 6b02c0e25..edc2bd9ba 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -16,6 +16,7 @@ pub enum ShellError { pub enum Value { Bool { val: bool, span: Span }, Int { val: i64, span: Span }, + Float { val: f64, span: Span }, String { val: String, span: Span }, List(Vec), Block(BlockId), @@ -27,6 +28,7 @@ impl PartialEq for Value { match (self, other) { (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => lhs == rhs, (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => lhs == rhs, + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => lhs == rhs, (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => lhs == rhs, (Value::List(l1), Value::List(l2)) => l1 == l2, (Value::Block(b1), Value::Block(b2)) => b1 == b2, @@ -44,6 +46,9 @@ impl Display for Value { Value::Int { val, .. } => { write!(f, "{}", val) } + Value::Float { val, .. } => { + write!(f, "{}", val) + } Value::String { val, .. } => write!(f, "{}", val), Value::List(..) => write!(f, ""), Value::Block(..) => write!(f, ""), @@ -59,6 +64,18 @@ impl Value { val: lhs + rhs, span: Span::unknown(), }), + (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { + val: *lhs as f64 + *rhs, + span: Span::unknown(), + }), + (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Float { + val: *lhs + *rhs as f64, + span: Span::unknown(), + }), + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { + val: lhs + rhs, + span: Span::unknown(), + }), (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::String { val: lhs.to_string() + rhs, span: Span::unknown(), @@ -287,6 +304,10 @@ pub fn eval_expression( val: *i, span: expr.span, }), + Expr::Float(f) => Ok(Value::Float { + val: *f, + span: expr.span, + }), Expr::Var(var_id) => stack .get_var(*var_id) .map_err(move |_| ShellError::VariableNotFound(expr.span)), diff --git a/src/flatten.rs b/src/flatten.rs index fcafd54b3..d62beb0a2 100644 --- a/src/flatten.rs +++ b/src/flatten.rs @@ -5,6 +5,7 @@ pub enum FlatShape { Garbage, Bool, Int, + Float, InternalCall, External, Literal, @@ -57,6 +58,9 @@ impl<'a> ParserWorkingSet<'a> { Expr::Int(_) => { vec![(expr.span, FlatShape::Int)] } + Expr::Float(_) => { + vec![(expr.span, FlatShape::Float)] + } Expr::Bool(_) => { vec![(expr.span, FlatShape::Bool)] } diff --git a/src/parser.rs b/src/parser.rs index 12a369d4e..a8598eef5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -162,6 +162,7 @@ impl Call { pub enum Expr { Bool(bool), Int(i64), + Float(f64), Var(VarId), Call(Box), ExternalCall(Vec, Vec>), @@ -905,9 +906,29 @@ impl<'a> ParserWorkingSet<'a> { } } + pub fn parse_float(&mut self, token: &str, span: Span) -> (Expression, Option) { + if let Ok(x) = token.parse::() { + ( + Expression { + expr: Expr::Float(x), + span, + ty: Type::Int, + }, + None, + ) + } else { + ( + garbage(span), + Some(ParseError::Mismatch("int".into(), span)), + ) + } + } + pub fn parse_number(&mut self, token: &str, span: Span) -> (Expression, Option) { if let (x, None) = self.parse_int(token, span) { (x, None) + } else if let (x, None) = self.parse_float(token, span) { + (x, None) } else { ( garbage(span), diff --git a/src/parser_state.rs b/src/parser_state.rs index 6ed8d98b2..c53c8f350 100644 --- a/src/parser_state.rs +++ b/src/parser_state.rs @@ -9,7 +9,7 @@ pub struct ParserState { vars: Vec, decls: Vec, blocks: Vec, - scope: Vec, + scope: Vec, // REMOVE } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/syntax_highlight.rs b/src/syntax_highlight.rs index 197f65ba6..616626b05 100644 --- a/src/syntax_highlight.rs +++ b/src/syntax_highlight.rs @@ -54,6 +54,9 @@ impl Highlighter for NuHighlighter { FlatShape::Int => { output.push((Style::new().fg(nu_ansi_term::Color::Green), next_token)) } + FlatShape::Float => { + output.push((Style::new().fg(nu_ansi_term::Color::Green), next_token)) + } FlatShape::Bool => { output.push((Style::new().fg(nu_ansi_term::Color::LightCyan), next_token)) } diff --git a/src/tests.rs b/src/tests.rs index d620c46fb..e726beac0 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -128,3 +128,8 @@ fn def_with_no_dollar() -> TestResult { fn env_shorthand() -> TestResult { run_test("FOO=BAR if $false { 3 } else { 4 }", "4") } + +#[test] +fn floating_add() -> TestResult { + run_test("10.1 + 0.8", "10.9") +} diff --git a/src/type_check.rs b/src/type_check.rs index 524a58b95..e09f274e3 100644 --- a/src/type_check.rs +++ b/src/type_check.rs @@ -9,6 +9,7 @@ impl<'a> ParserWorkingSet<'a> { ) -> (Type, Option) { match &op.expr { Expr::Operator(operator) => match operator { + Operator::Equal => (Type::Bool, None), Operator::Multiply => match (&lhs.ty, &rhs.ty) { (Type::Int, Type::Int) => (Type::Int, None), (Type::Unknown, _) => (Type::Unknown, None),