adana_script_core/
lib.rs

1pub mod primitive;
2use std::collections::BTreeMap;
3
4use constants::{
5    BREAK, CAPITALIZE, CEIL, DROP, ELSE, EULER_NUMBER, FALSE, FLOOR, FOR, IF,
6    IN, IS_ARRAY, IS_BOOL, IS_DOUBLE, IS_ERROR, IS_FUNCTION, IS_I8, IS_INT,
7    IS_MATCH, IS_STRUCT, IS_U8, JSONIFY, MAKE_ERROR, MATCH, MULTILINE, NULL,
8    PARSE_JSON, PI, REPLACE, REPLACE_ALL, REQUIRE, RETURN, ROUND, STRUCT, TAU,
9    TO_BINARY, TO_HEX, TO_LOWER, TO_UPPER, TRUE, WHILE,
10};
11pub use primitive::Primitive;
12
13use serde::{Deserialize, Serialize};
14use strum::EnumCount;
15
16use self::constants::TO_STRING;
17use self::constants::{
18    ABS, COS, EVAL, INCLUDE, LENGTH, LN, LOG, PRINT, PRINT_LN, SIN, SQRT, TAN,
19    TO_BOOL, TO_DOUBLE, TO_INT, TYPE_OF,
20};
21
22#[macro_use]
23pub mod constants {
24    macro_rules! pi {
25        () => {
26            'π'
27        };
28    }
29    macro_rules! euler_number {
30        () => {
31            'γ'
32        };
33    }
34    macro_rules! tau {
35        () => {
36            'τ'
37        };
38    }
39    pub const TRUE: &str = "true";
40    pub const FALSE: &str = "false";
41    pub const IF: &str = "if";
42    pub const ELSE: &str = "else";
43    pub const WHILE: &str = "while";
44    pub const TAU: &str = concat!(tau!());
45    pub const PI: &str = concat!(pi!());
46    pub const EULER_NUMBER: &str = concat!(euler_number!());
47    pub const SQRT: &str = "sqrt";
48    pub const TO_HEX: &str = "to_hex";
49    pub const TO_BINARY: &str = "to_binary";
50    pub const TO_INT: &str = "to_int";
51    pub const TO_BOOL: &str = "to_bool";
52    pub const TO_UPPER: &str = "to_upper";
53    pub const TO_LOWER: &str = "to_lower";
54    pub const CAPITALIZE: &str = "capitalize";
55    pub const REPLACE: &str = "replace";
56    pub const REPLACE_ALL: &str = "replace_all";
57    pub const FLOOR: &str = "floor";
58    pub const CEIL: &str = "ceil";
59    pub const ROUND: &str = "round";
60    pub const TO_DOUBLE: &str = "to_double";
61    pub const TO_STRING: &str = "to_string";
62    pub const IS_ERROR: &str = "is_error";
63    pub const IS_U8: &str = "is_u8";
64    pub const IS_I8: &str = "is_i8";
65    pub const IS_INT: &str = "is_int";
66    pub const IS_DOUBLE: &str = "is_double";
67    pub const IS_BOOL: &str = "is_bool";
68    pub const IS_FUNCTION: &str = "is_function";
69    pub const IS_ARRAY: &str = "is_array";
70    pub const IS_STRUCT: &str = "is_struct";
71    pub const JSONIFY: &str = "jsonify";
72    pub const PARSE_JSON: &str = "parse_json";
73    pub const MAKE_ERROR: &str = "make_err";
74    pub const ABS: &str = "abs";
75    pub const LENGTH: &str = "length";
76    pub const LOG: &str = "log";
77    pub const LN: &str = "ln";
78    pub const SIN: &str = "sin";
79    pub const COS: &str = "cos";
80    pub const TAN: &str = "tan";
81    pub const BREAK: &str = "break";
82    pub const RETURN: &str = "return";
83    pub const PRINT_LN: &str = "println";
84    pub const PRINT: &str = "print";
85    pub const INCLUDE: &str = "include";
86    pub const DROP: &str = "drop";
87    pub const NULL: &str = "null";
88    pub const MULTILINE: &str = "multiline";
89    pub const STRUCT: &str = "struct";
90    pub const EVAL: &str = "eval";
91    pub const TYPE_OF: &str = "type_of";
92    pub const IS_MATCH: &str = "is_match";
93    pub const MATCH: &str = "match";
94    pub const FOR: &str = "for";
95    pub const IN: &str = "in";
96    pub const REQUIRE: &str = "require";
97    pub const NATIVE_LIB: &[u8; 14] = b"__native_lib__";
98}
99
100#[derive(Debug, EnumCount)]
101pub enum MathConstants {
102    Pi,
103    EulerNumber,
104    Tau,
105}
106
107impl MathConstants {
108    pub const fn get_symbol(&self) -> char {
109        match self {
110            MathConstants::Pi => pi!(),
111            MathConstants::EulerNumber => euler_number!(),
112            MathConstants::Tau => tau!(),
113        }
114    }
115    pub const fn get_symbols() -> &'static str {
116        concat!(pi!(), euler_number!(), tau!())
117    }
118
119    pub const fn _get_variants()
120    -> &'static [&'static MathConstants; MathConstants::COUNT] {
121        &[&MathConstants::Pi, &MathConstants::EulerNumber, &MathConstants::Tau]
122    }
123}
124
125impl Value {
126    pub fn is_divisible_or_multipliable(&self) -> bool {
127        matches!(
128            self,
129            Value::Primitive(_)
130                | Value::U8(_)
131                | Value::I8(_)
132                | Value::Integer(_)
133                | Value::Decimal(_)
134                | Value::Const(_)
135                | Value::Array(_)
136                | Value::MultiDepthAccess { .. }
137                | Value::Variable(_)
138                | Value::VariableNegate(_)
139                | Value::VariableRef(_)
140        )
141    }
142}
143#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
144pub enum Value {
145    Break,
146    Primitive(Primitive),
147    EarlyReturn(Box<Option<Value>>),
148    Drop(Box<Value>),
149    Expression(Vec<Value>),
150    ImplicitMultiply(Box<Value>),
151    Operation(Operator),
152    BuiltInFunction {
153        fn_type: BuiltInFunctionType,
154        expr: Box<Value>,
155    },
156    Function {
157        parameters: Box<Value>,
158        exprs: Vec<Value>,
159    },
160    FunctionCall {
161        parameters: Box<Value>,
162        function: Box<Value>,
163    },
164    Null,
165    Decimal(f64),
166    U8(u8),
167    I8(i8),
168    Integer(i128),
169    Bool(bool),
170    Range {
171        start: Box<Value>,
172        incl_both_end: bool,
173        end: Box<Value>,
174    },
175    NoOp,
176    String(String),
177    FString(String, Vec<(String, Value)>),
178    BlockParen(Vec<Value>),
179    Variable(String),
180    VariableRef(String),
181    VariableUnused,
182    Const(char),
183    VariableNegate(String),
184    VariableExpr {
185        name: Box<Value>,
186        expr: Box<Value>,
187    },
188    IfExpr {
189        cond: Box<Value>,
190        exprs: Vec<Value>,
191        else_expr: Option<Vec<Value>>,
192    },
193    WhileExpr {
194        cond: Box<Value>,
195        exprs: Vec<Value>,
196    },
197    ForeachExpr {
198        var: String,
199        index_var: Option<String>,
200        iterator: Box<Value>,
201        exprs: Vec<Value>,
202    },
203    Array(Vec<Value>),
204    Struct(BTreeMap<String, Value>),
205
206    MultiDepthAccess {
207        root: Box<Value>,
208        next_keys: Vec<KeyAccess>,
209    },
210}
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub enum KeyAccess {
213    Index(Primitive),
214    Key(Primitive),
215    Variable(Value),
216    FunctionCall { key: Box<KeyAccess>, parameters: Value },
217}
218#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
219pub enum BuiltInFunctionType {
220    Sqrt,
221    Abs,
222    Log,
223    Ln,
224    Sin,
225    Cos,
226    ToInt,
227    ToBinary,
228    ToHex,
229    ToDouble,
230    ToBool,
231    ToUpper,
232    ToLower,
233    Capitalize,
234    Replace,
235    ReplaceAll,
236    Floor,
237    Round,
238    Ceil,
239    ToString,
240    Tan,
241    Println,
242    Print,
243    Eval,
244    TypeOf,
245    Match,
246    IsMatch,
247    Length,
248    Include,
249    Require,
250    IsError,
251    IsU8,
252    IsI8,
253    IsStruct,
254    IsBool,
255    IsInt,
256    MakeError,
257    IsDouble,
258    IsFunction,
259    IsArray,
260    ParseJson,
261    Jsonify,
262}
263
264#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
265pub enum Operator {
266    Add,
267    Subtr,
268    Mult,
269    Div,
270    Mod,
271    Pow,
272    Pow2,
273    Pow3,
274    Not,
275    Less,
276    Greater,
277    LessOrEqual,
278    GreaterOrEqual,
279    Equal,
280    NotEqual,
281    And,
282    Or,
283    BitwiseNot,
284    BitwiseAnd,
285    BitwiseOr,
286    BitwiseXor,
287    BitwiseLShift,
288    BitwiseRShift,
289}
290
291#[derive(Debug)]
292pub enum TreeNodeValue {
293    Break,
294    EarlyReturn(Option<Value>),
295    Drop(Vec<Value>),
296    VariableUnused,
297    VariableAssign(Option<String>),
298    MultiDepthVariableAssign { root: Value, next_keys: Vec<KeyAccess> },
299    Ops(Operator),
300    Primitive(Primitive),
301    VariableRef(String),
302    BuiltInFunction { fn_type: BuiltInFunctionType, params: Value },
303    IfExpr(Value),
304    FString(String, Vec<(String, Value)>),
305    WhileExpr(Value),
306    Array(Vec<Value>),
307    Struct(BTreeMap<String, Value>),
308    MultiDepthAccess { root: Value, keys: Vec<KeyAccess> },
309    Function(Value),
310    FunctionCall(Value),
311    Foreach(Value),
312    Null,
313}
314
315impl BuiltInFunctionType {
316    pub fn as_str(&self) -> &'static str {
317        match self {
318            BuiltInFunctionType::Sqrt => SQRT,
319            BuiltInFunctionType::Abs => ABS,
320            BuiltInFunctionType::Log => LOG,
321            BuiltInFunctionType::Ln => LN,
322            BuiltInFunctionType::Length => LENGTH,
323            BuiltInFunctionType::Sin => SIN,
324            BuiltInFunctionType::Cos => COS,
325            BuiltInFunctionType::Tan => TAN,
326            BuiltInFunctionType::TypeOf => TYPE_OF,
327            BuiltInFunctionType::IsMatch => IS_MATCH,
328            BuiltInFunctionType::Match => MATCH,
329            BuiltInFunctionType::Println => PRINT_LN,
330            BuiltInFunctionType::Print => PRINT,
331            BuiltInFunctionType::Eval => EVAL,
332            BuiltInFunctionType::Include => INCLUDE,
333            BuiltInFunctionType::Require => REQUIRE,
334            BuiltInFunctionType::ToInt => TO_INT,
335            BuiltInFunctionType::ToHex => TO_HEX,
336            BuiltInFunctionType::ToBinary => TO_BINARY,
337            BuiltInFunctionType::ToDouble => TO_DOUBLE,
338            BuiltInFunctionType::ToBool => TO_BOOL,
339            BuiltInFunctionType::ToUpper => TO_UPPER,
340            BuiltInFunctionType::ToLower => TO_LOWER,
341            BuiltInFunctionType::Capitalize => CAPITALIZE,
342            BuiltInFunctionType::Replace => REPLACE,
343            BuiltInFunctionType::ReplaceAll => REPLACE_ALL,
344            BuiltInFunctionType::Floor => FLOOR,
345            BuiltInFunctionType::Ceil => CEIL,
346            BuiltInFunctionType::Round => ROUND,
347            BuiltInFunctionType::ToString => TO_STRING,
348            BuiltInFunctionType::IsError => IS_ERROR,
349            BuiltInFunctionType::IsU8 => IS_U8,
350            BuiltInFunctionType::IsI8 => IS_I8,
351            BuiltInFunctionType::IsStruct => IS_STRUCT,
352            BuiltInFunctionType::IsBool => IS_BOOL,
353            BuiltInFunctionType::IsInt => IS_INT,
354            BuiltInFunctionType::IsDouble => IS_DOUBLE,
355            BuiltInFunctionType::IsFunction => IS_FUNCTION,
356            BuiltInFunctionType::IsArray => IS_ARRAY,
357            BuiltInFunctionType::MakeError => MAKE_ERROR,
358            BuiltInFunctionType::Jsonify => JSONIFY,
359            BuiltInFunctionType::ParseJson => PARSE_JSON,
360        }
361    }
362}
363impl Operator {
364    pub const fn as_str(&self) -> &'static str {
365        match self {
366            Operator::Add => "+",
367            Operator::Subtr => "-",
368            Operator::Div => "/",
369            Operator::Mult => "*",
370            Operator::Pow => "^",
371            Operator::Pow2 => "²",
372            Operator::Pow3 => "³",
373            Operator::Not => "!",
374            Operator::Mod => "%",
375            Operator::Less => "<",
376            Operator::Greater => ">",
377            Operator::LessOrEqual => "<=",
378            Operator::GreaterOrEqual => ">=",
379            Operator::Equal => "==",
380            Operator::NotEqual => "!=",
381            Operator::And => "&&",
382            Operator::Or => "||",
383            Operator::BitwiseNot => "~",
384            Operator::BitwiseAnd => "@",
385            Operator::BitwiseOr => "|",
386            Operator::BitwiseXor => "$",
387            Operator::BitwiseLShift => "<<",
388            Operator::BitwiseRShift => ">>",
389        }
390    }
391}
392
393pub const FORBIDDEN_VARIABLE_NAME: &[&str] = &[
394    TRUE,
395    FALSE,
396    TAU,
397    IF,
398    PI,
399    PRINT_LN,
400    PRINT,
401    LENGTH,
402    EULER_NUMBER,
403    ABS,
404    LOG,
405    TO_INT,
406    TO_DOUBLE,
407    TO_HEX,
408    CEIL,
409    ROUND,
410    FLOOR,
411    TO_UPPER,
412    TO_LOWER,
413    REPLACE,
414    REPLACE_ALL,
415    CAPITALIZE,
416    IS_MATCH,
417    MATCH,
418    TO_BINARY,
419    TO_STRING,
420    IS_FUNCTION,
421    IS_DOUBLE,
422    IS_INT,
423    IS_STRUCT,
424    IS_U8,
425    IS_ERROR,
426    IS_I8,
427    IS_BOOL,
428    IS_ARRAY,
429    MAKE_ERROR,
430    JSONIFY,
431    PARSE_JSON,
432    EVAL,
433    TO_BOOL,
434    SQRT,
435    BREAK,
436    NULL,
437    FOR,
438    IN,
439    DROP,
440    //READ_LINES,
441    RETURN,
442    LN,
443    SIN,
444    COS,
445    TYPE_OF,
446    TAN,
447    INCLUDE,
448    WHILE,
449    ELSE,
450    REQUIRE,
451    MULTILINE,
452    STRUCT,
453    Operator::Add.as_str(),
454    Operator::Subtr.as_str(),
455    Operator::Div.as_str(),
456    Operator::Mult.as_str(),
457    Operator::Pow.as_str(),
458    Operator::Pow2.as_str(),
459    Operator::Pow3.as_str(),
460    Operator::Not.as_str(),
461    Operator::Mod.as_str(),
462    Operator::Less.as_str(),
463    Operator::Greater.as_str(),
464    Operator::LessOrEqual.as_str(),
465    Operator::GreaterOrEqual.as_str(),
466    Operator::Equal.as_str(),
467    Operator::NotEqual.as_str(),
468    Operator::And.as_str(),
469    Operator::Or.as_str(),
470    Operator::BitwiseNot.as_str(),
471    Operator::BitwiseAnd.as_str(),
472    Operator::BitwiseOr.as_str(),
473    Operator::BitwiseXor.as_str(),
474    Operator::BitwiseLShift.as_str(),
475    Operator::BitwiseRShift.as_str(),
476];