Better implementation for Expression::get_literal_value.
This commit is contained in:
parent
b5898f451e
commit
03cb398edf
@ -1,13 +1,16 @@
|
|||||||
//! Module implementing custom syntax for [`Engine`].
|
//! Module implementing custom syntax for [`Engine`].
|
||||||
|
|
||||||
use crate::ast::Expr;
|
use crate::ast::Expr;
|
||||||
|
use crate::dynamic::Variant;
|
||||||
use crate::engine::EvalContext;
|
use crate::engine::EvalContext;
|
||||||
use crate::fn_native::SendSync;
|
use crate::fn_native::SendSync;
|
||||||
|
use crate::r#unsafe::unsafe_try_cast;
|
||||||
use crate::token::{is_valid_identifier, Token};
|
use crate::token::{is_valid_identifier, Token};
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult,
|
Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared,
|
||||||
Shared, StaticVec,
|
StaticVec, INT,
|
||||||
};
|
};
|
||||||
|
use std::any::TypeId;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
@ -67,10 +70,53 @@ impl Expression<'_> {
|
|||||||
self.0.position()
|
self.0.position()
|
||||||
}
|
}
|
||||||
/// Get the value of this expression if it is a literal constant.
|
/// Get the value of this expression if it is a literal constant.
|
||||||
|
/// Supports [`INT`][crate::INT], [`FLOAT`][crate::FLOAT], `()`, `char`, `bool` and
|
||||||
|
/// [`ImmutableString`][crate::ImmutableString].
|
||||||
|
///
|
||||||
|
/// Returns [`None`] also if the constant is not of the specified type.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_literal_value(&self) -> Option<Dynamic> {
|
pub fn get_literal_value<T: Variant>(&self) -> Option<T> {
|
||||||
self.0.get_literal_value()
|
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
||||||
|
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::IntegerConstant(x, _) => unsafe_try_cast(*x).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<crate::FLOAT>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::FloatConstant(x, _) => unsafe_try_cast(*x).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::CharConstant(x, _) => unsafe_try_cast(*x).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::StringConstant(x, _) => unsafe_try_cast(x.clone()).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::BoolConstant(x, _) => unsafe_try_cast(*x).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
|
return match self.0 {
|
||||||
|
Expr::Unit(_) => unsafe_try_cast(()).ok(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
true,
|
true,
|
||||||
|context, inputs| {
|
|context, inputs| {
|
||||||
let var_name = inputs[0].get_variable_name().unwrap().to_string();
|
let var_name = inputs[0].get_variable_name().unwrap().to_string();
|
||||||
let max = inputs[1].get_literal_value().unwrap().as_int().unwrap();
|
let max = inputs[1].get_literal_value::<INT>().unwrap();
|
||||||
let stmt = inputs.get(2).unwrap();
|
let stmt = inputs.get(2).unwrap();
|
||||||
let condition = inputs.get(3).unwrap();
|
let condition = inputs.get(3).unwrap();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user