1#![doc = include_str!("readme.md")]
2use core::range::Range;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[derive(Debug, Clone, PartialEq)]
9pub struct PythonRoot {
10 pub program: Program,
12 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
14 pub span: Range<usize>,
15}
16
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[derive(Debug, Clone, PartialEq)]
20pub struct Program {
21 pub statements: Vec<Statement>,
23}
24
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27#[derive(Debug, Clone, PartialEq)]
28pub enum Statement {
29 FunctionDef {
31 decorators: Vec<Expression>,
33 name: String,
35 parameters: Vec<Parameter>,
37 return_type: Option<Type>,
39 body: Vec<Statement>,
41 },
42 AsyncFunctionDef {
44 decorators: Vec<Expression>,
46 name: String,
48 parameters: Vec<Parameter>,
50 return_type: Option<Type>,
52 body: Vec<Statement>,
54 },
55 ClassDef {
57 decorators: Vec<Expression>,
59 name: String,
61 bases: Vec<Expression>,
63 body: Vec<Statement>,
65 },
66 Assignment {
68 target: Expression,
70 value: Expression,
72 },
73 AugmentedAssignment {
75 target: Expression,
77 operator: AugmentedOperator,
79 value: Expression,
81 },
82 Expression(Expression),
84 Return(Option<Expression>),
86 If {
88 test: Expression,
90 body: Vec<Statement>,
92 orelse: Vec<Statement>,
94 },
95 For {
97 target: Expression,
99 iter: Expression,
101 body: Vec<Statement>,
103 orelse: Vec<Statement>,
105 },
106 AsyncFor {
108 target: Expression,
110 iter: Expression,
112 body: Vec<Statement>,
114 orelse: Vec<Statement>,
116 },
117 While {
119 test: Expression,
121 body: Vec<Statement>,
123 orelse: Vec<Statement>,
125 },
126 Break,
128 Continue,
130 Pass,
132 Import {
134 names: Vec<ImportName>,
136 },
137 ImportFrom {
139 module: Option<String>,
141 names: Vec<ImportName>,
143 },
144 Global {
146 names: Vec<String>,
148 },
149 Nonlocal {
151 names: Vec<String>,
153 },
154 Try {
156 body: Vec<Statement>,
158 handlers: Vec<ExceptHandler>,
160 orelse: Vec<Statement>,
162 finalbody: Vec<Statement>,
164 },
165 Raise {
167 exc: Option<Expression>,
169 cause: Option<Expression>,
171 },
172 With {
174 items: Vec<WithItem>,
176 body: Vec<Statement>,
178 },
179 AsyncWith {
181 items: Vec<WithItem>,
183 body: Vec<Statement>,
185 },
186 Assert {
188 test: Expression,
190 msg: Option<Expression>,
192 },
193 Match {
195 subject: Expression,
197 cases: Vec<MatchCase>,
199 },
200 Delete {
202 targets: Vec<Expression>,
204 },
205}
206
207#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
209#[derive(Debug, Clone, PartialEq)]
210pub struct MatchCase {
211 pub pattern: Pattern,
213 pub guard: Option<Expression>,
215 pub body: Vec<Statement>,
217}
218
219#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221#[derive(Debug, Clone, PartialEq)]
222pub enum Pattern {
223 Value(Expression),
225 Wildcard,
227 As {
229 pattern: Option<Box<Pattern>>,
231 name: String,
233 },
234 Sequence(Vec<Pattern>),
236 Mapping {
238 keys: Vec<Expression>,
240 patterns: Vec<Pattern>,
242 },
243 Class {
245 cls: Expression,
247 patterns: Vec<Pattern>,
249 keywords: Vec<String>,
251 keyword_patterns: Vec<Pattern>,
253 },
254 Or(Vec<Pattern>),
256}
257
258#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
260#[derive(Debug, Clone, PartialEq)]
261pub enum Expression {
262 Literal(Literal),
264 Name(String),
266 BinaryOp {
268 left: Box<Expression>,
270 operator: BinaryOperator,
272 right: Box<Expression>,
274 },
275 UnaryOp {
277 operator: UnaryOperator,
279 operand: Box<Expression>,
281 },
282 BoolOp {
284 operator: BoolOperator,
286 values: Vec<Expression>,
288 },
289 Compare {
291 left: Box<Expression>,
293 ops: Vec<CompareOperator>,
295 comparators: Vec<Expression>,
297 },
298 Call {
300 func: Box<Expression>,
302 args: Vec<Expression>,
304 keywords: Vec<Keyword>,
306 },
307 Attribute {
309 value: Box<Expression>,
311 attr: String,
313 },
314 Subscript {
316 value: Box<Expression>,
318 slice: Box<Expression>,
320 },
321 List {
323 elts: Vec<Expression>,
325 },
326 Tuple {
328 elts: Vec<Expression>,
330 },
331 Slice {
333 lower: Option<Box<Expression>>,
335 upper: Option<Box<Expression>>,
337 step: Option<Box<Expression>>,
339 },
340 Dict {
342 keys: Vec<Option<Expression>>,
344 values: Vec<Expression>,
346 },
347 Set {
349 elts: Vec<Expression>,
351 },
352 ListComp {
354 elt: Box<Expression>,
356 generators: Vec<Comprehension>,
358 },
359 DictComp {
361 key: Box<Expression>,
363 value: Box<Expression>,
365 generators: Vec<Comprehension>,
367 },
368 SetComp {
370 elt: Box<Expression>,
372 generators: Vec<Comprehension>,
374 },
375 GeneratorExp {
377 elt: Box<Expression>,
379 generators: Vec<Comprehension>,
381 },
382 Lambda {
384 args: Vec<Parameter>,
386 body: Box<Expression>,
388 },
389 IfExp {
391 test: Box<Expression>,
393 body: Box<Expression>,
395 orelse: Box<Expression>,
397 },
398 JoinedStr {
400 values: Vec<Expression>,
402 },
403 FormattedValue {
405 value: Box<Expression>,
407 conversion: usize,
409 format_spec: Option<Box<Expression>>,
411 },
412 Yield(Option<Box<Expression>>),
414 YieldFrom(Box<Expression>),
416 Await(Box<Expression>),
418 Starred {
420 value: Box<Expression>,
422 is_double: bool,
424 },
425}
426
427#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
429#[derive(Debug, Clone, PartialEq)]
430pub enum Literal {
431 Integer(i64),
433 Float(f64),
435 String(String),
437 Bytes(Vec<u8>),
439 Boolean(bool),
441 None,
443}
444
445#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
447#[derive(Debug, Clone, PartialEq)]
448pub enum AugmentedOperator {
449 Add,
451 Sub,
453 Mult,
455 Div,
457 FloorDiv,
459 Mod,
461 Pow,
463 LShift,
465 RShift,
467 BitOr,
469 BitXor,
471 BitAnd,
473}
474
475#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
477#[derive(Debug, Clone, PartialEq)]
478pub enum BinaryOperator {
479 Add,
481 Sub,
483 Mult,
485 Div,
487 FloorDiv,
489 Mod,
491 Pow,
493 LShift,
495 RShift,
497 BitOr,
499 BitXor,
501 BitAnd,
503}
504
505#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
507#[derive(Debug, Clone, PartialEq)]
508pub enum UnaryOperator {
509 Invert,
511 Not,
513 UAdd,
515 USub,
517}
518
519#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
521#[derive(Debug, Clone, PartialEq)]
522pub enum BoolOperator {
523 And,
525 Or,
527}
528
529#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
531#[derive(Debug, Clone, PartialEq)]
532pub enum CompareOperator {
533 Eq,
535 NotEq,
537 Lt,
539 LtE,
541 Gt,
543 GtE,
545 Is,
547 IsNot,
549 In,
551 NotIn,
553}
554
555#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
557#[derive(Debug, Clone, PartialEq)]
558pub struct Parameter {
559 pub name: String,
561 pub annotation: Option<Type>,
563 pub default: Option<Expression>,
565 pub is_vararg: bool,
567 pub is_kwarg: bool,
569}
570
571#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
573#[derive(Debug, Clone, PartialEq)]
574pub enum Type {
575 Name(String),
577 Generic {
579 name: String,
581 args: Vec<Type>,
583 },
584 Union(Vec<Type>),
586 Optional(Box<Type>),
588}
589
590#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
592#[derive(Debug, Clone, PartialEq)]
593pub struct Keyword {
594 pub arg: Option<String>,
596 pub value: Expression,
598}
599
600#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
602#[derive(Debug, Clone, PartialEq)]
603pub struct Comprehension {
604 pub target: Expression,
606 pub iter: Expression,
608 pub ifs: Vec<Expression>,
610 pub is_async: bool,
612}
613
614#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
616#[derive(Debug, Clone, PartialEq)]
617pub struct ImportName {
618 pub name: String,
620 pub asname: Option<String>,
622}
623
624#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
626#[derive(Debug, Clone, PartialEq)]
627pub struct ExceptHandler {
628 pub type_: Option<Expression>,
630 pub name: Option<String>,
632 pub body: Vec<Statement>,
634}
635
636#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
638#[derive(Debug, Clone, PartialEq)]
639pub struct WithItem {
640 pub context_expr: Expression,
642 pub optional_vars: Option<Expression>,
644}
645
646impl Program {
647 pub fn new() -> Self {
649 Self { statements: Vec::new() }
650 }
651
652 pub fn add_statement(&mut self, statement: Statement) {
654 self.statements.push(statement)
655 }
656}
657
658impl Default for Program {
659 fn default() -> Self {
660 Self::new()
661 }
662}
663
664impl Expression {
665 pub fn name(name: impl Into<String>) -> Self {
667 Self::Name(name.into())
668 }
669
670 pub fn string(value: impl Into<String>) -> Self {
672 Self::Literal(Literal::String(value.into()))
673 }
674
675 pub fn integer(value: i64) -> Self {
677 Self::Literal(Literal::Integer(value))
678 }
679
680 pub fn float(value: f64) -> Self {
682 Self::Literal(Literal::Float(value))
683 }
684
685 pub fn boolean(value: bool) -> Self {
687 Self::Literal(Literal::Boolean(value))
688 }
689
690 pub fn none() -> Self {
692 Self::Literal(Literal::None)
693 }
694}
695
696impl Statement {
697 pub fn function_def(name: impl Into<String>, parameters: Vec<Parameter>, return_type: Option<Type>, body: Vec<Statement>) -> Self {
699 Self::FunctionDef { decorators: Vec::new(), name: name.into(), parameters, return_type, body }
700 }
701
702 pub fn assignment(target: Expression, value: Expression) -> Self {
704 Self::Assignment { target, value }
705 }
706
707 pub fn expression(expr: Expression) -> Self {
709 Self::Expression(expr)
710 }
711
712 pub fn return_stmt(value: Option<Expression>) -> Self {
714 Self::Return(value)
715 }
716}