arrow_parser/
ast.rs

1use super::operator::ExprOperatorName;
2use super::source::SourceRange;
3use crate::symbol::Scope;
4use ordered_float::OrderedFloat;
5
6pub trait Syntax {}
7
8pub enum LiteralTemplatePart {
9  Substitution(Node<Expression>),
10  String(String),
11}
12
13pub enum Expression {
14  Binary {
15    left: Node<Expression>,
16    right: Node<Expression>,
17    operator: ExprOperatorName,
18  },
19  BindMethod {
20    impl_: String,
21    method: String,
22    arguments: Vec<Node<Expression>>,
23  },
24  Block {
25    statements: Vec<Node<Statement>>,
26    result: Option<Node<Expression>>,
27  },
28  CallMethod {
29    object: Node<Expression>,
30    method: String,
31    arguments: Vec<Node<Expression>>,
32    optional: bool,
33  },
34  CallValue {
35    callee: Node<Expression>,
36    arguments: Vec<Node<Expression>>,
37    optional: bool,
38  },
39  Cast {
40    value: Node<Expression>,
41    typ: String,
42  },
43  Closure {
44    parameters: Vec<String>,
45    body: Node<Expression>, // Always Expression::Block.
46  },
47  Field {
48    object: Node<Expression>,
49    field: String,
50    optional: bool,
51  },
52  Index {
53    object: Node<Expression>,
54    index: Node<Expression>,
55    optional: bool,
56  },
57  If {
58    condition: Node<Expression>,
59    consequent: Node<Expression>,        // Always Expression::Block.
60    alternate: Option<Node<Expression>>, // Always Expression::Block or Expression::If if Some.
61  },
62  LiteralArray {
63    entries: Vec<Node<Expression>>,
64  },
65  LiteralBoolean {
66    value: bool,
67  },
68  LiteralFloat {
69    value: OrderedFloat<f64>,
70  },
71  LiteralInt {
72    value: i64,
73  },
74  LiteralNone {},
75  LiteralObject {
76    fields: Vec<(String, Node<Expression>)>,
77  },
78  LiteralTemplateExpr {
79    parts: Vec<LiteralTemplatePart>,
80  },
81  Unary {
82    operand: Node<Expression>,
83    operator: ExprOperatorName,
84  },
85  Var {
86    name: String,
87  },
88}
89
90impl Syntax for Expression {}
91
92// Statements never result in values.
93pub enum Statement {
94  Break,
95  Continue,
96  Expression {
97    expression: Node<Expression>,
98  },
99  FieldAssign {
100    object: Node<Expression>,
101    field: String,
102    value: Node<Expression>,
103    optional: bool,
104  },
105  For {
106    variable: String,
107    iterable: Node<Expression>,
108    body: Node<Expression>, // Always Expression::Block with None `result`.
109  },
110  IndexAssign {
111    object: Node<Expression>,
112    index: Node<Expression>,
113    value: Node<Expression>,
114    optional: bool,
115  },
116  Let {
117    variable: String,
118    value: Node<Expression>,
119  },
120  Loop {
121    body: Node<Expression>, // Always Expression::Block with None `result`.
122  },
123  Return {
124    value: Option<Node<Expression>>,
125  },
126  VarAssign {
127    variable: String,
128    value: Node<Expression>,
129  },
130}
131
132impl Syntax for Statement {}
133
134pub enum ModuleItem {
135  Impl {
136    name: String,
137    methods: Vec<(String, Node<Expression>)>, // Always Expression::Closure.
138  },
139  Statement {
140    statement: Node<Statement>,
141  },
142}
143
144impl Syntax for ModuleItem {}
145
146pub struct Node<S: Syntax> {
147  pub loc: SourceRange,
148  pub stx: Box<S>,
149  // A new scope is introduced immediately at Expression::Block and Expression::Closure, not their immediate children. This makes it easier to get and identify new scopes from nodes.
150  pub scope: Scope,
151}
152
153pub struct Module {
154  pub items: Vec<Node<ModuleItem>>,
155}