xenon_codegen/
expression.rs

1use enum_as_inner::EnumAsInner;
2
3use super::identifier::Identifier;
4
5/// An Expression
6#[derive(Clone, Default, EnumAsInner)]
7pub enum Expression {
8    /// Parentheses
9    Parentheses(Parentheses),
10    /// Any singular literal
11    Literal(Literal),
12    /// A unary operation
13    UnaryOperation(UnaryOperation),
14    /// A binary operation
15    BinaryOperation(BinaryOperation),
16    #[default]
17    Null
18}
19impl Expression {
20    /// Checks if the instance of expression is valid
21    pub fn is_valid(&self) -> bool {
22        if self.is_parentheses() {
23            return self.as_parentheses().unwrap().is_valid();
24        }
25        else if self.is_literal() {
26            return self.as_literal().unwrap().is_valid();
27        }
28        else if self.is_unary_operation() {
29            return self.as_unary_operation().unwrap().is_valid();
30        }
31        else if self.is_binary_operation() {
32            return self.as_binary_operation().unwrap().is_valid();
33        }
34        else {
35            return false;
36        }
37    }
38}
39
40/// A set of parentheses surrounding an expression
41#[derive(Clone, Default)]
42pub struct Parentheses {
43    /// The contained expression
44    pub value: Box<Expression>
45}
46impl Parentheses {
47    /// Creates a new valid instance of Parentheses
48    pub fn new(value: Expression) -> Parentheses {
49        return Parentheses {
50            value: Box::new(value)
51        };
52    }
53
54    /// Checks if the instance is valid
55    pub fn is_valid(&self) -> bool {
56        return self.value.is_valid();
57    }
58}
59
60/// A boolean literal
61#[derive(Clone, Default)]
62pub struct BooleanLiteral {
63    /// The value of the literal
64    pub value: bool
65}
66impl BooleanLiteral {
67    /// Creates a new valid instance of BooleanLiteral
68    pub fn new(value: bool) -> BooleanLiteral {
69        return BooleanLiteral {
70            value
71        };
72    }
73
74    /// Checks if the instance is valid
75    pub fn is_valid(&self) -> bool {
76        return true;
77    }
78}
79
80#[derive(Clone, Default)]
81pub struct IntegerLiteral {
82    pub value: i64
83}
84impl IntegerLiteral {
85    pub fn new(value: i64) -> IntegerLiteral {
86        return IntegerLiteral {
87            value: value
88        };
89    }
90
91    pub fn is_valid(&self) -> bool {
92        return true;
93    }
94}
95
96#[derive(Clone, Default)]
97pub struct FloatLiteral {
98    pub value: f64
99}
100impl FloatLiteral {
101    pub fn new(value: f64) -> FloatLiteral {
102        return FloatLiteral {
103            value
104        };
105    }
106
107    pub fn is_valid(&self) -> bool {
108        return self.value.is_normal();
109    }
110}
111
112#[derive(Clone, Default)]
113pub struct CharLiteral {
114    pub value: char
115}
116impl CharLiteral {
117    pub fn new(value: char) -> CharLiteral {
118        return CharLiteral {
119            value
120        };
121    }
122
123    pub fn is_valid(&self) -> bool {
124        return true;
125    }
126}
127
128#[derive(Clone, Default)]
129pub struct StringLiteral {
130    pub value: String
131}
132impl StringLiteral {
133    pub fn new(value: String) -> StringLiteral {
134        return StringLiteral {
135            value
136        };
137    }
138
139    pub fn is_valid(&self) -> bool {
140        return true;
141    }
142}
143
144#[derive(Clone, Default, EnumAsInner)]
145pub enum Literal {
146    BooleanLiteral(BooleanLiteral),
147    IntegerLiteral(IntegerLiteral),
148    HexLiteral(IntegerLiteral),
149    BinaryLiteral(IntegerLiteral),
150    FloatLiteral(FloatLiteral),
151    CharLiteral(CharLiteral),
152    StringLiteral(StringLiteral),
153    FunctionCall(Identifier),
154    #[default]
155    Null
156}
157impl Literal {
158    pub fn is_valid(&self) -> bool {
159        if self.is_boolean_literal() {
160            return self.as_boolean_literal().unwrap().is_valid();
161        }
162        else if self.is_integer_literal() {
163            return self.as_integer_literal().unwrap().is_valid();
164        }
165        else if self.is_hex_literal() {
166            return self.as_hex_literal().unwrap().is_valid();
167        }
168        else if self.is_binary_literal() {
169            return self.as_binary_literal().unwrap().is_valid();
170        }
171        else if self.is_float_literal() {
172            return self.as_float_literal().unwrap().is_valid();
173        }
174        else if self.is_char_literal() {
175            return self.as_char_literal().unwrap().is_valid();
176        }
177        else if self.is_string_literal() {
178            return self.as_string_literal().unwrap().is_valid();
179        }
180        else if self.is_function_call() {
181            return self.as_function_call().unwrap().is_valid();
182        }
183        else {
184            return false;
185        }
186    }
187}
188
189#[derive(Clone, Default)]
190pub struct UnaryOperation {
191    pub operator: String,
192    pub value: Box<Expression>
193}
194impl UnaryOperation {
195    pub fn new(operator: String, value: Expression) -> UnaryOperation {
196        return UnaryOperation {
197            operator,
198            value: Box::new(value)
199        };
200    }
201
202    pub fn is_valid(&self) -> bool {
203        return ["+", "-", "!", "&", "*"].contains(&self.operator.as_str()) && self.value.is_valid();
204    }
205}
206
207#[derive(Clone, Default)]
208pub struct BinaryOperation {
209    pub left: Box<Expression>,
210    pub operator: String,
211    pub right: Box<Expression>
212}
213impl BinaryOperation {
214    pub fn new(left: Expression, operator: String, right: Expression) -> BinaryOperation {
215        return BinaryOperation {
216            left: Box::new(left),
217            operator,
218            right: Box::new(right)
219        };
220    }
221
222    pub fn is_valid(&self) -> bool {
223        if !self.left.is_valid() {
224            return false;
225        }
226
227        if !self.right.is_valid() {
228            return false;
229        }
230
231        return ["as", "*", "/", "%", "+", "-", "<<", ">>", "&", "^", "|", "==", "!=", "<", "<=", ">", ">=", "&&", "||"].contains(&self.operator.as_str());
232    }
233}