mirror of
https://github.com/gorules/zen.git
synced 2026-10-04 00:02:18 +00:00
feat: is numeric function; (#95)
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::ast::Node;
|
||||
use crate::compiler::CompilerError::{
|
||||
ArgumentNotFound, UnknownBinaryOperator, UnknownBuiltIn, UnknownUnaryOperator,
|
||||
};
|
||||
use crate::opcodes::{Opcode, TypeConversionKind, Variable};
|
||||
use crate::opcodes::{Opcode, TypeCheckKind, TypeConversionKind, Variable};
|
||||
|
||||
type Bytecode<'a> = Rc<UnsafeCell<Vec<&'a Opcode<'a>>>>;
|
||||
|
||||
@@ -399,6 +399,10 @@ impl<'a> Compiler<'a> {
|
||||
self.compile_argument(name, arguments, 0)?;
|
||||
Ok(self.emit(Opcode::TypeConversion(TypeConversionKind::Number)))
|
||||
}
|
||||
"isNumeric" => {
|
||||
self.compile_argument(name, arguments, 0)?;
|
||||
Ok(self.emit(Opcode::TypeCheck(TypeCheckKind::Numeric)))
|
||||
}
|
||||
"startOf" | "endOf" => {
|
||||
self.compile_argument(name, arguments, 0)?;
|
||||
self.compile_argument(name, arguments, 1)?;
|
||||
|
||||
@@ -143,6 +143,7 @@ pub enum Opcode<'a> {
|
||||
End,
|
||||
Flatten,
|
||||
TypeConversion(TypeConversionKind),
|
||||
TypeCheck(TypeCheckKind),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -151,6 +152,11 @@ pub enum TypeConversionKind {
|
||||
String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeCheckKind {
|
||||
Numeric,
|
||||
}
|
||||
|
||||
impl TryFrom<&Variable<'_>> for Value {
|
||||
type Error = ();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ pub(crate) static BUILT_INS: Lazy<HashMap<&'static str, BuiltIn, ADefHasher>> =
|
||||
|
||||
"string" => BuiltIn { arity: Arity::Single },
|
||||
"number" => BuiltIn { arity: Arity::Single },
|
||||
"isNumeric" => BuiltIn { arity: Arity::Single },
|
||||
|
||||
"abs" => BuiltIn { arity: Arity::Single },
|
||||
"sum" => BuiltIn { arity: Arity::Single },
|
||||
|
||||
@@ -10,6 +10,7 @@ pub(crate) const BUILT_INS: Map<&'static str, BuiltIn> = phf_map! {
|
||||
|
||||
"string" => BuiltIn { arity: Arity::Single },
|
||||
"number" => BuiltIn { arity: Arity::Single },
|
||||
"isNumeric" => BuiltIn { arity: Arity::Single },
|
||||
|
||||
"upper" => BuiltIn { arity: Arity::Single },
|
||||
"lower" => BuiltIn { arity: Arity::Single },
|
||||
|
||||
@@ -14,7 +14,7 @@ use thiserror::Error;
|
||||
|
||||
use crate::helpers::{date_time, date_time_end_of, date_time_start_of, time};
|
||||
use crate::opcodes::Variable::{Array, Bool, Null, Number, Object, String};
|
||||
use crate::opcodes::{IntervalObject, Opcode, TypeConversionKind, Variable};
|
||||
use crate::opcodes::{IntervalObject, Opcode, TypeCheckKind, TypeConversionKind, Variable};
|
||||
use crate::vm::VMError::{OpcodeErr, OpcodeOutOfBounds, ParseDateTimeErr, StackOutOfBounds};
|
||||
|
||||
const NULL_VAR: &'static Variable = &Null;
|
||||
@@ -1206,6 +1206,19 @@ impl<'a> VM<'a> {
|
||||
|
||||
self.stack.push(self.bump.alloc(Number(dur.into())));
|
||||
}
|
||||
Opcode::TypeCheck(check) => {
|
||||
let var = self.pop()?;
|
||||
|
||||
let is_equal = match (check, var) {
|
||||
(TypeCheckKind::Numeric, String(str)) => {
|
||||
Decimal::from_str_exact(str).is_ok()
|
||||
}
|
||||
(TypeCheckKind::Numeric, Number(_)) => true,
|
||||
(TypeCheckKind::Numeric, _) => false,
|
||||
};
|
||||
|
||||
self.push(Bool(is_equal));
|
||||
}
|
||||
Opcode::TypeConversion(conversion) => {
|
||||
let var = self.pop()?;
|
||||
|
||||
|
||||
@@ -234,4 +234,12 @@ number('123');;123
|
||||
number(123.123);;123.123
|
||||
number(123);;123
|
||||
number(true);;1
|
||||
number(false);;0
|
||||
number(false);;0
|
||||
|
||||
# Type check
|
||||
isNumeric(123.123);;true
|
||||
isNumeric(123);;true
|
||||
isNumeric('123.123');;true
|
||||
isNumeric('123');;true
|
||||
isNumeric('string');;false
|
||||
isNumeric(true);;false
|
||||
|
Can't render this file because it contains an unexpected character in line 14 and column 13.
|
Reference in New Issue
Block a user