oak_python/ast/mod.rs
1#![doc = include_str!("readme.md")]
2use core::range::Range;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// Root node of a Python source file.
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[derive(Debug, Clone, PartialEq)]
9pub struct PythonRoot {
10 /// The program structure
11 pub program: Program,
12 /// Source code span
13 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
14 pub span: Range<usize>,
15}
16
17/// A Python program consisting of a list of statements.
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19#[derive(Debug, Clone, PartialEq)]
20pub struct Program {
21 /// List of statements in the program
22 pub statements: Vec<Statement>,
23}
24
25/// Represents a Python statement.
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27#[derive(Debug, Clone, PartialEq)]
28pub enum Statement {
29 /// Function definition
30 FunctionDef {
31 /// Decorators applied to the function
32 decorators: Vec<Expression>,
33 /// Function name
34 name: String,
35 /// List of parameters
36 parameters: Vec<Parameter>,
37 /// Optional return type annotation
38 return_type: Option<Type>,
39 /// Function body
40 body: Vec<Statement>,
41 },
42 /// Async function definition
43 AsyncFunctionDef {
44 /// Decorators applied to the function
45 decorators: Vec<Expression>,
46 /// Function name
47 name: String,
48 /// List of parameters
49 parameters: Vec<Parameter>,
50 /// Optional return type annotation
51 return_type: Option<Type>,
52 /// Function body
53 body: Vec<Statement>,
54 },
55 /// Class definition
56 ClassDef {
57 /// Decorators applied to the class
58 decorators: Vec<Expression>,
59 /// Class name
60 name: String,
61 /// Base classes
62 bases: Vec<Expression>,
63 /// Class body
64 body: Vec<Statement>,
65 },
66 /// Variable assignment
67 Assignment {
68 /// Target expression
69 target: Expression,
70 /// Value expression
71 value: Expression,
72 },
73 /// Augmented assignment (e.g., `+=`, `-=`)
74 AugmentedAssignment {
75 /// Target expression
76 target: Expression,
77 /// Augmented operator
78 operator: AugmentedOperator,
79 /// Value expression
80 value: Expression,
81 },
82 /// Expression statement
83 Expression(Expression),
84 /// Return statement
85 Return(Option<Expression>),
86 /// If statement
87 If {
88 /// Test expression
89 test: Expression,
90 /// Body of the if block
91 body: Vec<Statement>,
92 /// Else block (or empty)
93 orelse: Vec<Statement>,
94 },
95 /// For loop
96 For {
97 /// Loop target
98 target: Expression,
99 /// Iterable expression
100 iter: Expression,
101 /// Loop body
102 body: Vec<Statement>,
103 /// Else block (or empty)
104 orelse: Vec<Statement>,
105 },
106 /// Async for loop
107 AsyncFor {
108 /// Loop target
109 target: Expression,
110 /// Iterable expression
111 iter: Expression,
112 /// Loop body
113 body: Vec<Statement>,
114 /// Else block (or empty)
115 orelse: Vec<Statement>,
116 },
117 /// While loop
118 While {
119 /// Test expression
120 test: Expression,
121 /// Loop body
122 body: Vec<Statement>,
123 /// Else block (or empty)
124 orelse: Vec<Statement>,
125 },
126 /// Break statement
127 Break,
128 /// Continue statement
129 Continue,
130 /// Pass statement
131 Pass,
132 /// Import statement
133 Import {
134 /// List of names being imported
135 names: Vec<ImportName>,
136 },
137 /// From-import statement
138 ImportFrom {
139 /// Optional module name
140 module: Option<String>,
141 /// List of names being imported
142 names: Vec<ImportName>,
143 },
144 /// Global statement
145 Global {
146 /// List of global names
147 names: Vec<String>,
148 },
149 /// Nonlocal statement
150 Nonlocal {
151 /// List of nonlocal names
152 names: Vec<String>,
153 },
154 /// Try statement
155 Try {
156 /// Try body
157 body: Vec<Statement>,
158 /// Exception handlers
159 handlers: Vec<ExceptHandler>,
160 /// Else block
161 orelse: Vec<Statement>,
162 /// Finally block
163 finalbody: Vec<Statement>,
164 },
165 /// Raise statement
166 Raise {
167 /// Optional exception
168 exc: Option<Expression>,
169 /// Optional cause
170 cause: Option<Expression>,
171 },
172 /// With statement
173 With {
174 /// With items
175 items: Vec<WithItem>,
176 /// With body
177 body: Vec<Statement>,
178 },
179 /// Async with statement
180 AsyncWith {
181 /// With items
182 items: Vec<WithItem>,
183 /// With body
184 body: Vec<Statement>,
185 },
186 /// Assert statement
187 Assert {
188 /// Test expression
189 test: Expression,
190 /// Optional error message
191 msg: Option<Expression>,
192 },
193 /// Match statement
194 Match {
195 /// Subject expression
196 subject: Expression,
197 /// Match cases
198 cases: Vec<MatchCase>,
199 },
200}
201
202/// Represents a case in a match statement.
203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
204#[derive(Debug, Clone, PartialEq)]
205pub struct MatchCase {
206 /// Pattern to match
207 pub pattern: Pattern,
208 /// Optional guard expression
209 pub guard: Option<Expression>,
210 /// Case body
211 pub body: Vec<Statement>,
212}
213
214/// Represents a pattern in a match case.
215#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
216#[derive(Debug, Clone, PartialEq)]
217pub enum Pattern {
218 /// Value pattern
219 Value(Expression),
220 /// Wildcard pattern
221 Wildcard,
222 /// As pattern
223 As {
224 /// Optional sub-pattern
225 pattern: Option<Box<Pattern>>,
226 /// Target name
227 name: String,
228 },
229 /// Sequence pattern
230 Sequence(Vec<Pattern>),
231 /// Mapping pattern
232 Mapping {
233 /// Keys to match
234 keys: Vec<Expression>,
235 /// Corresponding patterns
236 patterns: Vec<Pattern>,
237 },
238 /// Class pattern
239 Class {
240 /// Class expression
241 cls: Expression,
242 /// Positional patterns
243 patterns: Vec<Pattern>,
244 /// Keyword names
245 keywords: Vec<String>,
246 /// Keyword patterns
247 keyword_patterns: Vec<Pattern>,
248 },
249 /// Or pattern
250 Or(Vec<Pattern>),
251}
252
253/// Represents a Python expression.
254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255#[derive(Debug, Clone, PartialEq)]
256pub enum Expression {
257 /// Literal value
258 Literal(Literal),
259 /// Identifier name
260 Name(String),
261 /// Binary operation
262 BinaryOp {
263 /// Left operand
264 left: Box<Expression>,
265 /// Binary operator
266 operator: BinaryOperator,
267 /// Right operand
268 right: Box<Expression>,
269 },
270 /// Unary operation
271 UnaryOp {
272 /// Unary operator
273 operator: UnaryOperator,
274 /// Operand
275 operand: Box<Expression>,
276 },
277 /// Boolean operation (and, or)
278 BoolOp {
279 /// Boolean operator
280 operator: BoolOperator,
281 /// List of values
282 values: Vec<Expression>,
283 },
284 /// Comparison operation
285 Compare {
286 /// Leftmost operand
287 left: Box<Expression>,
288 /// Comparison operators
289 ops: Vec<CompareOperator>,
290 /// Subsequent operands
291 comparators: Vec<Expression>,
292 },
293 /// Function call
294 Call {
295 /// Function being called
296 func: Box<Expression>,
297 /// Positional arguments
298 args: Vec<Expression>,
299 /// Keyword arguments
300 keywords: Vec<Keyword>,
301 },
302 /// Attribute access
303 Attribute {
304 /// Base expression
305 value: Box<Expression>,
306 /// Attribute name
307 attr: String,
308 },
309 /// Subscript access
310 Subscript {
311 /// Base expression
312 value: Box<Expression>,
313 /// Slice or index expression
314 slice: Box<Expression>,
315 },
316 /// List literal
317 List {
318 /// List elements
319 elts: Vec<Expression>,
320 },
321 /// Tuple literal
322 Tuple {
323 /// Tuple elements
324 elts: Vec<Expression>,
325 },
326 /// Slice expression
327 Slice {
328 /// Optional lower bound
329 lower: Option<Box<Expression>>,
330 /// Optional upper bound
331 upper: Option<Box<Expression>>,
332 /// Optional step
333 step: Option<Box<Expression>>,
334 },
335 /// Dictionary literal
336 Dict {
337 /// Optional keys
338 keys: Vec<Option<Expression>>,
339 /// Values
340 values: Vec<Expression>,
341 },
342 /// Set literal
343 Set {
344 /// Set elements
345 elts: Vec<Expression>,
346 },
347 /// List comprehension
348 ListComp {
349 /// Result expression
350 elt: Box<Expression>,
351 /// Generators
352 generators: Vec<Comprehension>,
353 },
354 /// Dictionary comprehension
355 DictComp {
356 /// Key expression
357 key: Box<Expression>,
358 /// Value expression
359 value: Box<Expression>,
360 /// Generators
361 generators: Vec<Comprehension>,
362 },
363 /// Set comprehension
364 SetComp {
365 /// Result expression
366 elt: Box<Expression>,
367 /// Generators
368 generators: Vec<Comprehension>,
369 },
370 /// Generator expression
371 GeneratorExp {
372 /// Result expression
373 elt: Box<Expression>,
374 /// Generators
375 generators: Vec<Comprehension>,
376 },
377 /// Lambda expression
378 Lambda {
379 /// Lambda arguments
380 args: Vec<Parameter>,
381 /// Lambda body
382 body: Box<Expression>,
383 },
384 /// Conditional expression (ternary operator)
385 IfExp {
386 /// Test expression
387 test: Box<Expression>,
388 /// Body expression
389 body: Box<Expression>,
390 /// Else expression
391 orelse: Box<Expression>,
392 },
393 /// f-string
394 JoinedStr {
395 /// f-string parts
396 values: Vec<Expression>,
397 },
398 /// Formatted value within an f-string
399 FormattedValue {
400 /// Value to format
401 value: Box<Expression>,
402 /// Conversion type
403 conversion: usize,
404 /// Optional format specification
405 format_spec: Option<Box<Expression>>,
406 },
407 /// Yield expression
408 Yield(Option<Box<Expression>>),
409 /// Yield from expression
410 YieldFrom(Box<Expression>),
411 /// Await expression
412 Await(Box<Expression>),
413 /// Starred expression (*args, **kwargs)
414 Starred {
415 /// Value being starred
416 value: Box<Expression>,
417 /// Whether it's a double star (**kwargs)
418 is_double: bool,
419 },
420}
421
422/// Represents a literal value.
423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
424#[derive(Debug, Clone, PartialEq)]
425pub enum Literal {
426 /// Integer literal
427 Integer(i64),
428 /// Float literal
429 Float(f64),
430 /// String literal
431 String(String),
432 /// Bytes literal
433 Bytes(Vec<u8>),
434 /// Boolean literal
435 Boolean(bool),
436 /// None literal
437 None,
438}
439
440/// Represents binary operators.
441#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
442#[derive(Debug, Clone, PartialEq)]
443pub enum BinaryOperator {
444 /// `+`
445 Add,
446 /// `-`
447 Sub,
448 /// `*`
449 Mult,
450 /// `/`
451 Div,
452 /// `//`
453 FloorDiv,
454 /// `%`
455 Mod,
456 /// `**`
457 Pow,
458 /// `<<`
459 LShift,
460 /// `>>`
461 RShift,
462 /// `|`
463 BitOr,
464 /// `^`
465 BitXor,
466 /// `&`
467 BitAnd,
468}
469
470/// Represents unary operators.
471#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
472#[derive(Debug, Clone, PartialEq)]
473pub enum UnaryOperator {
474 /// `~`
475 Invert,
476 /// `not`
477 Not,
478 /// `+`
479 UAdd,
480 /// `-`
481 USub,
482}
483
484/// Represents boolean operators.
485#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
486#[derive(Debug, Clone, PartialEq)]
487pub enum BoolOperator {
488 /// `and`
489 And,
490 /// `or`
491 Or,
492}
493
494/// Represents comparison operators.
495#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
496#[derive(Debug, Clone, PartialEq)]
497pub enum CompareOperator {
498 /// `==`
499 Eq,
500 /// `!=`
501 NotEq,
502 /// `<`
503 Lt,
504 /// `<=`
505 LtE,
506 /// `>`
507 Gt,
508 /// `>=`
509 GtE,
510 /// `is`
511 Is,
512 /// `is not`
513 IsNot,
514 /// `in`
515 In,
516 /// `not in`
517 NotIn,
518}
519
520/// Represents augmented assignment operators.
521#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
522#[derive(Debug, Clone, PartialEq)]
523pub enum AugmentedOperator {
524 /// `+=`
525 Add,
526 /// `-=`
527 Sub,
528 /// `*=`
529 Mult,
530 /// `/=`
531 Div,
532 /// `//= `
533 FloorDiv,
534 /// `%=`
535 Mod,
536 /// `**=`
537 Pow,
538 /// `<<=`
539 LShift,
540 /// `>>=`
541 RShift,
542 /// `|=`
543 BitOr,
544 /// `^=`
545 BitXor,
546 /// `&=`
547 BitAnd,
548}
549
550/// Represents a function parameter.
551#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
552#[derive(Debug, Clone, PartialEq)]
553pub struct Parameter {
554 /// Parameter name
555 pub name: String,
556 /// Optional type annotation
557 pub annotation: Option<Type>,
558 /// Optional default value
559 pub default: Option<Expression>,
560 /// Whether it's a variable positional argument (*args)
561 pub is_vararg: bool,
562 /// Whether it's a variable keyword argument (**kwargs)
563 pub is_kwarg: bool,
564}
565
566/// Represents a type annotation.
567#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
568#[derive(Debug, Clone, PartialEq)]
569pub enum Type {
570 /// Basic type name
571 Name(String),
572 /// Generic type
573 Generic {
574 /// Type name
575 name: String,
576 /// Type arguments
577 args: Vec<Type>,
578 },
579 /// Union type
580 Union(Vec<Type>),
581 /// Optional type
582 Optional(Box<Type>),
583}
584
585/// Represents a keyword argument.
586#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
587#[derive(Debug, Clone, PartialEq)]
588pub struct Keyword {
589 /// Optional argument name
590 pub arg: Option<String>,
591 /// Argument value
592 pub value: Expression,
593}
594
595/// Represents a comprehension in a list/dict/set/generator.
596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
597#[derive(Debug, Clone, PartialEq)]
598pub struct Comprehension {
599 /// Target expression
600 pub target: Expression,
601 /// Iterable expression
602 pub iter: Expression,
603 /// Optional conditions
604 pub ifs: Vec<Expression>,
605 /// Whether it's an async comprehension
606 pub is_async: bool,
607}
608
609/// Represents a name in an import statement.
610#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
611#[derive(Debug, Clone, PartialEq)]
612pub struct ImportName {
613 /// Name being imported
614 pub name: String,
615 /// Optional alias (asname)
616 pub asname: Option<String>,
617}
618
619/// Represents an exception handler in a try statement.
620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
621#[derive(Debug, Clone, PartialEq)]
622pub struct ExceptHandler {
623 /// Optional exception type
624 pub type_: Option<Expression>,
625 /// Optional name for the exception instance
626 pub name: Option<String>,
627 /// Handler body
628 pub body: Vec<Statement>,
629}
630
631/// Represents an item in a with statement.
632#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
633#[derive(Debug, Clone, PartialEq)]
634pub struct WithItem {
635 /// Context manager expression
636 pub context_expr: Expression,
637 /// Optional variables to bind to
638 pub optional_vars: Option<Expression>,
639}
640
641impl Program {
642 /// Creates a new empty program.
643 pub fn new() -> Self {
644 Self { statements: Vec::new() }
645 }
646
647 /// Adds a statement to the program.
648 pub fn add_statement(&mut self, statement: Statement) {
649 self.statements.push(statement)
650 }
651}
652
653impl Default for Program {
654 /// Returns a default empty program.
655 fn default() -> Self {
656 Self::new()
657 }
658}
659
660impl Expression {
661 /// Creates a name expression.
662 pub fn name(name: impl Into<String>) -> Self {
663 Self::Name(name.into())
664 }
665
666 /// Creates a string literal expression.
667 pub fn string(value: impl Into<String>) -> Self {
668 Self::Literal(Literal::String(value.into()))
669 }
670
671 /// Creates an integer literal expression.
672 pub fn integer(value: i64) -> Self {
673 Self::Literal(Literal::Integer(value))
674 }
675
676 /// Creates a float literal expression.
677 pub fn float(value: f64) -> Self {
678 Self::Literal(Literal::Float(value))
679 }
680
681 /// Creates a boolean literal expression.
682 pub fn boolean(value: bool) -> Self {
683 Self::Literal(Literal::Boolean(value))
684 }
685
686 /// Creates a None literal expression.
687 pub fn none() -> Self {
688 Self::Literal(Literal::None)
689 }
690}
691
692impl Statement {
693 /// Creates a function definition statement.
694 pub fn function_def(name: impl Into<String>, parameters: Vec<Parameter>, return_type: Option<Type>, body: Vec<Statement>) -> Self {
695 Self::FunctionDef { decorators: Vec::new(), name: name.into(), parameters, return_type, body }
696 }
697
698 /// Creates an assignment statement.
699 pub fn assignment(target: Expression, value: Expression) -> Self {
700 Self::Assignment { target, value }
701 }
702
703 /// Creates an expression statement.
704 pub fn expression(expr: Expression) -> Self {
705 Self::Expression(expr)
706 }
707
708 /// Creates a return statement.
709 pub fn return_stmt(value: Option<Expression>) -> Self {
710 Self::Return(value)
711 }
712}