Remove Expr::get_constant_str and change Expr::get_constant_value not to panic.
This commit is contained in:
parent
8809d25d3c
commit
ae1157a140
@ -1454,8 +1454,9 @@ impl Engine {
|
|||||||
Some((result, rhs_expr.position()))
|
Some((result, rhs_expr.position()))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Must be either `var[index] op= val` or `var.prop op= val`
|
||||||
match lhs_expr {
|
match lhs_expr {
|
||||||
// name op= rhs
|
// name op= rhs (handled above)
|
||||||
Expr::Variable(_) => unreachable!(),
|
Expr::Variable(_) => unreachable!(),
|
||||||
// idx_lhs[idx_expr] op= rhs
|
// idx_lhs[idx_expr] op= rhs
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -1473,12 +1474,8 @@ impl Engine {
|
|||||||
)?;
|
)?;
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
// Error assignment to constant
|
// Constant expression (should be caught during parsing)
|
||||||
expr if expr.is_constant() => EvalAltResult::ErrorAssignmentToConstant(
|
expr if expr.is_constant() => unreachable!(),
|
||||||
expr.get_constant_str(),
|
|
||||||
expr.position(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
// Syntax error
|
// Syntax error
|
||||||
expr => EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(),
|
expr => EvalAltResult::ErrorAssignmentToUnknownLHS(expr.position()).into(),
|
||||||
}
|
}
|
||||||
|
@ -585,7 +585,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
=> {
|
=> {
|
||||||
let ((name, _, _, pos), _, _, args, _) = x.as_mut();
|
let ((name, _, _, pos), _, _, args, _) = x.as_mut();
|
||||||
|
|
||||||
let arg_values: StaticVec<_> = args.iter().map(Expr::get_constant_value).collect();
|
let arg_values: StaticVec<_> = args.iter().map(|e| e.get_constant_value().unwrap()).collect();
|
||||||
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
||||||
|
|
||||||
// Search for overloaded operators (can override built-in).
|
// Search for overloaded operators (can override built-in).
|
||||||
@ -618,7 +618,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
let has_script_fn = false;
|
let has_script_fn = false;
|
||||||
|
|
||||||
if !has_script_fn {
|
if !has_script_fn {
|
||||||
let mut arg_values: StaticVec<_> = args.iter().map(Expr::get_constant_value).collect();
|
let mut arg_values: StaticVec<_> = args.iter().map(|e| e.get_constant_value().unwrap()).collect();
|
||||||
|
|
||||||
// Save the typename of the first argument if it is `type_of()`
|
// Save the typename of the first argument if it is `type_of()`
|
||||||
// This is to avoid `call_args` being passed into the closure
|
// This is to avoid `call_args` being passed into the closure
|
||||||
|
@ -12,13 +12,17 @@ use crate::syntax::FnCustomSyntaxEval;
|
|||||||
use crate::token::{is_keyword_function, is_valid_identifier, Position, Token, TokenStream};
|
use crate::token::{is_keyword_function, is_valid_identifier, Position, Token, TokenStream};
|
||||||
use crate::utils::{StaticVec, StraightHasherBuilder};
|
use crate::utils::{StaticVec, StraightHasherBuilder};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
use crate::engine::Array;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::engine::{make_getter, make_setter, Map};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::engine::{FN_ANONYMOUS, KEYWORD_FN_PTR_CURRY};
|
use crate::engine::{FN_ANONYMOUS, KEYWORD_FN_PTR_CURRY};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
use crate::engine::{make_getter, make_setter};
|
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
|
any::TypeId,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
char,
|
char,
|
||||||
@ -847,14 +851,40 @@ impl Default for Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
|
/// Get the type of an expression.
|
||||||
|
///
|
||||||
|
/// Returns `None` if the expression's result type is not constant.
|
||||||
|
pub fn get_type_id(&self) -> Option<TypeId> {
|
||||||
|
Some(match self {
|
||||||
|
Self::Expr(x) => return x.get_type_id(),
|
||||||
|
|
||||||
|
Self::IntegerConstant(_) => TypeId::of::<INT>(),
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
Self::FloatConstant(_) => TypeId::of::<FLOAT>(),
|
||||||
|
Self::CharConstant(_) => TypeId::of::<char>(),
|
||||||
|
Self::StringConstant(_) => TypeId::of::<ImmutableString>(),
|
||||||
|
Self::FnPointer(_) => TypeId::of::<FnPtr>(),
|
||||||
|
Self::True(_) | Self::False(_) | Self::In(_) | Self::And(_) | Self::Or(_) => {
|
||||||
|
TypeId::of::<bool>()
|
||||||
|
}
|
||||||
|
Self::Unit(_) => TypeId::of::<()>(),
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
Self::Array(_) => TypeId::of::<Array>(),
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
Self::Map(_) => TypeId::of::<Map>(),
|
||||||
|
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the `Dynamic` value of a constant expression.
|
/// Get the `Dynamic` value of a constant expression.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// Returns `None` if the expression is not constant.
|
||||||
///
|
pub fn get_constant_value(&self) -> Option<Dynamic> {
|
||||||
/// Panics when the expression is not constant.
|
Some(match self {
|
||||||
pub fn get_constant_value(&self) -> Dynamic {
|
Self::Expr(x) => return x.get_constant_value(),
|
||||||
match self {
|
|
||||||
Self::Expr(x) => x.get_constant_value(),
|
|
||||||
|
|
||||||
Self::IntegerConstant(x) => x.0.into(),
|
Self::IntegerConstant(x) => x.0.into(),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -871,45 +901,22 @@ impl Expr {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::Array(x) if x.0.iter().all(Self::is_constant) => Dynamic(Union::Array(Box::new(
|
Self::Array(x) if x.0.iter().all(Self::is_constant) => Dynamic(Union::Array(Box::new(
|
||||||
x.0.iter().map(Self::get_constant_value).collect::<Vec<_>>(),
|
x.0.iter()
|
||||||
|
.map(|v| v.get_constant_value().unwrap())
|
||||||
|
.collect(),
|
||||||
))),
|
))),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Self::Map(x) if x.0.iter().all(|(_, v)| v.is_constant()) => {
|
Self::Map(x) if x.0.iter().all(|(_, v)| v.is_constant()) => {
|
||||||
Dynamic(Union::Map(Box::new(
|
Dynamic(Union::Map(Box::new(
|
||||||
x.0.iter()
|
x.0.iter()
|
||||||
.map(|((k, _), v)| (k.clone(), v.get_constant_value()))
|
.map(|((k, _), v)| (k.clone(), v.get_constant_value().unwrap()))
|
||||||
.collect::<HashMap<_, _>>(),
|
.collect(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => unreachable!("cannot get value of non-constant expression"),
|
_ => return None,
|
||||||
}
|
})
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the display value of a constant expression.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics when the expression is not constant.
|
|
||||||
pub fn get_constant_str(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Self::Expr(x) => x.get_constant_str(),
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
Self::FloatConstant(x) => x.0.to_string(),
|
|
||||||
|
|
||||||
Self::IntegerConstant(x) => x.0.to_string(),
|
|
||||||
Self::CharConstant(x) => x.0.to_string(),
|
|
||||||
Self::StringConstant(_) => "string".to_string(),
|
|
||||||
Self::True(_) => "true".to_string(),
|
|
||||||
Self::False(_) => "false".to_string(),
|
|
||||||
Self::Unit(_) => "()".to_string(),
|
|
||||||
|
|
||||||
Self::Array(x) if x.0.iter().all(Self::is_constant) => "array".to_string(),
|
|
||||||
|
|
||||||
_ => unreachable!("cannot get value of non-constant expression"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `Position` of the expression.
|
/// Get the `Position` of the expression.
|
||||||
|
Loading…
Reference in New Issue
Block a user