1use std::fmt::Display;
2
3use crate::lexer::tokens::Literal;
4
5#[derive(Debug, PartialEq, Clone)]
6pub enum Statement {
7 Variable(VarStmt),
8 Return(ReturnStmt),
9 Break(BreakStmt),
10 Local(LocalStmt),
11 Use(UseStmt),
12 Expression(Expression),
13}
14
15#[derive(Debug, PartialEq, Clone)]
16pub enum Expression {
17 Ident(Ident),
18 Literal(Literal),
19 Prefix(PrefixExpr),
20 Infix(InfixExpr),
21 Index(IndexExpr),
22 Call(CallExpr),
23 List(ListExpr),
24 None,
25
26 If(IfExpr),
27 Loop(LoopExpr),
28 When(WhenExpr),
29 Func(FuncExpr),
30 Annotation(AnnotationExpr),
31 Struct(StructExpr),
32 Enum(EnumExpr),
33}
34
35#[derive(Debug, PartialEq, Clone)]
36pub struct Ident(pub String);
37
38#[derive(Debug, PartialEq, Clone)]
39pub struct OptionallyTypedIdent {
40 pub ident: Ident,
41 pub _type: Option<Ident>,
42}
43
44#[derive(Debug, PartialEq, Clone)]
45pub struct VarStmt {
46 pub name: OptionallyTypedIdent,
47 pub val: Expression,
48 pub is_const: bool,
49}
50
51#[derive(Debug, PartialEq, Clone)]
52pub struct ReturnStmt {
53 pub val: Option<Expression>,
54}
55
56#[derive(Debug, PartialEq, Clone)]
57pub struct BreakStmt {
58 pub label: Option<Ident>,
59}
60
61#[derive(Debug, PartialEq, Clone)]
62pub struct LocalStmt {
63 pub val: Box<Statement>,
64}
65
66#[derive(Debug, PartialEq, Clone)]
67pub struct UseStmt {
68 pub import: Ident,
70}
71
72#[derive(Debug, PartialEq, Clone)]
73pub struct PrefixExpr {
74 pub op: PrefixOp,
75 pub val: Box<Expression>,
76}
77
78#[derive(Debug, PartialEq, Clone)]
79pub struct InfixExpr {
80 pub op: InfixOp,
81 pub left: Box<Expression>,
82 pub right: Box<Expression>,
83}
84
85#[derive(Debug, PartialEq, Clone)]
86pub struct IndexExpr {
87 pub list: Box<Expression>,
88 pub pos: usize,
89}
90
91#[derive(Debug, PartialEq, Clone)]
92pub struct CallExpr {
93 pub ident: Box<Expression>,
96 pub args: Vec<Expression>,
97}
98
99#[derive(Debug, PartialEq, Clone)]
100pub struct ListExpr {
101 pub list: Vec<Expression>,
102}
103
104#[derive(Debug, PartialEq, Clone)]
105pub struct IfExpr {
106 pub _type: IfType,
107 pub cond: Option<Box<Expression>>,
108 pub block: BlockStmt,
109 pub alt: Option<Box<IfExpr>>,
110}
111
112#[derive(Debug, PartialEq, Clone)]
113pub struct LoopExpr {
114 pub _type: LoopType,
115 pub cond: Option<Box<Expression>>,
116 pub block: BlockStmt,
117 pub alt: Option<Box<LoopExpr>>,
118}
119
120#[derive(Debug, PartialEq, Clone)]
121pub struct WhenExpr {
122 pub comp_val: Option<Box<Expression>>,
123 pub cases: Vec<CaseStmt>,
124}
125
126#[derive(Debug, PartialEq, Clone)]
127pub struct FuncExpr {
128 pub ret_type: Option<Ident>,
129 pub args: Vec<OptionallyTypedIdent>,
130 pub block: BlockStmt,
131}
132
133#[derive(Debug, PartialEq, Clone)]
135pub struct AnnotationExpr {
136 pub name: Ident,
137}
138
139#[derive(Debug, PartialEq, Clone)]
140pub struct StructExpr {
141 pub fields: Vec<OptionallyTypedIdent>,
142}
143
144#[derive(Debug, PartialEq, Clone)]
145pub struct EnumExpr {
146 pub consts: Ident,
147}
148
149#[derive(Debug, PartialEq, Clone)]
150pub struct BlockStmt {
151 pub stmts: Vec<Statement>,
152}
153
154#[derive(Debug, PartialEq, Clone)]
155pub struct CaseStmt {
156 pub _type: CaseType,
157 pub comp_cond: Option<Box<Expression>>,
160 pub comp_val: Option<Box<Expression>>,
162}
163
164#[derive(Debug, PartialEq, Clone, Copy)]
165pub enum PrefixOp {
166 Pos,
167 Neg,
168 Not,
169}
170
171#[derive(Debug, PartialEq, Clone, Copy)]
172pub enum InfixOp {
173 Add,
174 Sub,
175 Mul,
176 Div,
177 Eq,
178 NEq,
179 GT,
180 LT,
181 GTEq,
182 LTEq,
183 As,
184 In,
185 Range,
186 Assign,
187}
188
189#[derive(Debug, PartialEq, Clone, Copy)]
190pub enum IfType {
191 If,
192 Else,
193 ElseIf,
194}
195
196#[derive(Debug, PartialEq, Clone, Copy)]
197pub enum LoopType {
198 For,
199 While,
200 ElseFor,
201 ElseWhile,
202 Else,
203}
204
205#[derive(Debug, PartialEq, Clone)]
206pub enum CaseType {
207 Regular,
208 Else,
209}
210
211impl Display for Ident {
212 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213 write!(f, "{}", self.0)
214 }
215}
216
217impl Display for Statement {
218 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219 write!(
220 f,
221 "{}",
222 match self {
223 Statement::Variable(var) => format!(
224 "{} {} = {}",
225 match var.is_const {
226 true => "const",
227 false => "var",
228 },
229 todo!(), var.val,
231 ),
232 Statement::Return(ret) => todo!(),
233 Statement::Break(br) => todo!(),
234 Statement::Local(lcl) => todo!(),
235 Statement::Use(_use) => todo!(),
236 Statement::Expression(expr) => expr.to_string(),
237 }
238 )
239 }
240}
241
242impl Display for Expression {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 write!(
245 f,
246 "{}",
247 match self {
248 Expression::Ident(ident) => ident.to_string(),
249 Expression::Literal(lit) => lit.to_string(),
250 Expression::Prefix(prefix) => prefix.to_string(),
251 Expression::Infix(infix) => infix.to_string(),
252 Expression::Index(_) => todo!(),
253 Expression::List(_) => todo!(),
255 Expression::None => "none".into(),
256 Expression::When(_) => todo!(),
259 Expression::Annotation(_) => todo!(),
261 Expression::Struct(_) => todo!(),
262 Expression::Enum(_) => todo!(),
263 _ => todo!(),
264 }
265 )
266 }
267}
268
269impl Display for PrefixExpr {
270 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
271 write!(
272 f,
273 "{}{}",
274 match self.op {
275 PrefixOp::Pos => "+",
276 PrefixOp::Neg => "-",
277 PrefixOp::Not => "!",
278 },
279 self.to_string()
280 )
281 }
282}
283
284impl Display for InfixExpr {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 write!(
287 f,
288 "{} {} {}",
289 self.left.to_string(),
290 match self.op {
291 InfixOp::Add => "+",
292 InfixOp::Sub => "-",
293 InfixOp::Mul => "*",
294 InfixOp::Div => "/",
295 InfixOp::Eq => "==",
296 InfixOp::NEq => "!=",
297 InfixOp::GT => ">",
298 InfixOp::LT => "<",
299 InfixOp::GTEq => ">=",
300 InfixOp::LTEq => "<=",
301 InfixOp::As => "as",
302 InfixOp::In => "in",
303 InfixOp::Range =>
304 return write!(f, "{}..{}", self.left.to_string(), self.right.to_string()),
305 InfixOp::Assign => "=",
306 },
307 self.right.to_string()
308 )
309 }
310}