From 30e11f137b722976b92fdf7f509e7aa8f487c4e8 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 28 Oct 2020 10:26:36 +0800 Subject: [PATCH] Move ErrorAssignmentToUnknownLHS to ParseError. --- RELEASES.md | 1 + src/engine.rs | 27 ++++++++------------------- src/error.rs | 11 ++++++++--- src/parser.rs | 4 ++-- src/result.rs | 9 --------- 5 files changed, 19 insertions(+), 33 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 1c912a0b..ffdca9a9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -16,6 +16,7 @@ Breaking changes ---------------- * Custom syntax can no longer start with a keyword (even a _reserved_ one), even if it has been disabled. That is to avoid breaking scripts later when the keyword is no longer disabled. +* `EvalAltResult::ErrorAssignmentToUnknownLHS` is moved to `ParseError::AssignmentToInvalidLHS`. `ParseError::AssignmentToCopy` is removed. New features ------------ diff --git a/src/engine.rs b/src/engine.rs index 936f50a6..3563d22e 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -302,26 +302,19 @@ impl<'a> Target<'a> { #[cfg(not(feature = "no_index"))] Self::StringChar(_, _, ch) => { let char_value = ch.clone(); - self.set_value((char_value, Position::none()), Position::none()) - .unwrap(); + self.set_value((char_value, Position::none())).unwrap(); } } } /// Update the value of the `Target`. #[cfg(any(not(feature = "no_object"), not(feature = "no_index")))] - pub fn set_value( - &mut self, - new_val: (Dynamic, Position), - target_pos: Position, - ) -> Result<(), Box> { + pub fn set_value(&mut self, new_val: (Dynamic, Position)) -> Result<(), Box> { match self { Self::Ref(r) => **r = new_val.0, #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_object"))] Self::LockGuard((r, _)) => **r = new_val.0, - Self::Value(_) => { - return EvalAltResult::ErrorAssignmentToUnknownLHS(target_pos).into(); - } + Self::Value(_) => unreachable!(), #[cfg(not(feature = "no_index"))] Self::StringChar(string, index, _) if string.is::() => { let mut s = string.write_lock::().unwrap(); @@ -924,7 +917,7 @@ impl Engine { { // Indexed value is a reference - update directly Ok(ref mut obj_ptr) => { - obj_ptr.set_value(new_val.unwrap(), rhs.position())?; + obj_ptr.set_value(new_val.unwrap())?; None } Err(err) => match *err { @@ -992,7 +985,7 @@ impl Engine { let mut val = self .get_indexed_mut(state, lib, target, index, *pos, true, false, level)?; - val.set_value(new_val.unwrap(), rhs.position())?; + val.set_value(new_val.unwrap())?; Ok((Default::default(), true)) } // {xxx:map}.id @@ -1219,9 +1212,7 @@ impl Engine { .map_err(|err| err.fill_position(*op_pos)) } // {expr}.??? = ??? or {expr}[???] = ??? - expr if new_val.is_some() => { - return EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(); - } + _ if new_val.is_some() => unreachable!(), // {expr}.??? or {expr}[???] expr => { let val = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?; @@ -1803,10 +1794,8 @@ impl Engine { )?; Ok(Default::default()) } - // Constant expression (should be caught during parsing) - expr if expr.is_constant() => unreachable!(), - // Syntax error - expr => EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(), + // Non-lvalue expression (should be caught during parsing) + _ => unreachable!(), } } diff --git a/src/error.rs b/src/error.rs index 0d680b85..ca0f9d71 100644 --- a/src/error.rs +++ b/src/error.rs @@ -138,10 +138,11 @@ pub enum ParseErrorType { /// /// Never appears under the `no_module` feature. WrongExport, - /// Assignment to a copy of a value. - AssignmentToCopy, /// Assignment to an a constant variable. Wrapped value is the constant variable name. AssignmentToConstant(String), + /// Assignment to an inappropriate LHS (left-hand-side) expression. + /// Wrapped value is the error message (if any). + AssignmentToInvalidLHS(String), /// Expression exceeding the maximum levels of complexity. /// /// Never appears under the `unchecked` feature. @@ -183,8 +184,8 @@ impl ParseErrorType { Self::WrongFnDefinition => "Function definitions must be at global level and cannot be inside a block or another function", Self::DuplicatedExport(_) => "Duplicated variable/function in export statement", Self::WrongExport => "Export statement can only appear at global level", - Self::AssignmentToCopy => "Only a copy of the value is change with this assignment", Self::AssignmentToConstant(_) => "Cannot assign to a constant value", + Self::AssignmentToInvalidLHS(_) => "Expression cannot be assigned to", Self::ExprTooDeep => "Expression exceeds maximum complexity", Self::LiteralTooLarge(_, _) => "Literal exceeds maximum limit", Self::LoopBreak => "Break statement should only be used inside a loop" @@ -233,6 +234,10 @@ impl fmt::Display for ParseErrorType { Self::AssignmentToConstant(s) if s.is_empty() => f.write_str(self.desc()), Self::AssignmentToConstant(s) => write!(f, "Cannot assign to constant '{}'", s), + + Self::AssignmentToInvalidLHS(s) if s.is_empty() => f.write_str(self.desc()), + Self::AssignmentToInvalidLHS(s) => f.write_str(s), + Self::LiteralTooLarge(typ, max) => { write!(f, "{} exceeds the maximum limit ({})", typ, max) } diff --git a/src/parser.rs b/src/parser.rs index c5e90bf9..4329de2a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2280,7 +2280,7 @@ fn make_assignment_stmt<'a>( } } // expr[???] = rhs, expr.??? = rhs - _ => Err(PERR::AssignmentToCopy.into_err(x.lhs.position())), + _ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(x.lhs.position())), }, // const_expr = rhs expr if expr.is_constant() => { @@ -2291,7 +2291,7 @@ fn make_assignment_stmt<'a>( Err(PERR::BadInput("Possibly a typo of '=='?".to_string()).into_err(pos)) } // expr = rhs - _ => Err(PERR::AssignmentToCopy.into_err(lhs.position())), + _ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.position())), } } diff --git a/src/result.rs b/src/result.rs index 82e78fb6..fce42842 100644 --- a/src/result.rs +++ b/src/result.rs @@ -71,8 +71,6 @@ pub enum EvalAltResult { ErrorFor(Position), /// Data race detected when accessing a variable. Wrapped value is the variable name. ErrorDataRace(String, Position), - /// Assignment to an inappropriate LHS (left-hand-side) expression. - ErrorAssignmentToUnknownLHS(Position), /// Assignment to a constant variable. Wrapped value is the variable name. ErrorAssignmentToConstant(String, Position), /// Inappropriate property access. Wrapped value is the property name. @@ -129,9 +127,6 @@ impl EvalAltResult { Self::ErrorVariableNotFound(_, _) => "Variable not found", Self::ErrorModuleNotFound(_, _) => "Module not found", Self::ErrorDataRace(_, _) => "Data race detected when accessing variable", - Self::ErrorAssignmentToUnknownLHS(_) => { - "Assignment to an unsupported left-hand side expression" - } Self::ErrorAssignmentToConstant(_, _) => "Assignment to a constant variable", Self::ErrorMismatchOutputType(_, _, _) => "Output type is incorrect", Self::ErrorInExpr(_) => "Malformed 'in' expression", @@ -185,7 +180,6 @@ impl fmt::Display for EvalAltResult { Self::ErrorIndexingType(_, _) | Self::ErrorUnboundThis(_) | Self::ErrorFor(_) - | Self::ErrorAssignmentToUnknownLHS(_) | Self::ErrorInExpr(_) | Self::ErrorDotExpr(_, _) | Self::ErrorTooManyOperations(_) @@ -293,7 +287,6 @@ impl EvalAltResult { | Self::ErrorVariableNotFound(_, _) | Self::ErrorModuleNotFound(_, _) | Self::ErrorDataRace(_, _) - | Self::ErrorAssignmentToUnknownLHS(_) | Self::ErrorAssignmentToConstant(_, _) | Self::ErrorMismatchOutputType(_, _, _) | Self::ErrorInExpr(_) @@ -329,7 +322,6 @@ impl EvalAltResult { | Self::ErrorVariableNotFound(_, pos) | Self::ErrorModuleNotFound(_, pos) | Self::ErrorDataRace(_, pos) - | Self::ErrorAssignmentToUnknownLHS(pos) | Self::ErrorAssignmentToConstant(_, pos) | Self::ErrorMismatchOutputType(_, _, pos) | Self::ErrorInExpr(pos) @@ -364,7 +356,6 @@ impl EvalAltResult { | Self::ErrorVariableNotFound(_, pos) | Self::ErrorModuleNotFound(_, pos) | Self::ErrorDataRace(_, pos) - | Self::ErrorAssignmentToUnknownLHS(pos) | Self::ErrorAssignmentToConstant(_, pos) | Self::ErrorMismatchOutputType(_, _, pos) | Self::ErrorInExpr(pos)