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