Skip to main content

oak_valkyrie/ast/
expression_nodes.rs

1use super::{Identifier, Item, LoopKind, MatchArm, NamePath, Param, Pattern, Span, StringLiteral, Type};
2
3/// An expression
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub enum Expr {
7    /// An identifier expression.
8    Ident(Identifier),
9    /// A name path expression (e.g., `std::collections::HashMap`).
10    Path(NamePath),
11    /// A string literal expression.
12    StringLiteral(StringLiteral),
13    /// A boolean literal expression.
14    Bool {
15        /// The boolean value.
16        value: bool,
17        /// The source code span.
18        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
19        span: Span,
20    },
21    /// A binary operation expression.
22    Binary {
23        /// The left operand.
24        left: Box<Expr>,
25        /// The binary operator.
26        op: crate::lexer::token_type::ValkyrieTokenType,
27        /// The right operand.
28        right: Box<Expr>,
29        /// The source code span.
30        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
31        span: Span,
32    },
33    /// A unary operation expression.
34    Unary {
35        /// The unary operator.
36        op: crate::lexer::token_type::ValkyrieTokenType,
37        /// The operand expression.
38        expr: Box<Expr>,
39        /// The source code span.
40        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
41        span: Span,
42    },
43    /// A function call expression.
44    Call {
45        /// The callee expression.
46        callee: Box<Expr>,
47        /// The call arguments.
48        args: Vec<Expr>,
49        /// The source code span.
50        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
51        span: Span,
52    },
53    /// A field access expression.
54    Field {
55        /// The receiver expression.
56        receiver: Box<Expr>,
57        /// The field name.
58        field: Identifier,
59        /// The source code span.
60        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
61        span: Span,
62    },
63    /// An index expression.
64    Index {
65        /// The receiver expression.
66        receiver: Box<Expr>,
67        /// The index expression.
68        index: Box<Expr>,
69        /// The source code span.
70        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
71        span: Span,
72    },
73    /// An offset expression (pointer arithmetic).
74    Offset {
75        /// The receiver expression.
76        receiver: Box<Expr>,
77        /// The offset expression.
78        offset: Box<Expr>,
79        /// The source code span.
80        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
81        span: Span,
82    },
83    /// A parenthesized expression.
84    Paren {
85        /// The inner expression.
86        expr: Box<Expr>,
87        /// The source code span.
88        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
89        span: Span,
90    },
91    /// A block expression.
92    Block(Block),
93    /// A lambda expression.
94    Lambda(LambdaExpr),
95    /// An object expression.
96    ///
97    /// Creates a new object instance with specified field values.
98    ///
99    /// ```v
100    /// let p = Point { x: 10, y: 20 }
101    /// let shorthand = Point { x, y }  // shorthand syntax
102    /// ```
103    Object {
104        /// The callee expression.
105        callee: Box<Expr>,
106        /// The field-value pairs. None for shorthand syntax.
107        fields: Vec<(Identifier, Option<Expr>)>,
108        /// The source code span.
109        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
110        span: Span,
111    },
112    /// Anonymous class expression.
113    ///
114    /// ```v
115    /// let obj = class { x: 10, y: 20 }
116    /// let impl_trait = class: Trait { ... }
117    /// ```
118    AnonymousClass {
119        /// Parent traits or classes to implement/extend.
120        parents: Vec<String>,
121        /// Fields and methods defined in the anonymous class.
122        items: Vec<Item>,
123        /// Variables captured from the enclosing scope.
124        captures: Vec<Identifier>,
125        /// Source span.
126        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
127        span: Span,
128    },
129    /// An if expression.
130    If {
131        /// Optional pattern for pattern-matching the condition.
132        pattern: Option<Pattern>,
133        /// The condition expression.
134        condition: Box<Expr>,
135        /// The then branch block.
136        then_branch: Block,
137        /// The optional else branch block.
138        else_branch: Option<Block>,
139        /// The source code span.
140        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
141        span: Span,
142    },
143    /// A match expression.
144    Match {
145        /// The expression being matched.
146        scrutinee: Box<Expr>,
147        /// The match arms.
148        arms: Vec<MatchArm>,
149        /// The source code span.
150        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
151        span: Span,
152    },
153    /// A loop expression.
154    Loop {
155        /// The loop keyword kind.
156        kind: LoopKind,
157        /// Optional label for the loop.
158        label: Option<String>,
159        /// Optional pattern for loop variable binding.
160        pattern: Option<Pattern>,
161        /// Optional condition for conditional loops.
162        condition: Option<Box<Expr>>,
163        /// The loop body.
164        body: Block,
165        /// The source code span.
166        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
167        span: Span,
168    },
169    /// A return expression.
170    Return {
171        /// The optional return value expression.
172        expr: Option<Box<Expr>>,
173        /// The source code span.
174        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
175        span: Span,
176    },
177    /// A break expression.
178    Break {
179        /// Optional label of the loop to break from.
180        label: Option<String>,
181        /// Optional value to break with.
182        expr: Option<Box<Expr>>,
183        /// The source code span.
184        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
185        span: Span,
186    },
187    /// A continue expression.
188    Continue {
189        /// Optional label of the loop to continue.
190        label: Option<String>,
191        /// The source code span.
192        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
193        span: Span,
194    },
195    /// A yield expression.
196    Yield {
197        /// The optional value to yield.
198        expr: Option<Box<Expr>>,
199        /// Whether this is a yield from expression.
200        yield_from: bool,
201        /// The source code span.
202        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
203        span: Span,
204    },
205    /// A raise (throw) expression.
206    Raise {
207        /// The expression to raise.
208        expr: Box<Expr>,
209        /// The source code span.
210        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
211        span: Span,
212    },
213    /// A resume expression.
214    ///
215    /// Resumes execution from an effect handler with a value.
216    /// Only valid inside a catch block.
217    ///
218    /// ```v
219    /// catch process() {
220    ///     case Read { prompt }: resume "input data"
221    /// }
222    /// ```
223    Resume {
224        /// The value to resume with.
225        expr: Box<Expr>,
226        /// The source code span.
227        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
228        span: Span,
229    },
230    /// A catch (try-catch) expression.
231    Catch {
232        /// The expression to try.
233        expr: Box<Expr>,
234        /// The catch arms.
235        arms: Vec<MatchArm>,
236        /// The source code span.
237        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
238        span: Span,
239    },
240    /// With expression for functional record updates.
241    ///
242    /// Creates a new record by copying an existing one and updating specified fields.
243    ///
244    /// ```v
245    /// let p2 = p1.with { x: 20.0, y: 30.0 }
246    /// let updated = config.with { timeout: 60 }
247    /// ```
248    With {
249        /// The base expression to copy from.
250        base: Box<Expr>,
251        /// Field updates to apply.
252        updates: Vec<(Identifier, Expr)>,
253        /// Source span.
254        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
255        span: Span,
256    },
257    /// Super call expression for constructor chaining.
258    ///
259    /// Represents a call to a parent class constructor within a subclass constructor.
260    ///
261    /// ```v
262    /// class Derived(Base) {
263    ///     initiate(mut self, x: i32, y: i32) {
264    ///         super.initiate(x)  // Call parent constructor
265    ///         self.y = y
266    ///     }
267    /// }
268    /// ```
269    SuperCall {
270        /// Optional parent alias for renamed inheritance.
271        ///
272        /// In renamed inheritance, specifies which parent to call:
273        /// ```v
274        /// class Child(primary: ParentA, secondary: ParentB) {
275        ///     initiate(mut self) {
276        ///         super.primary.initiate()  // alias: "primary"
277        ///     }
278        /// }
279        /// ```
280        parent_alias: Option<Identifier>,
281        /// The method name to call (usually "initiate").
282        method: Identifier,
283        /// Arguments passed to the parent constructor.
284        args: Vec<Expr>,
285        /// Source span.
286        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
287        span: Span,
288    },
289}
290
291/// A block of statements
292#[derive(Debug, Clone, PartialEq, Eq, Hash)]
293#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
294pub struct Block {
295    /// The statements in the block.
296    pub statements: Vec<super::Statement>,
297    /// The source code span.
298    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
299    pub span: Span,
300}
301
302/// A lambda expression
303#[derive(Debug, Clone, PartialEq, Eq, Hash)]
304#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
305pub struct LambdaExpr {
306    /// The lambda parameters.
307    pub params: Vec<Param>,
308    /// Optional return type annotation.
309    pub return_type: Option<Type>,
310    /// The lambda body.
311    pub body: Block,
312    /// The source code span.
313    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
314    pub span: Span,
315}