oak_valkyrie/ast/mod.rs
1#[doc = include_str!("readme.md")]
2use crate::kind::ValkyrieSyntaxKind;
3use core::range::Range;
4use serde::{self, Deserialize, Serialize};
5
6/// Represents an identifier in Valkyrie source code.
7///
8/// Identifiers are names used for variables, functions, types, and other named entities.
9/// Each identifier carries its textual representation and source location information.
10///
11/// # Examples
12///
13/// ```rust
14/// #![feature(new_range_api)]
15/// use core::range::Range;
16/// use oak_valkyrie::ast::Identifier;
17///
18/// let ident = Identifier { name: "main".to_string(), span: (0..4).into() };
19/// assert_eq!(ident.name, "main");
20/// ```
21#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
22pub struct Identifier {
23 /// The textual name of the identifier
24 pub name: String,
25 /// Source code span where this identifier appears
26 #[serde(with = "oak_core::serde_range")]
27 pub span: Range<usize>,
28}
29
30/// Strongly-typed AST root node representing the entire Valkyrie source file.
31///
32/// This is the top-level structure that contains all items (functions, statements, etc.)
33/// parsed from a Valkyrie source file.
34#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
35pub struct ValkyrieRoot {
36 /// Collection of top-level items in the Valkyrie file
37 pub items: Vec<Item>,
38}
39
40/// Top-level items that can appear in a Valkyrie source file.
41///
42/// These represent the main constructs that can exist at the module level,
43/// such as function definitions and statements.
44#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
45pub enum Item {
46 /// A standalone statement
47 Statement(Statement),
48 /// A namespace definition
49 Namespace(Namespace),
50 /// A class definition
51 Class(Class),
52 /// A widget definition
53 Widget(Widget),
54 /// A type function definition
55 TypeFunction(TypeFunction),
56 /// A micro definition
57 Micro(MicroDefinition),
58}
59
60/// Represents a type function definition (mezzo) in Valkyrie source code.
61#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
62pub struct TypeFunction {
63 /// The name identifier of the type function
64 pub name: Identifier,
65 /// Parameters of the type function
66 pub params: Vec<Param>,
67 /// The body of the type function
68 pub body: Block,
69 /// Source code span where this type function appears
70 #[serde(with = "oak_core::serde_range")]
71 pub span: Range<usize>,
72}
73
74/// Represents a class definition in Valkyrie source code.
75#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
76pub struct Class {
77 /// The name identifier of the class
78 pub name: Identifier,
79 /// List of items within the class
80 pub items: Vec<Item>,
81 /// Source code span where this class appears
82 #[serde(with = "oak_core::serde_range")]
83 pub span: Range<usize>,
84}
85
86/// Represents a widget definition in Valkyrie source code.
87#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
88pub struct Widget {
89 /// The name identifier of the widget
90 pub name: Identifier,
91 /// List of items within the widget
92 pub items: Vec<Item>,
93 /// Source code span where this widget appears
94 #[serde(with = "oak_core::serde_range")]
95 pub span: Range<usize>,
96}
97
98/// Represents a namespace definition in Valkyrie source code.
99///
100/// Namespaces are used to organize code and prevent naming conflicts.
101#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
102pub struct Namespace {
103 /// The name identifier of the namespace
104 pub name: Identifier,
105 /// List of items within the namespace
106 pub items: Vec<Item>,
107 /// Source code span where this namespace appears
108 #[serde(with = "oak_core::serde_range")]
109 pub span: Range<usize>,
110}
111
112/// Represents a micro definition in Valkyrie source code.
113///
114/// Micro definitions are specialized constructs in the Valkyrie language.
115#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
116pub struct MicroDefinition {
117 /// The name identifier of the micro definition
118 pub name: Identifier,
119 /// List of function parameters
120 pub params: Vec<Param>,
121 /// The optional return type of the function
122 pub return_type: Option<String>,
123 /// The function body containing executable statements
124 pub body: Block,
125 /// Source code span where this micro definition appears
126 #[serde(with = "oak_core::serde_range")]
127 pub span: Range<usize>,
128}
129
130/// Represents a function parameter with its type annotation.
131///
132/// Parameters define the inputs that a function can accept, with their respective types.
133#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
134pub struct Param {
135 /// The parameter name identifier
136 pub name: Identifier,
137 /// The type annotation for this parameter
138 pub ty: String,
139 /// Source code span where this parameter appears
140 #[serde(with = "oak_core::serde_range")]
141 pub span: Range<usize>,
142}
143
144/// Represents a block of statements enclosed in braces.
145///
146/// Blocks are fundamental control structures in Valkyrie that group statements together.
147/// They create new scopes and can be used as expressions.
148#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
149pub struct Block {
150 /// Collection of statements within the block
151 pub statements: Vec<Statement>,
152 /// Source code span where this block appears
153 #[serde(with = "oak_core::serde_range")]
154 pub span: Range<usize>,
155}
156
157/// Represents different types of statements in Valkyrie source code.
158///
159/// Statements are executable instructions that don't return values.
160/// They form the body of functions and other code blocks.
161#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
162pub enum Statement {
163 /// A variable binding statement with `let` keyword
164 ///
165 /// Contains the variable name, initialization expression, and source location
166 Let {
167 /// Whether the variable is mutable
168 is_mutable: bool,
169 /// The variable name identifier
170 name: Identifier,
171 /// The initialization expression
172 expr: Expr,
173 /// Source code span where this statement appears
174 #[serde(with = "oak_core::serde_range")]
175 span: Range<usize>,
176 },
177 /// An expression statement that may end with a semicolon
178 ///
179 /// Contains the expression, whether it ends with semicolon, and source location
180 ExprStmt {
181 /// The expression being evaluated
182 expr: Expr,
183 /// Whether this statement ends with a semicolon
184 semi: bool,
185 /// Source code span where this statement appears
186 #[serde(with = "oak_core::serde_range")]
187 span: Range<usize>,
188 },
189}
190
191/// Represents different types of expressions in Valkyrie source code.
192///
193/// Expressions are code constructs that evaluate to values. They can be simple
194/// like identifiers and literals, or complex like function calls and binary operations.
195#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
196pub enum Expr {
197 /// An identifier that refers to a variable, function, or other named entity
198 Ident(Identifier),
199 /// A string or numeric literal value
200 ///
201 /// Contains the literal value as a string and its source location
202 Literal {
203 /// The string representation of the literal value
204 value: String,
205 /// Source code span where this literal appears
206 #[serde(with = "oak_core::serde_range")]
207 span: Range<usize>,
208 },
209 /// A boolean literal (true or false)
210 ///
211 /// Contains the boolean value and its source location
212 Bool {
213 /// The boolean value
214 value: bool,
215 /// Source code span where this boolean appears
216 #[serde(with = "oak_core::serde_range")]
217 span: Range<usize>,
218 },
219 /// A unary operation expression (e.g., !x, -y)
220 ///
221 /// Contains the operator, operand expression, and source location
222 Unary {
223 /// The unary operator kind
224 op: ValkyrieSyntaxKind,
225 /// The operand expression
226 expr: Box<Expr>,
227 /// Source code span where this unary expression appears
228 #[serde(with = "oak_core::serde_range")]
229 span: Range<usize>,
230 },
231 /// A binary operation expression (e.g., x + y, a == b)
232 ///
233 /// Contains the left operand, operator, right operand, and source location
234 Binary {
235 /// The left operand expression
236 left: Box<Expr>,
237 /// The binary operator kind
238 op: ValkyrieSyntaxKind,
239 /// The right operand expression
240 right: Box<Expr>,
241 /// Source code span where this binary expression appears
242 #[serde(with = "oak_core::serde_range")]
243 span: Range<usize>,
244 },
245 /// A function call expression
246 ///
247 /// Contains the function being called, argument expressions, and source location
248 Call {
249 /// The expression that evaluates to the function being called
250 callee: Box<Expr>,
251 /// List of argument expressions
252 args: Vec<Expr>,
253 /// Source code span where this function call appears
254 #[serde(with = "oak_core::serde_range")]
255 span: Range<usize>,
256 },
257 /// A field access expression (e.g., obj.field)
258 ///
259 /// Contains the object expression, field name, and source location
260 Field {
261 /// The expression that evaluates to the object containing the field
262 receiver: Box<Expr>,
263 /// The field name identifier
264 field: Identifier,
265 /// Source code span where this field access appears
266 #[serde(with = "oak_core::serde_range")]
267 span: Range<usize>,
268 },
269 /// An array/slice indexing expression (e.g., arr[i])
270 ///
271 /// Contains the array expression, index expression, and source location
272 Index {
273 /// The expression that evaluates to the array or slice
274 receiver: Box<Expr>,
275 /// The index expression
276 index: Box<Expr>,
277 /// Source code span where this indexing expression appears
278 #[serde(with = "oak_core::serde_range")]
279 span: Range<usize>,
280 },
281 /// A parenthesized expression
282 ///
283 /// Contains the wrapped expression and source location
284 Paren {
285 /// The expression wrapped in parentheses
286 expr: Box<Expr>,
287 /// Source code span where this parenthesized expression appears
288 #[serde(with = "oak_core::serde_range")]
289 span: Range<usize>,
290 },
291 /// A block expression that can be used as a value
292 Block(Block),
293 /// An anonymous class definition
294 AnonymousClass {
295 /// List of parent types/traits
296 parents: Vec<String>,
297 /// List of fields and methods
298 items: Vec<Item>,
299 /// Source code span where this anonymous class appears
300 #[serde(with = "oak_core::serde_range")]
301 span: Range<usize>,
302 },
303 /// An if-else expression
304 If {
305 /// The condition expression
306 condition: Box<Expr>,
307 /// The then-branch block
308 then_branch: Block,
309 /// The optional else-branch block
310 else_branch: Option<Block>,
311 /// Source code span where this if expression appears
312 #[serde(with = "oak_core::serde_range")]
313 span: Range<usize>,
314 },
315 /// A match expression
316 Match {
317 /// The expression being matched
318 scrutinee: Box<Expr>,
319 /// List of match arms
320 arms: Vec<MatchArm>,
321 /// Source code span where this match expression appears
322 #[serde(with = "oak_core::serde_range")]
323 span: Range<usize>,
324 },
325 /// A loop expression
326 Loop {
327 /// Optional loop label
328 label: Option<String>,
329 /// The loop body block
330 body: Block,
331 /// Source code span where this loop expression appears
332 #[serde(with = "oak_core::serde_range")]
333 span: Range<usize>,
334 },
335 /// A return expression
336 Return {
337 /// The optional return value
338 expr: Option<Box<Expr>>,
339 /// Source code span where this return expression appears
340 #[serde(with = "oak_core::serde_range")]
341 span: Range<usize>,
342 },
343 /// A break expression
344 Break {
345 /// Optional break label
346 label: Option<String>,
347 /// Optional break value
348 expr: Option<Box<Expr>>,
349 /// Source code span where this break expression appears
350 #[serde(with = "oak_core::serde_range")]
351 span: Range<usize>,
352 },
353 /// A continue expression
354 Continue {
355 /// Optional continue label
356 label: Option<String>,
357 /// Source code span where this continue expression appears
358 #[serde(with = "oak_core::serde_range")]
359 span: Range<usize>,
360 },
361 /// A yield expression
362 Yield {
363 /// Optional yield value
364 expr: Option<Box<Expr>>,
365 /// Whether this is a yield-from expression
366 yield_from: bool,
367 /// Source code span where this yield expression appears
368 #[serde(with = "oak_core::serde_range")]
369 span: Range<usize>,
370 },
371 /// A raise/throw expression
372 Raise {
373 /// The exception expression to raise
374 expr: Box<Expr>,
375 /// Source code span where this raise expression appears
376 #[serde(with = "oak_core::serde_range")]
377 span: Range<usize>,
378 },
379 /// A catch expression
380 Catch {
381 /// The expression to try
382 expr: Box<Expr>,
383 /// List of catch arms
384 arms: Vec<MatchArm>,
385 /// Source code span where this catch expression appears
386 #[serde(with = "oak_core::serde_range")]
387 span: Range<usize>,
388 },
389 /// An object creation or trailing closure call (e.g., Point { x: 1 })
390 Object {
391 /// The name or expression being "called" with a block
392 callee: Box<Expr>,
393 /// The block contents
394 block: Block,
395 /// Source code span
396 #[serde(with = "oak_core::serde_range")]
397 span: Range<usize>,
398 },
399}
400
401/// Represents an arm in a match or catch expression.
402#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
403pub struct MatchArm {
404 /// The pattern to match
405 pub pattern: Pattern,
406 /// Optional guard expression
407 pub guard: Option<Expr>,
408 /// The body expression
409 pub body: Expr,
410 /// Source code span where this match arm appears
411 #[serde(with = "oak_core::serde_range")]
412 pub span: Range<usize>,
413}
414
415/// Represents different types of patterns in Valkyrie.
416#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
417pub enum Pattern {
418 /// A wildcard pattern (_)
419 Wildcard {
420 #[serde(with = "oak_core::serde_range")]
421 span: Range<usize>,
422 },
423 /// A variable pattern
424 Variable {
425 name: Identifier,
426 #[serde(with = "oak_core::serde_range")]
427 span: Range<usize>,
428 },
429 /// A literal pattern
430 Literal {
431 value: String,
432 #[serde(with = "oak_core::serde_range")]
433 span: Range<usize>,
434 },
435}