xenon_codegen/
expression.rs

1use core::fmt;
2
3use enum_as_inner::EnumAsInner;
4
5use crate::identifier::IdentifierAccess;
6
7#[derive(Debug, Clone, Default, EnumAsInner)]
8pub enum Expression {
9    IntegerLiteral(IntegerLiteral),
10    FloatLiteral(FloatLiteral),
11    StringLiteral(StringLiteral),
12    BooleanLiteral(BooleanLiteral),
13    Parentheses(Parentheses),
14    UnaryOperation(UnaryOperation),
15    BinaryOperation(BinaryOperation),
16    Identifier(IdentifierAccess),
17    #[default]
18    Null,
19}
20impl Expression {
21    pub fn is_valid(&self) -> bool {
22        if self.is_integer_literal() {
23            self.as_integer_literal().unwrap().is_valid()
24        } else if self.is_float_literal() {
25            return self.as_float_literal().unwrap().is_valid();
26        } else if self.is_string_literal() {
27            return self.as_string_literal().unwrap().is_valid();
28        } else if self.is_boolean_literal() {
29            return self.as_boolean_literal().unwrap().is_valid();
30        } else if self.is_parentheses() {
31            return self.as_parentheses().unwrap().is_valid();
32        } else if self.is_unary_operation() {
33            return self.as_unary_operation().unwrap().is_valid();
34        } else if self.is_binary_operation() {
35            return self.as_binary_operation().unwrap().is_valid();
36        } else if self.is_identifier() {
37            return self.as_identifier().unwrap().is_valid();
38        } else {
39            return false;
40        }
41    }
42}
43impl fmt::Display for Expression {
44    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        if self.is_integer_literal() {
46            match write!(fmt, "{}", self.as_integer_literal().unwrap()) {
47                Ok(_) => (),
48                Err(e) => return Err(e),
49            }
50        } else if self.is_float_literal() {
51            match write!(fmt, "{}", self.as_float_literal().unwrap()) {
52                Ok(_) => (),
53                Err(e) => return Err(e),
54            }
55        } else if self.is_string_literal() {
56            match write!(fmt, "{}", self.as_string_literal().unwrap()) {
57                Ok(_) => (),
58                Err(e) => return Err(e),
59            }
60        } else if self.is_boolean_literal() {
61            match write!(fmt, "{}", self.as_boolean_literal().unwrap()) {
62                Ok(_) => (),
63                Err(e) => return Err(e),
64            }
65        } else if self.is_unary_operation() {
66            match write!(fmt, "{}", self.as_unary_operation().unwrap()) {
67                Ok(_) => (),
68                Err(e) => return Err(e),
69            }
70        } else if self.is_binary_operation() {
71            match write!(fmt, "{}", self.as_binary_operation().unwrap()) {
72                Ok(_) => (),
73                Err(e) => return Err(e),
74            }
75        } else if self.is_identifier() {
76            match write!(fmt, "{}", self.as_identifier().unwrap()) {
77                Ok(_) => (),
78                Err(e) => return Err(e),
79            }
80        }
81        Ok(())
82    }
83}
84
85#[derive(Debug, Clone, Default)]
86pub struct IntegerLiteral {
87    pub value: i64,
88}
89impl IntegerLiteral {
90    pub fn new(val: i64) -> IntegerLiteral {
91        IntegerLiteral { value: val }
92    }
93
94    pub fn is_valid(&self) -> bool {
95        true
96    }
97}
98impl fmt::Display for IntegerLiteral {
99    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        match write!(fmt, "{}", self.value) {
101            Ok(_) => (),
102            Err(e) => return Err(e),
103        }
104        Ok(())
105    }
106}
107
108#[derive(Debug, Clone, Default)]
109pub struct FloatLiteral {
110    pub value: f64,
111}
112impl FloatLiteral {
113    pub fn new(val: f64) -> FloatLiteral {
114        FloatLiteral { value: val }
115    }
116
117    pub fn is_valid(&self) -> bool {
118        self.value.is_normal() || self.value == 0.0
119    }
120}
121impl fmt::Display for FloatLiteral {
122    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        match write!(fmt, "{}", self.value) {
124            Ok(_) => (),
125            Err(e) => return Err(e),
126        }
127        Ok(())
128    }
129}
130
131#[derive(Debug, Clone, Default)]
132pub struct StringLiteral {
133    pub value: String,
134}
135impl StringLiteral {
136    pub fn new(val: String) -> StringLiteral {
137        StringLiteral { value: val }
138    }
139    pub fn is_valid(&self) -> bool {
140        true
141    }
142}
143impl fmt::Display for StringLiteral {
144    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        match write!(fmt, "\"{}\"", self.value) {
146            Ok(_) => (),
147            Err(e) => return Err(e),
148        }
149        Ok(())
150    }
151}
152
153#[derive(Debug, Clone, Default)]
154pub struct BooleanLiteral {
155    pub value: bool,
156}
157impl BooleanLiteral {
158    pub fn new(val: bool) -> BooleanLiteral {
159        BooleanLiteral { value: val }
160    }
161
162    pub fn is_valid(&self) -> bool {
163        true
164    }
165}
166impl fmt::Display for BooleanLiteral {
167    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168        match write!(fmt, "{}", self.value) {
169            Ok(_) => (),
170            Err(e) => return Err(e),
171        }
172        Ok(())
173    }
174}
175
176#[derive(Debug, Clone, Default)]
177pub struct UnaryOperation {
178    pub operator: String,
179    pub term: Box<Expression>,
180}
181impl UnaryOperation {
182    pub fn new(op: String, val: Expression) -> UnaryOperation {
183        UnaryOperation {
184            operator: op,
185            term: Box::new(val),
186        }
187    }
188
189    pub fn is_valid(&self) -> bool {
190        if !["+", "-", "*", "&"].contains(&self.operator.as_str()) {
191            return false;
192        }
193        self.term.is_valid()
194    }
195}
196impl fmt::Display for UnaryOperation {
197    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198        match write!(fmt, "{}{}", self.operator, self.term) {
199            Ok(_) => (),
200            Err(e) => return Err(e),
201        }
202        Ok(())
203    }
204}
205
206#[derive(Debug, Clone, Default)]
207pub struct Parentheses {
208    pub value: Box<Expression>,
209}
210impl Parentheses {
211    pub fn new(expr: Expression) -> Parentheses {
212        Parentheses {
213            value: Box::new(expr),
214        }
215    }
216
217    pub fn is_valid(&self) -> bool {
218        self.value.is_valid()
219    }
220}
221impl fmt::Display for Parentheses {
222    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        match write!(fmt, "({})", self.value) {
224            Ok(_) => (),
225            Err(e) => return Err(e),
226        }
227        Ok(())
228    }
229}
230
231#[derive(Debug, Clone, Default)]
232pub struct BinaryOperation {
233    pub left: Box<Expression>,
234    pub operator: String,
235    pub right: Box<Expression>,
236}
237impl BinaryOperation {
238    pub fn new(left: Expression, op: String, right: Expression) -> BinaryOperation {
239        BinaryOperation {
240            left: Box::new(left),
241            operator: op,
242            right: Box::new(right),
243        }
244    }
245
246    pub fn is_valid(&self) -> bool {
247        self.left.is_valid()
248            && self.right.is_valid()
249            && ["+", "-", "*", "/", "==", "<", "<=", ">", ">=", "&&", "||"]
250                .contains(&self.operator.as_str())
251    }
252}
253impl fmt::Display for BinaryOperation {
254    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
255        match write!(fmt, "{} {} {}", self.left, self.operator, self.right) {
256            Ok(_) => (),
257            Err(e) => return Err(e),
258        }
259        Ok(())
260    }
261}