Skip to main content

lumen_engine/expr/
ast.rs

1use crate::node::NodeId;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub struct ExpressionId(pub u64);
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct PropertyPath(pub String);
8
9impl PropertyPath {
10    pub fn new(path: impl Into<String>) -> Self {
11        Self(path.into())
12    }
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct VirtualPropertyId(pub u64);
17
18impl VirtualPropertyId {
19    pub const fn new(value: u64) -> Self {
20        Self(value)
21    }
22}
23
24#[derive(Debug, Clone, PartialEq)]
25pub enum ExpressionValue {
26    Number(f64),
27    Boolean(bool),
28    String(String),
29}
30
31impl ExpressionValue {
32    pub fn type_name(&self) -> &'static str {
33        match self {
34            Self::Number(_) => "number",
35            Self::Boolean(_) => "boolean",
36            Self::String(_) => "string",
37        }
38    }
39
40    pub fn as_f64(&self) -> Option<f64> {
41        match self {
42            Self::Number(n) => Some(*n),
43            Self::Boolean(b) => Some(if *b { 1.0 } else { 0.0 }),
44            Self::String(s) => s.parse().ok(),
45        }
46    }
47
48    pub fn as_bool(&self) -> bool {
49        match self {
50            Self::Boolean(b) => *b,
51            Self::Number(n) => n.abs() > f64::EPSILON,
52            Self::String(s) => !s.is_empty(),
53        }
54    }
55
56    pub fn as_string(&self) -> String {
57        match self {
58            Self::String(s) => s.clone(),
59            Self::Number(n) => n.to_string(),
60            Self::Boolean(b) => b.to_string(),
61        }
62    }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum BinaryOp {
67    Add,
68    Sub,
69    Mul,
70    Div,
71    Mod,
72    Gt,
73    Lt,
74    Gte,
75    Lte,
76    Eq,
77    Neq,
78    And,
79    Or,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub enum UnaryOp {
84    Neg,
85    Not,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Hash)]
89pub enum GlobalVar {
90    Frame,
91    Time,
92    Fps,
93    Width,
94    Height,
95    Custom(String),
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99pub enum BuiltinFn {
100    Min,
101    Max,
102    Abs,
103    Floor,
104    Ceil,
105    Round,
106    Sin,
107    Cos,
108    Clamp,
109    Lerp,
110    Pow,
111    Mod,
112    Fract,
113    Smoothstep,
114    Linear,
115    Step,
116    TextHeight,
117    TextWidth,
118    Uppercase,
119    Lowercase,
120}
121
122#[derive(Debug, Clone, PartialEq)]
123pub enum ExprNode {
124    Literal(ExpressionValue),
125    Binary(Box<ExprNode>, BinaryOp, Box<ExprNode>),
126    Unary(UnaryOp, Box<ExprNode>),
127    Builtin(BuiltinFn, Vec<ExprNode>),
128    Global(GlobalVar),
129    SymbolicPath(Vec<String>),
130    Node(NodeId),
131    PropertyValue(NodeId, PropertyPath),
132    VirtualProperty(VirtualPropertyId),
133    Conditional(Box<ExprNode>, Box<ExprNode>, Box<ExprNode>),
134}
135
136#[derive(Debug, Clone, PartialEq, Eq, Hash)]
137pub enum ExpressionReference {
138    Node {
139        node_id: NodeId,
140    },
141    PropertyValue {
142        node_id: NodeId,
143        property_path: PropertyPath,
144    },
145    VirtualProperty {
146        id: VirtualPropertyId,
147    },
148    SymbolicPath {
149        segments: Vec<String>,
150    },
151}
152
153#[derive(Debug, Clone, PartialEq)]
154pub struct Expression {
155    pub id: ExpressionId,
156    pub ast: ExprNode,
157    pub references: Vec<ExpressionReference>,
158    pub source: String,
159}