roan_ast/ast/expr.rs
1use crate::{statements::Stmt, GetSpan, Token, TokenKind};
2use indexmap::IndexMap;
3use roan_error::TextSpan;
4use std::fmt::{Display, Formatter};
5
6/// Represents a collection of expressions as a vector.
7/// Used to handle lists of expressions, such as arrays or argument lists.
8#[derive(Clone, Debug, PartialEq)]
9pub struct VecExpr {
10 /// The vector containing the expressions.
11 pub exprs: Vec<Expr>,
12}
13
14/// Enum that defines the possible literal types in the language.
15/// Literals are constant values such as numbers, strings, and booleans.
16#[derive(Clone, Debug, PartialEq)]
17pub enum LiteralType {
18 /// An integer literal (e.g., `42`).
19 Int(i64),
20 /// A floating-point literal (e.g., `3.14`).
21 Float(f64),
22 /// A string literal (e.g., `"hello"`).
23 String(String),
24 /// A boolean literal (`true` or `false`).
25 Bool(bool),
26 /// A character literal (e.g., `'a'`).
27 Char(char),
28 /// A `null` literal representing the absence of a value.
29 Null,
30}
31
32/// Represents a literal expression in the AST.
33/// It consists of a token and a specific literal value (e.g., integer, string).
34#[derive(Clone, Debug, PartialEq)]
35pub struct Literal {
36 /// The token representing the literal in the source code.
37 pub token: Token,
38 /// The value of the literal.
39 pub value: LiteralType,
40}
41
42impl Literal {
43 pub fn new(token: Token, value: LiteralType) -> Self {
44 Literal { token, value }
45 }
46}
47
48/// Enum representing the various binary operators in the language.
49/// Binary operators are used in binary expressions (e.g., `a + b`).
50#[derive(Debug, Copy, Clone, PartialEq)]
51pub enum BinOpKind {
52 // Arithmetic operators
53 /// Addition operator (`+`).
54 Plus,
55 /// Subtraction operator (`-`).
56 Minus,
57 /// Multiplication operator (`*`).
58 Multiply,
59 /// Division operator (`/`).
60 Divide,
61 /// Exponentiation operator (`**`).
62 Power,
63 /// Modulo operator (`%`).
64 Modulo,
65 // Bitwise operators
66 /// Bitwise AND operator (`&`).
67 BitwiseAnd,
68 /// Bitwise OR operator (`|`).
69 BitwiseOr,
70 /// Bitwise XOR operator (`^`).
71 BitwiseXor,
72 /// Bitwise shift left operator (`<<`).
73 ShiftLeft,
74 /// Bitwise shift right operator (`>>`).
75 ShiftRight,
76 // Relational operators
77 /// Equality operator (`==`).
78 Equals,
79 /// Less-than operator (`<`).
80 LessThan,
81 /// Less-than-or-equal operator (`<=`).
82 LessThanOrEqual,
83 /// Greater-than operator (`>`).
84 GreaterThan,
85 /// Greater-than-or-equal operator (`>=`).
86 GreaterThanOrEqual,
87 // Logical operators
88 /// Logical AND operator (`&&`).
89 And,
90 /// Logical OR operator (`||`).
91 Or,
92 // Equality operators (duplicated? Consider removing duplicates)
93 /// Equality operator (`==`).
94 EqualsEquals,
95 /// Inequality operator (`!=`).
96 BangEquals,
97 // Increment/Decrement operators
98 /// Increment operator (`++`).
99 Increment,
100 /// Decrement operator (`--`).
101 Decrement,
102 // Assignment operators
103 /// Subtraction assignment operator (`-=`).
104 MinusEquals,
105 /// Addition assignment operator (`+=`).
106 PlusEquals,
107}
108
109/// Represents a binary expression in the AST.
110/// A binary expression consists of two operands and an operator (e.g., `a + b`).
111#[derive(Debug, Clone, PartialEq)]
112pub struct Binary {
113 /// The left operand of the binary expression.
114 pub left: Box<Expr>,
115 /// The operator used in the binary expression.
116 pub operator: BinOpKind,
117 /// The right operand of the binary expression.
118 pub right: Box<Expr>,
119}
120
121impl GetSpan for Binary {
122 /// Returns the combined source span of the left and right operands.
123 fn span(&self) -> TextSpan {
124 let left = self.left.span();
125 let right = self.right.span();
126
127 TextSpan::combine(vec![left, right]).unwrap()
128 }
129}
130
131/// Represents a unary expression in the AST.
132/// Unary expressions operate on a single operand (e.g., `-a`).
133#[derive(Debug, Clone, PartialEq)]
134pub struct Unary {
135 /// The operator used in the unary expression.
136 pub operator: UnOperator,
137 /// The operand of the unary expression.
138 pub expr: Box<Expr>,
139 /// The token representing the unary operation in the source code.
140 pub token: Token,
141}
142
143impl GetSpan for Unary {
144 /// Returns the source span of the unary expression.
145 fn span(&self) -> TextSpan {
146 TextSpan::combine(vec![self.operator.token.span.clone(), self.expr.span()]).unwrap()
147 }
148}
149
150/// Represents a variable in the AST.
151/// A variable refers to a named entity in the program.
152#[derive(Debug, Clone, PartialEq)]
153pub struct Variable {
154 /// The name of the variable.
155 pub ident: String,
156 /// The token representing the variable in the source code.
157 pub token: Token,
158}
159
160/// Represents a parenthesized expression in the AST.
161/// Parenthesized expressions are used to override operator precedence.
162#[derive(Debug, Clone, PartialEq)]
163pub struct Parenthesized {
164 /// The expression contained within the parentheses.
165 pub expr: Box<Expr>,
166}
167
168/// Represents a function call in the AST.
169/// It consists of a function name (callee) and a list of arguments.
170#[derive(Debug, Clone, PartialEq)]
171pub struct CallExpr {
172 /// The name of the function being called.
173 pub callee: String,
174 /// The list of arguments passed to the function.
175 pub args: Vec<Expr>,
176 /// The token representing the function call in the source code.
177 pub token: Token,
178}
179
180impl GetSpan for CallExpr {
181 /// Returns the source span of the function call expression.
182 fn span(&self) -> TextSpan {
183 // TODO: get the span of the closing parenthesis
184 let callee_span = self.token.span.clone();
185 let args_span: Vec<TextSpan> = self.args.iter().map(|arg| arg.span()).collect();
186 let args_span = TextSpan::combine(args_span);
187
188 let mut spans = vec![callee_span];
189
190 if args_span.is_some() {
191 spans.push(args_span.unwrap());
192 }
193
194 TextSpan::combine(spans).unwrap()
195 }
196}
197
198#[derive(Debug, Clone, PartialEq)]
199pub enum AssignOperator {
200 /// Assignment operator (`=`).
201 Assign,
202 /// Addition assignment operator (`+=`).
203 PlusEquals,
204 /// Subtraction assignment operator (`-=`).
205 MinusEquals,
206 /// Multiplication assignment operator (`*=`).
207 MultiplyEquals,
208 /// Division assignment operator (`/=`).
209 DivideEquals,
210}
211
212impl AssignOperator {
213 pub fn from_token_kind(kind: TokenKind) -> Self {
214 match kind {
215 TokenKind::Equals => AssignOperator::Assign,
216 TokenKind::PlusEquals => AssignOperator::PlusEquals,
217 TokenKind::MinusEquals => AssignOperator::MinusEquals,
218 TokenKind::MultiplyEquals => AssignOperator::MultiplyEquals,
219 TokenKind::DivideEquals => AssignOperator::DivideEquals,
220 _ => todo!("Proper error"),
221 }
222 }
223}
224
225/// Represents an assignment expression in the AST.
226/// An assignment binds a value to a variable.
227#[derive(Debug, Clone, PartialEq)]
228pub struct Assign {
229 /// The variable being assigned to.
230 pub left: Box<Expr>,
231 /// The assignment operator.
232 pub op: AssignOperator,
233 /// The value being assigned.
234 pub right: Box<Expr>,
235}
236
237/// Enum representing unary operator kinds (e.g., `-`, `~`).
238#[derive(Debug, Copy, Clone, PartialEq)]
239pub enum UnOpKind {
240 /// Minus operator (`-`).
241 Minus,
242 /// Bitwise NOT operator (`~`).
243 BitwiseNot,
244 /// Logical NOT operator (`!`).
245 LogicalNot,
246}
247
248impl Display for UnOpKind {
249 /// Formats the unary operator as a string.
250 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
251 match self {
252 UnOpKind::Minus => write!(f, "-"),
253 UnOpKind::BitwiseNot => write!(f, "~"),
254 UnOpKind::LogicalNot => write!(f, "!"),
255 }
256 }
257}
258
259/// Represents a unary operator in the AST.
260#[derive(Debug, Clone, PartialEq)]
261pub struct UnOperator {
262 /// The specific kind of unary operator.
263 pub kind: UnOpKind,
264 /// The token representing the unary operator in the source code.
265 pub token: Token,
266}
267
268impl UnOperator {
269 /// Creates a new unary operator.
270 ///
271 /// # Arguments
272 ///
273 /// * `kind` - The kind of unary operator.
274 /// * `token` - The token representing the operator in the source code.
275 ///
276 /// # Returns
277 ///
278 /// A new `UnOperator` instance.
279 pub fn new(kind: UnOpKind, token: Token) -> Self {
280 UnOperator { kind, token }
281 }
282}
283
284/// Represents a binary operator in the AST.
285#[derive(Debug, Clone)]
286pub struct BinOperator {
287 /// The specific kind of binary operator.
288 pub kind: BinOpKind,
289 /// The token representing the binary operator in the source code.
290 pub token: Token,
291}
292
293impl BinOperator {
294 /// Creates a new binary operator.
295 ///
296 /// # Arguments
297 ///
298 /// * `kind` - The kind of binary operator.
299 /// * `token` - The token representing the operator in the source code.
300 ///
301 /// # Returns
302 ///
303 /// A new `BinOperator` instance.
304 pub fn new(kind: BinOpKind, token: Token) -> Self {
305 BinOperator { kind, token }
306 }
307
308 /// Returns the precedence of the operator.
309 ///
310 /// Higher numbers indicate higher precedence.
311 ///
312 /// # Returns
313 ///
314 /// An unsigned 8-bit integer representing the operator's precedence.
315 pub fn precedence(&self) -> u8 {
316 match self.kind {
317 // Highest precedence
318 BinOpKind::Power => 20,
319 BinOpKind::Multiply | BinOpKind::Divide | BinOpKind::Modulo => 19,
320 BinOpKind::Plus | BinOpKind::Minus => 18,
321 BinOpKind::ShiftLeft | BinOpKind::ShiftRight => 17,
322 BinOpKind::BitwiseAnd => 16,
323 BinOpKind::BitwiseXor => 15,
324 BinOpKind::BitwiseOr => 14,
325 // Relational operators
326 BinOpKind::LessThan
327 | BinOpKind::LessThanOrEqual
328 | BinOpKind::GreaterThan
329 | BinOpKind::GreaterThanOrEqual => 13,
330 // Equality operators
331 BinOpKind::Equals | BinOpKind::EqualsEquals | BinOpKind::BangEquals => 12,
332 // Logical operators
333 BinOpKind::And => 11,
334 BinOpKind::Or => 10,
335 // Increment/Decrement operators
336 BinOpKind::Increment | BinOpKind::Decrement => 9,
337 // Assignment operators
338 BinOpKind::MinusEquals | BinOpKind::PlusEquals => 8,
339 }
340 }
341
342 /// Returns the associativity of the operator.
343 ///
344 /// Operators can be either left-associative or right-associative.
345 ///
346 /// # Returns
347 ///
348 /// A `BinOpAssociativity` enum indicating the associativity.
349 pub fn associativity(&self) -> BinOpAssociativity {
350 match self.kind {
351 BinOpKind::Power => BinOpAssociativity::Right,
352 _ => BinOpAssociativity::Left,
353 }
354 }
355}
356
357/// Enum representing the associativity of a binary operator.
358#[derive(Debug, Clone, PartialEq)]
359pub enum BinOpAssociativity {
360 /// Left-associative operators group from the left.
361 Left,
362 /// Right-associative operators group from the right.
363 Right,
364}
365
366/// Spread operator for variadic arguments.
367///
368/// The spread operator is used to pass an array as separate arguments to a function.
369#[derive(Debug, Clone, PartialEq)]
370pub struct Spread {
371 pub token: Token,
372 pub expr: Box<Expr>,
373}
374
375/// Enum representing an expression in the AST.
376/// Expressions include literals, binary operations, unary operations, and more.
377#[derive(Clone, Debug, PartialEq)]
378pub enum Expr {
379 /// A literal value (e.g., number, string).
380 Literal(Literal),
381 /// A binary operation (e.g., `a + b`).
382 Binary(Binary),
383 /// A unary operation (e.g., `-a`).
384 Unary(Unary),
385 /// A variable reference.
386 Variable(Variable),
387 /// A parenthesized expression to override precedence.
388 Parenthesized(Parenthesized),
389 /// A function call expression.
390 Call(CallExpr),
391 /// An assignment expression (e.g., `a = b`).
392 Assign(Assign),
393 /// A vector (list) of expressions.
394 Vec(VecExpr),
395 /// An access expression (e.g., `struct.name`, `arr[0]`, `Person::new`).
396 Access(AccessExpr),
397 /// A spread operator for variadic arguments. (e.g., `...args`)
398 Spread(Spread),
399 /// Null literal.
400 Null(Token),
401 /// Struct constructor. (e.g., `MyStruct { field: value }`)
402 StructConstructor(StructConstructor),
403 /// Then-else expression. (e.g., `if condition then value else other`)
404 ThenElse(ThenElse),
405 /// Object expression.
406 Object(ObjectExpr),
407}
408
409/// Represents an object expression in the AST.
410///
411/// An object expression is a collection of key-value pairs.
412#[derive(Debug, Clone, PartialEq)]
413pub struct ObjectExpr {
414 /// The key-value pairs in the object.
415 pub fields: IndexMap<String, Expr>,
416 /// The token representing opening and closing braces.
417 pub braces: (Token, Token),
418}
419
420/// Represents a then-else expression in the AST.
421///
422/// A then-else expression is used to conditionally evaluate one of two expressions.
423///
424/// # Examples
425/// ```roan
426/// let value = if condition then 42 else 0
427/// ```
428#[derive(Debug, Clone, PartialEq)]
429pub struct ThenElse {
430 /// The condition expression.
431 pub condition: Box<Expr>,
432 /// The expression to evaluate if the condition is true.
433 pub then_expr: Box<Expr>,
434 /// The expression to evaluate if the condition is false.
435 pub else_expr: Box<Expr>,
436 /// The token representing the `then` keyword.
437 pub then_token: Token,
438 /// The token representing the `else` keyword.
439 pub else_token: Token,
440}
441
442impl GetSpan for ThenElse {
443 /// Returns the combined source span of the condition, then expression, and else expression.
444 fn span(&self) -> TextSpan {
445 let condition_span = self.condition.span();
446 let then_span = self.then_expr.span();
447 let else_span = self.else_expr.span();
448
449 TextSpan::combine(vec![condition_span, then_span, else_span]).unwrap()
450 }
451}
452
453/// Represents a struct constructor expression in the AST.
454///
455/// A struct constructor creates a new instance of a struct with the specified field values.
456#[derive(Debug, Clone, PartialEq)]
457pub struct StructConstructor {
458 /// The name of the struct being constructed.
459 pub name: String,
460 /// The field values for the struct.
461 pub fields: Vec<(String, Expr)>,
462 /// The token representing the struct constructor in the source code.
463 pub token: Token,
464}
465
466/// Enum representing the kind of access in an access expression.
467#[derive(Debug, Clone, PartialEq)]
468pub enum AccessKind {
469 /// Field access (e.g., `.name`).
470 Field(Box<Expr>),
471 /// Index access (e.g., `[0]`).
472 Index(Box<Expr>),
473 /// Static method access (e.g., `Person::new`).
474 StaticMethod(Box<Expr>),
475}
476
477/// Represents an access expression in the AST.
478/// It includes accessing a field or indexing into a collection.
479#[derive(Debug, Clone, PartialEq)]
480pub struct AccessExpr {
481 /// The base expression being accessed.
482 pub base: Box<Expr>,
483 /// The kind of access (field or index).
484 pub access: AccessKind,
485 /// The token representing the access operation (e.g., `.`, `[`, `]`).
486 pub token: Token,
487}
488
489impl GetSpan for AccessExpr {
490 /// Returns the combined source span of the base expression and the access operation.
491 fn span(&self) -> TextSpan {
492 let base_span = self.base.span();
493 let access_span = match &self.access {
494 AccessKind::Field(_) => self.token.span.clone(), // Span includes the '.' and the field name
495 AccessKind::Index(index_expr) => {
496 TextSpan::combine(vec![self.token.span.clone(), index_expr.span()]).unwrap()
497 } // Span includes '[' , index, and ']'
498 AccessKind::StaticMethod(method) => {
499 TextSpan::combine(vec![self.token.span.clone(), method.span()]).unwrap()
500 }
501 };
502 TextSpan::combine(vec![base_span, access_span]).unwrap()
503 }
504}
505
506impl GetSpan for Expr {
507 /// Returns the `TextSpan` associated with the expression in the source code.
508 fn span(&self) -> TextSpan {
509 match &self {
510 Expr::Literal(l) => l.clone().token.span,
511 Expr::Binary(b) => {
512 let left = b.left.span();
513 let right = b.right.span();
514 TextSpan::combine(vec![left, right]).unwrap()
515 }
516 Expr::Unary(u) => u.clone().token.span,
517 Expr::Variable(v) => v.clone().token.span,
518 Expr::Parenthesized(p) => p.expr.span(),
519 Expr::Call(c) => c.clone().token.span,
520 Expr::Assign(a) => {
521 let left = a.left.span();
522 let right = a.right.span();
523 TextSpan::combine(vec![left, right]).unwrap()
524 }
525 Expr::Vec(v) => {
526 let spans: Vec<TextSpan> = v.exprs.iter().map(|e| e.span()).collect();
527 TextSpan::combine(spans).unwrap()
528 }
529 Expr::Access(a) => a.span(),
530 Expr::Spread(s) => {
531 TextSpan::combine(vec![s.token.span.clone(), s.expr.span()]).unwrap()
532 }
533 Expr::Null(t) => t.span.clone(),
534 Expr::StructConstructor(s) => s.token.span.clone(),
535 Expr::ThenElse(t) => t.span(),
536 Expr::Object(o) => {
537 TextSpan::combine(vec![o.braces.0.span.clone(), o.braces.1.span.clone()]).unwrap()
538 }
539 }
540 }
541}
542
543impl Expr {
544 /// Converts the expression into a statement.
545 ///
546 /// # Returns
547 ///
548 /// A `Stmt::Expr` variant containing the expression.
549 pub fn into_stmt(self) -> Stmt {
550 Stmt::Expr(Box::new(self))
551 }
552
553 /// Converts the expression into a variable.
554 ///
555 /// # Panics
556 ///
557 /// Panics if the expression is not a `Variable` variant.
558 ///
559 /// # Returns
560 ///
561 /// The `Variable` struct contained within the expression.
562 pub fn into_variable(self) -> Variable {
563 match self {
564 Expr::Variable(v) => v,
565 _ => panic!("Expected variable"),
566 }
567 }
568
569 /// Creates a new null literal expression.
570 pub fn new_null(token: Token) -> Self {
571 Expr::Null(token)
572 }
573
574 /// Creates a new field access expression.
575 ///
576 /// # Arguments
577 ///
578 /// * `base` - The base expression being accessed.
579 /// * `field` - The name of the field to access.
580 /// * `token` - The token representing the '.' operator.
581 ///
582 /// # Returns
583 ///
584 /// A new `Expr::Access` variant with `AccessKind::Field`.
585 pub fn new_field_access(base: Expr, field: Expr, token: Token) -> Self {
586 Expr::Access(AccessExpr {
587 base: Box::new(base),
588 access: AccessKind::Field(Box::new(field)),
589 token,
590 })
591 }
592
593 /// Create a new spread expression.
594 ///
595 /// # Arguments
596 /// * `token` - The token representing the spread operator.
597 /// * `expr` - The expression to spread.
598 ///
599 /// # Returns
600 /// A new `Expr::Spread` variant.
601 pub fn new_spread(token: Token, expr: Expr) -> Self {
602 Expr::Spread(Spread {
603 token,
604 expr: Box::new(expr),
605 })
606 }
607
608 /// Creates a new index access expression.
609 ///
610 /// # Arguments
611 ///
612 /// * `base` - The base expression being accessed.
613 /// * `index` - The index expression.
614 /// * `token` - The token representing the '[' and ']' operators.
615 ///
616 /// # Returns
617 ///
618 /// A new `Expr::Access` variant with `AccessKind::Index`.
619 pub fn new_index_access(base: Expr, index: Expr, token: Token) -> Self {
620 // **Added**
621 Expr::Access(AccessExpr {
622 base: Box::new(base),
623 access: AccessKind::Index(Box::new(index)),
624 token,
625 })
626 }
627
628 /// Creates a new then-else expression.
629 ///
630 /// # Arguments
631 /// * `condition` - The condition expression.
632 /// * `then_expr` - The expression to evaluate if the condition is true.
633 /// * `else_expr` - The expression to evaluate if the condition is false.
634 /// * `then_token` - The token representing the `then` keyword.
635 /// * `else_token` - The token representing the `else` keyword.
636 ///
637 /// # Returns
638 ///
639 /// A new `Expr::ThenElse` variant.
640 pub fn new_then_else(
641 condition: Expr,
642 then_expr: Expr,
643 else_expr: Expr,
644 then_token: Token,
645 else_token: Token,
646 ) -> Self {
647 Expr::ThenElse(ThenElse {
648 condition: Box::new(condition),
649 then_expr: Box::new(then_expr),
650 else_expr: Box::new(else_expr),
651 then_token,
652 else_token,
653 })
654 }
655
656 /// Creates a new unary expression.
657 ///
658 /// # Arguments
659 ///
660 /// * `operator` - The unary operator.
661 /// * `expr` - The operand expression.
662 /// * `token` - The token representing the unary operation.
663 ///
664 /// # Returns
665 ///
666 /// A new `Expr::Unary` variant.
667 pub fn new_unary(operator: UnOperator, expr: Expr, token: Token) -> Self {
668 Expr::Unary(Unary {
669 operator,
670 expr: Box::new(expr),
671 token,
672 })
673 }
674
675 /// Creates a new assignment expression.
676 ///
677 /// # Arguments
678 ///
679 /// * `ident` - The token representing the variable identifier.
680 /// * `token` - The token representing the assignment operation.
681 /// * `value` - The expression to assign.
682 ///
683 /// # Returns
684 ///
685 /// A new `Expr::Assign` variant.
686 pub fn new_assign(left: Expr, op: AssignOperator, right: Expr) -> Self {
687 Expr::Assign(Assign {
688 left: Box::new(left),
689 op,
690 right: Box::new(right),
691 })
692 }
693
694 /// Creates a new binary expression.
695 ///
696 /// # Arguments
697 ///
698 /// * `left` - The left operand expression.
699 /// * `operator` - The binary operator.
700 /// * `right` - The right operand expression.
701 ///
702 /// # Returns
703 ///
704 /// A new `Expr::Binary` variant.
705 pub fn new_binary(left: Expr, operator: BinOperator, right: Expr) -> Self {
706 Expr::Binary(Binary {
707 left: Box::new(left),
708 operator: operator.kind,
709 right: Box::new(right),
710 })
711 }
712
713 /// Creates a new integer literal expression.
714 ///
715 /// # Arguments
716 ///
717 /// * `token` - The token representing the integer literal.
718 /// * `value` - The integer value.
719 ///
720 /// # Returns
721 ///
722 /// A new `Expr::Literal` variant with `LiteralType::Int`.
723 pub fn new_integer(token: Token, value: i64) -> Self {
724 Expr::Literal(Literal {
725 token,
726 value: LiteralType::Int(value),
727 })
728 }
729
730 /// Creates a new floating-point literal expression.
731 ///
732 /// # Arguments
733 ///
734 /// * `token` - The token representing the float literal.
735 /// * `value` - The floating-point value.
736 ///
737 /// # Returns
738 ///
739 /// A new `Expr::Literal` variant with `LiteralType::Float`.
740 pub fn new_float(token: Token, value: f64) -> Self {
741 Expr::Literal(Literal {
742 token,
743 value: LiteralType::Float(value),
744 })
745 }
746
747 /// Creates a new boolean literal expression.
748 ///
749 /// # Arguments
750 ///
751 /// * `token` - The token representing the boolean literal.
752 /// * `value` - The boolean value.
753 ///
754 /// # Returns
755 ///
756 /// A new `Expr::Literal` variant with `LiteralType::Bool`.
757 pub fn new_bool(token: Token, value: bool) -> Self {
758 Expr::Literal(Literal {
759 token,
760 value: LiteralType::Bool(value),
761 })
762 }
763
764 /// Creates a new variable expression.
765 ///
766 /// # Arguments
767 ///
768 /// * `ident` - The token representing the variable identifier.
769 /// * `name` - The name of the variable.
770 ///
771 /// # Returns
772 ///
773 /// A new `Expr::Variable` variant.
774 pub fn new_variable(ident: Token, name: String) -> Self {
775 Expr::Variable(Variable {
776 ident: name,
777 token: ident,
778 })
779 }
780
781 /// Creates a new function call expression.
782 ///
783 /// # Arguments
784 ///
785 /// * `callee` - The name of the function being called.
786 /// * `args` - The list of argument expressions.
787 /// * `token` - The token representing the function call.
788 ///
789 /// # Returns
790 ///
791 /// A new `Expr::Call` variant.
792 pub fn new_call(callee: String, args: Vec<Expr>, token: Token) -> Self {
793 Expr::Call(CallExpr {
794 callee,
795 args,
796 token,
797 })
798 }
799
800 /// Creates a new string literal expression.
801 ///
802 /// # Arguments
803 ///
804 /// * `token` - The token representing the string literal.
805 /// * `value` - The string value.
806 ///
807 /// # Returns
808 ///
809 /// A new `Expr::Literal` variant with `LiteralType::String`.
810 pub fn new_string(token: Token, value: String) -> Self {
811 Expr::Literal(Literal {
812 token,
813 value: LiteralType::String(value),
814 })
815 }
816
817 /// Creates a new character literal expression.
818 ///
819 /// # Arguments
820 /// * `token` - The token representing the character literal.
821 /// * `value` - The character value.
822 ///
823 /// # Returns
824 ///
825 /// A new `Expr::Literal` variant with `LiteralType::Char`.
826 pub fn new_char(token: Token, value: char) -> Self {
827 Expr::Literal(Literal {
828 token,
829 value: LiteralType::Char(value),
830 })
831 }
832
833 /// Creates a new parenthesized expression.
834 ///
835 /// # Arguments
836 ///
837 /// * `expr` - The expression to be parenthesized.
838 ///
839 /// # Returns
840 ///
841 /// A new `Expr::Parenthesized` variant.
842 pub fn new_parenthesized(expr: Expr) -> Self {
843 Expr::Parenthesized(Parenthesized {
844 expr: Box::new(expr),
845 })
846 }
847
848 /// Creates a new vector expression.
849 ///
850 /// # Arguments
851 ///
852 /// * `exprs` - The list of expressions in the vector.
853 ///
854 /// # Returns
855 ///
856 /// A new `Expr::Vec` variant.
857 pub fn new_vec(exprs: Vec<Expr>) -> Self {
858 Expr::Vec(VecExpr { exprs })
859 }
860
861 /// Creates a new struct constructor expression.
862 ///
863 /// # Arguments
864 /// * `name` - The name of the struct being constructed.
865 /// * `fields` - The field values for the struct.
866 /// * `token` - The token representing the struct constructor.
867 ///
868 /// # Returns
869 ///
870 /// A new `Expr::StructConstructor` variant.
871 pub fn new_struct_constructor(name: String, fields: Vec<(String, Expr)>, token: Token) -> Self {
872 Expr::StructConstructor(StructConstructor {
873 name,
874 fields,
875 token,
876 })
877 }
878
879 /// Creates a new static method access expression.
880 ///
881 /// # Arguments
882 /// * `base` - The base expression being accessed.
883 /// * `method` - The method expression.
884 /// * `token` - The token representing the '::' operator.
885 ///
886 /// # Returns
887 ///
888 /// A new `Expr::Access` variant with `AccessKind::StaticMethod`.
889 pub fn new_static_method_access(base: Expr, method: Expr, token: Token) -> Self {
890 Expr::Access(AccessExpr {
891 base: Box::new(base),
892 access: AccessKind::StaticMethod(Box::new(method)),
893 token,
894 })
895 }
896
897 /// Creates a new object expression.
898 ///
899 /// # Arguments
900 /// * `fields` - The key-value pairs in the object.
901 /// * `braces` - The tokens representing the opening and closing braces.
902 ///
903 /// # Returns
904 ///
905 /// A new `Expr::Object` variant.
906 pub fn new_object(fields: IndexMap<String, Expr>, braces: (Token, Token)) -> Self {
907 Expr::Object(ObjectExpr { fields, braces })
908 }
909}