scilla_parser/ast/
nodes.rs

1use std::fmt;
2
3use crate::parser::lexer::SourcePosition;
4
5/// A wrapper struct that adds source position to an AST node.
6#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
7pub struct WithMetaData<T> {
8    /// The AST node
9    pub node: T,
10    /// The starting position of the AST node in the source code
11    pub start: SourcePosition,
12    /// The ending position of the AST node in the source code
13    pub end: SourcePosition,
14}
15
16/// Implementing Display trait for WithMetaData struct
17impl<T: fmt::Display> fmt::Display for WithMetaData<T> {
18    /// Formats the WithMetaData instance into a string
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        write!(f, "{}", self.node)
21    }
22}
23
24/// NodeByteStr represents a byte string node in the AST
25#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
26pub enum NodeByteStr {
27    /// Represents a constant byte string
28    /// Example: `let x = "constant";`
29    Constant(WithMetaData<String>), // TODO: Apparently not used anywhere
30    /// Represents a byte string type
31    /// Example: `let x: ByStr = "type";`
32    Type(WithMetaData<String>),
33}
34
35impl fmt::Display for NodeByteStr {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        let str = match self {
38            NodeByteStr::Constant(s) => s.node.clone(),
39            NodeByteStr::Type(t) => t.node.clone(),
40        };
41        write!(f, "{}", str)
42    }
43}
44
45/// NodeTypeNameIdentifier represents a type name identifier node in the AST
46#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
47pub enum NodeTypeNameIdentifier {
48    /// Represents a byte string type
49    /// Example: `let x: ByStr = "type";`
50    ByteStringType(NodeByteStr),
51    /// Represents an event type
52    /// Example: `event e;`
53    EventType,
54    /// Represents a type or enum-like identifier
55    /// Example: `let x: CustomType = "type";`
56    TypeOrEnumLikeIdentifier(WithMetaData<String>),
57}
58
59impl fmt::Display for NodeTypeNameIdentifier {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        let str = match self {
62            NodeTypeNameIdentifier::ByteStringType(byte_str) => byte_str.to_string(),
63            NodeTypeNameIdentifier::EventType => "Event".to_string(),
64            NodeTypeNameIdentifier::TypeOrEnumLikeIdentifier(custom_type) => {
65                format!("{}", custom_type.clone())
66            }
67        };
68        write!(f, "{}", str)
69    }
70}
71
72/// NodeImportedName represents an imported name node in the AST
73#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
74pub enum NodeImportedName {
75    /// Represents a regular import
76    /// Example: `import CustomType;`
77    RegularImport(WithMetaData<NodeTypeNameIdentifier>),
78    /// Represents an aliased import
79    /// Example: `import CustomType as Alias;`
80    AliasedImport(
81        WithMetaData<NodeTypeNameIdentifier>,
82        WithMetaData<NodeTypeNameIdentifier>,
83    ),
84}
85
86/// NodeImportDeclarations represents a list of import declarations in the AST
87#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
88pub struct NodeImportDeclarations {
89    pub import_list: Vec<WithMetaData<NodeImportedName>>,
90}
91
92/// NodeMetaIdentifier represents a meta identifier node in the AST
93#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
94pub enum NodeMetaIdentifier {
95    /// Represents a meta name
96    /// Example: `let x: MetaName = "type";`
97    MetaName(WithMetaData<NodeTypeNameIdentifier>),
98    /// Represents a meta name in a namespace
99    /// Example: `let x: Namespace.MetaName = "type";`
100    MetaNameInNamespace(
101        WithMetaData<NodeTypeNameIdentifier>,
102        WithMetaData<NodeTypeNameIdentifier>,
103    ),
104    /// Represents a meta name in a hexspace
105    /// Example: `let x: 0x123.MetaName = "type";`
106    MetaNameInHexspace(WithMetaData<String>, WithMetaData<NodeTypeNameIdentifier>),
107    /// Represents a byte string
108    /// Example: `let x: ByStr = "type";`
109    ByteString,
110}
111
112impl fmt::Display for NodeMetaIdentifier {
113    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114        let str = match self {
115            NodeMetaIdentifier::MetaName(name) => {
116                format!("{}", name)
117            }
118            NodeMetaIdentifier::MetaNameInNamespace(namespace, name) => {
119                format!("{}.{}", namespace, name)
120            }
121            NodeMetaIdentifier::MetaNameInHexspace(hexspace, name) => {
122                format!("{}.{}", hexspace, name)
123            }
124            NodeMetaIdentifier::ByteString => "ByStr".to_string(),
125        };
126        write!(f, "{}", str)
127    }
128}
129
130/// NodeVariableIdentifier represents a variable identifier node in the AST
131#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
132pub enum NodeVariableIdentifier {
133    /// Represents a variable name
134    /// Example: `let x = "variable";`
135    VariableName(WithMetaData<String>),
136    /// Represents a special identifier
137    /// Example: `let _ = "special";`
138    SpecialIdentifier(WithMetaData<String>),
139    /// Represents a variable in a namespace
140    /// Example: `let x: Namespace.Variable = "variable";`
141    VariableInNamespace(WithMetaData<NodeTypeNameIdentifier>, WithMetaData<String>),
142}
143
144impl fmt::Display for NodeVariableIdentifier {
145    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146        let str = match self {
147            NodeVariableIdentifier::VariableName(name) => format!("{}", name),
148            NodeVariableIdentifier::SpecialIdentifier(id) => format!("{}", id),
149            NodeVariableIdentifier::VariableInNamespace(namespace, var_name) => {
150                format!("{}.{}", namespace, var_name)
151            }
152        };
153        write!(f, "{}", str)
154    }
155}
156
157/// NodeBuiltinArguments represents a list of arguments for a built-in function in the AST
158#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
159pub struct NodeBuiltinArguments {
160    pub arguments: Vec<WithMetaData<NodeVariableIdentifier>>,
161}
162
163/// NodeTypeMapKey represents a type map key node in the AST
164#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
165pub enum NodeTypeMapKey {
166    /// Represents a generic map key
167    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
168    GenericMapKey(WithMetaData<NodeMetaIdentifier>),
169    /// Represents an enclosed generic id
170    /// Example: `let x: Map ((KeyType), ValueType) = Emp;`
171    EnclosedGenericId(WithMetaData<NodeMetaIdentifier>),
172    /// Represents an enclosed address map key type
173    /// Example: `let x: Map ((ByStr20), ValueType) = Emp;`
174    EnclosedAddressMapKeyType(WithMetaData<NodeAddressType>),
175    /// Represents an address map key type
176    /// Example: `let x: Map (ByStr20, ValueType) = Emp;`
177    AddressMapKeyType(WithMetaData<NodeAddressType>),
178}
179
180/// NodeTypeMapValue represents a type map value node in the AST
181#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
182pub enum NodeTypeMapValue {
183    /// Represents a map value type or enum-like identifier
184    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
185    MapValueTypeOrEnumLikeIdentifier(WithMetaData<NodeMetaIdentifier>),
186    /// Represents a map key value type
187    /// Example: `let x: Map (KeyType, (KeyType, ValueType)) = Emp;`
188    MapKeyValue(Box<WithMetaData<NodeTypeMapEntry>>),
189    /// Represents a map value parenthesized type
190    /// Example: `let x: Map (KeyType, (ValueType)) = Emp;`
191    MapValueParenthesizedType(Box<WithMetaData<NodeTypeMapValueAllowingTypeArguments>>),
192    /// Represents a map value address type
193    /// Example: `let x: Map (KeyType, ByStr20) = Emp;`
194    MapValueAddressType(Box<WithMetaData<NodeAddressType>>),
195}
196
197/// NodeTypeArgument represents a type argument node in the AST
198#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
199pub enum NodeTypeArgument {
200    /// Represents an enclosed type argument
201    /// Example: `let x: CustomType (ArgType) = "type";`
202    EnclosedTypeArgument(Box<WithMetaData<NodeScillaType>>),
203    /// Represents a generic type argument
204    /// Example: `let x: CustomType ArgType = "type";`
205    GenericTypeArgument(WithMetaData<NodeMetaIdentifier>),
206    /// Represents a template type argument
207    /// Example: `let x: CustomType "ArgType" = "type";`
208    TemplateTypeArgument(WithMetaData<String>),
209    /// Represents an address type argument
210    /// Example: `let x: CustomType ByStr20 = "type";`
211    AddressTypeArgument(WithMetaData<NodeAddressType>),
212    /// Represents a map type argument
213    /// Example: `let x: CustomType (KeyType, ValueType) = "type";`
214    MapTypeArgument(WithMetaData<NodeTypeMapKey>, WithMetaData<NodeTypeMapValue>),
215}
216
217/// NodeScillaType represents a Scilla type node in the AST
218#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
219pub enum NodeScillaType {
220    /// Represents a generic type with arguments
221    /// Example: `let x: CustomType ArgType = "type";`
222    GenericTypeWithArgs(
223        WithMetaData<NodeMetaIdentifier>,
224        Vec<WithMetaData<NodeTypeArgument>>,
225    ),
226    /// Represents a map type
227    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
228    MapType(WithMetaData<NodeTypeMapKey>, WithMetaData<NodeTypeMapValue>),
229    /// Represents a function type
230    /// Example: `let x: Fun (ArgType) ReturnType = fun (arg : ArgType) => arg;`
231    FunctionType(
232        Box<WithMetaData<NodeScillaType>>,
233        Box<WithMetaData<NodeScillaType>>,
234    ),
235    /// Represents an enclosed type
236    /// Example: `let x: (CustomType) = "type";`
237    EnclosedType(Box<WithMetaData<NodeScillaType>>),
238    /// Represents a Scilla address type
239    /// Example: `let x: ByStr20 = "0x123";`
240    ScillaAddresseType(Box<WithMetaData<NodeAddressType>>),
241    /// Represents a poly function type
242    /// Example: `let x: forall 'A. ('A -> 'A) = fun (arg : 'A) => arg;`
243    PolyFunctionType(WithMetaData<String>, Box<WithMetaData<NodeScillaType>>),
244    /// Represents a type var type
245    /// Example: `let x: 'A = "type";`
246    TypeVarType(WithMetaData<String>),
247}
248
249/// NodeTypeMapEntry represents a type map entry node in the AST
250#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
251pub struct NodeTypeMapEntry {
252    pub key: WithMetaData<NodeTypeMapKey>,
253    pub value: WithMetaData<NodeTypeMapValue>,
254}
255
256/// NodeAddressTypeField represents an address type field node in the AST
257#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
258pub struct NodeAddressTypeField {
259    pub identifier: WithMetaData<NodeVariableIdentifier>,
260    pub type_name: WithMetaData<NodeScillaType>,
261}
262
263/// NodeAddressType represents an address type node in the AST
264#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
265pub struct NodeAddressType {
266    pub identifier: WithMetaData<NodeTypeNameIdentifier>,
267    pub type_name: WithMetaData<String>,
268    pub address_fields: Vec<WithMetaData<NodeAddressTypeField>>,
269}
270
271/// NodeFullExpression represents a full expression node in the AST
272#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
273pub enum NodeFullExpression {
274    /// Represents a local variable declaration
275    /// Example: `let x = "variable";`
276    LocalVariableDeclaration {
277        identifier_name: WithMetaData<String>,
278        expression: Box<WithMetaData<NodeFullExpression>>,
279        type_annotation: Option<WithMetaData<NodeTypeAnnotation>>,
280        containing_expression: Box<WithMetaData<NodeFullExpression>>,
281    },
282    /// Represents a function declaration
283    /// Example: `let f = fun (arg : ArgType) => arg;`
284    FunctionDeclaration {
285        identier_value: WithMetaData<String>,
286        type_annotation: WithMetaData<NodeTypeAnnotation>,
287        expression: Box<WithMetaData<NodeFullExpression>>,
288    },
289    /// Represents a function call
290    /// Example: `f(arg);`
291    FunctionCall {
292        function_name: WithMetaData<NodeVariableIdentifier>,
293        argument_list: Vec<WithMetaData<NodeVariableIdentifier>>,
294    },
295    /// Represents an atomic expression
296    /// Example: `let x = "atomic";`
297    ExpressionAtomic(Box<WithMetaData<NodeAtomicExpression>>),
298    /// Represents a built-in expression
299    /// Example: `let x = builtin f arg;`
300    ExpressionBuiltin {
301        b: WithMetaData<String>,
302        targs: Option<WithMetaData<NodeContractTypeArguments>>,
303        xs: WithMetaData<NodeBuiltinArguments>,
304    },
305    /// Represents a message
306    /// Example: `msg = { _tag : "tag", _recipient : "0x123", _amount : "0", param : "value" };`
307    Message(Vec<WithMetaData<NodeMessageEntry>>),
308    /// Represents a match expression
309    /// Example: `match x with | Nil => "nil" | Cons a b => "cons" end`
310    Match {
311        match_expression: WithMetaData<NodeVariableIdentifier>,
312        clauses: Vec<WithMetaData<NodePatternMatchExpressionClause>>,
313    },
314    /// Represents a constructor call
315    /// Example: `let x = CustomType arg;`
316    ConstructorCall {
317        identifier_name: WithMetaData<NodeMetaIdentifier>,
318        contract_type_arguments: Option<WithMetaData<NodeContractTypeArguments>>,
319        argument_list: Vec<WithMetaData<NodeVariableIdentifier>>,
320    },
321    /// Represents a template function
322    /// Example: `let x = tfun 'A => fun (arg : 'A) => arg;`
323    TemplateFunction {
324        identifier_name: WithMetaData<String>,
325        expression: Box<WithMetaData<NodeFullExpression>>,
326    },
327    /// Represents a type application
328    /// Example: `let x = @CustomType arg;`
329    TApp {
330        identifier_name: WithMetaData<NodeVariableIdentifier>,
331        type_arguments: Vec<WithMetaData<NodeTypeArgument>>,
332    },
333}
334
335/// NodeMessageEntry represents a message entry node in the AST
336/// It can either be a MessageLiteral or a MessageVariable
337/// Example: `msg = { _tag : "tag", _recipient : "0x123", _amount : "0", param : "value" };`
338#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
339pub enum NodeMessageEntry {
340    /// Represents a message literal
341    /// Example: `msg = { _tag : "tag", _recipient : "0x123", _amount : "0", param : "value" };`
342    MessageLiteral(
343        WithMetaData<NodeVariableIdentifier>,
344        WithMetaData<NodeValueLiteral>,
345    ),
346    /// Represents a message variable
347    /// Example: `msg = { _tag : "tag", _recipient : "0x123", _amount : "0", param : variable };`
348    MessageVariable(
349        WithMetaData<NodeVariableIdentifier>,
350        WithMetaData<NodeVariableIdentifier>,
351    ),
352}
353
354/// NodePatternMatchExpressionClause represents a pattern match expression clause node in the AST
355/// It contains a pattern and an expression
356#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
357pub struct NodePatternMatchExpressionClause {
358    /// The pattern of the clause
359    pub pattern: WithMetaData<NodePattern>,
360    /// The expression of the clause
361    pub expression: WithMetaData<NodeFullExpression>,
362}
363
364/// NodeAtomicExpression represents an atomic expression node in the AST
365/// It can either be an AtomicSid or an AtomicLit
366#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
367pub enum NodeAtomicExpression {
368    /// Represents an atomic sid
369    /// Example: `let x = sid;`
370    AtomicSid(WithMetaData<NodeVariableIdentifier>),
371    /// Represents an atomic literal
372    /// Example: `let x = "literal";`
373    AtomicLit(WithMetaData<NodeValueLiteral>),
374}
375
376/// NodeContractTypeArguments represents a contract type arguments node in the AST
377/// It contains a vector of type arguments
378#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
379pub struct NodeContractTypeArguments {
380    /// The type arguments of the contract
381    pub type_arguments: Vec<WithMetaData<NodeTypeArgument>>,
382}
383
384/// NodeValueLiteral represents a value literal node in the AST
385/// It can either be a LiteralInt, LiteralHex, LiteralString or LiteralEmptyMap
386#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
387pub enum NodeValueLiteral {
388    /// Represents a literal integer
389    /// Example: `let x = 10;`
390    LiteralInt(WithMetaData<NodeTypeNameIdentifier>, WithMetaData<String>),
391    /// Represents a literal hexadecimal
392    /// Example: `let x = 0x123;`
393    LiteralHex(WithMetaData<String>),
394    /// Represents a literal string
395    /// Example: `let x = "string";`
396    LiteralString(WithMetaData<String>),
397    /// Represents a literal empty map
398    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
399    LiteralEmptyMap(WithMetaData<NodeTypeMapKey>, WithMetaData<NodeTypeMapValue>),
400}
401
402/// NodeMapAccess represents a map access node in the AST
403/// It contains an identifier name
404#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
405pub struct NodeMapAccess {
406    /// The identifier name of the map access
407    pub identifier_name: WithMetaData<NodeVariableIdentifier>,
408}
409
410/// NodePattern represents a pattern node in the AST
411/// It can either be a Wildcard, Binder or Constructor
412#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
413pub enum NodePattern {
414    /// Represents a wildcard pattern
415    /// Example: `match x with | _ => "wildcard" end`
416    Wildcard,
417    /// Represents a binder pattern
418    /// Example: `match x with | a => "binder" end`
419    Binder(WithMetaData<String>),
420    /// Represents a constructor pattern
421    /// Example: `match x with | Cons a b => "constructor" end`
422    Constructor(
423        WithMetaData<NodeMetaIdentifier>,
424        Vec<WithMetaData<NodeArgumentPattern>>,
425    ),
426}
427
428/// NodeArgumentPattern represents an argument pattern node in the AST
429/// It can either be a WildcardArgument, BinderArgument, ConstructorArgument or PatternArgument
430#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
431pub enum NodeArgumentPattern {
432    /// Represents a wildcard argument
433    /// Example: `match x with | Cons _ _ => "wildcard argument" end`
434    WildcardArgument,
435    /// Represents a binder argument
436    /// Example: `match x with | Cons a _ => "binder argument" end`
437    BinderArgument(WithMetaData<String>),
438    /// Represents a constructor argument
439    /// Example: `match x with | Cons (Cons a b) _ => "constructor argument" end`
440    ConstructorArgument(WithMetaData<NodeMetaIdentifier>),
441    /// Represents a pattern argument
442    /// Example: `match x with | Cons (Cons a _) _ => "pattern argument" end`
443    PatternArgument(Box<WithMetaData<NodePattern>>),
444}
445
446/// NodePatternMatchClause represents a pattern match clause node in the AST
447/// It contains a pattern expression and an optional statement block
448#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
449pub struct NodePatternMatchClause {
450    /// The pattern expression of the clause
451    pub pattern_expression: Box<WithMetaData<NodePattern>>,
452    /// The statement block of the clause
453    pub statement_block: Option<WithMetaData<NodeStatementBlock>>,
454}
455
456/// NodeBlockchainFetchArguments represents a blockchain fetch arguments node in the AST
457/// It contains a vector of arguments
458#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
459pub struct NodeBlockchainFetchArguments {
460    /// The arguments of the blockchain fetch
461    pub arguments: Vec<WithMetaData<NodeVariableIdentifier>>,
462}
463
464/// NodeStatement represents a statement node in the AST
465/// It can be one of many different types of statements
466#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
467pub enum NodeStatement {
468    /// Represents a load statement
469    /// Example: `load x;`
470    Load {
471        left_hand_side: WithMetaData<String>,
472        right_hand_side: WithMetaData<NodeVariableIdentifier>,
473    },
474    /// Represents a remote fetch statement
475    /// Example: `fetch x from remote;`
476    RemoteFetch(Box<NodeRemoteFetchStatement>),
477    /// Represents a store statement
478    /// Example: `store x;`
479    Store {
480        left_hand_side: WithMetaData<String>,
481        right_hand_side: WithMetaData<NodeVariableIdentifier>,
482    },
483    /// Represents a bind statement
484    /// Example: `bind x = y;`
485    Bind {
486        left_hand_side: WithMetaData<String>,
487        right_hand_side: Box<WithMetaData<NodeFullExpression>>,
488    },
489    /// Represents a read from blockchain statement
490    /// Example: `read x from bc;`
491    ReadFromBC {
492        left_hand_side: WithMetaData<String>,
493        type_name: WithMetaData<NodeTypeNameIdentifier>,
494        arguments: Option<NodeBlockchainFetchArguments>,
495    },
496    /// Represents a map get statement
497    /// Example: `get x from map;`
498    MapGet {
499        left_hand_side: WithMetaData<String>,
500        keys: Vec<WithMetaData<NodeMapAccess>>,
501        right_hand_side: WithMetaData<String>,
502    },
503    /// Represents a map get exists statement
504    /// Example: `get x from map if exists;`
505    MapGetExists {
506        left_hand_side: WithMetaData<String>,
507        keys: Vec<WithMetaData<NodeMapAccess>>,
508        right_hand_side: WithMetaData<String>,
509    },
510    /// Represents a map update statement
511    /// Example: `update x in map;`
512    MapUpdate {
513        left_hand_side: WithMetaData<String>,
514        keys: Vec<WithMetaData<NodeMapAccess>>,
515        right_hand_side: WithMetaData<NodeVariableIdentifier>,
516    },
517    /// Represents a map update delete statement
518    /// Example: `delete x from map;`
519    MapUpdateDelete {
520        left_hand_side: WithMetaData<String>,
521        keys: Vec<WithMetaData<NodeMapAccess>>,
522    },
523    /// Represents an accept statement
524    /// Example: `accept;`
525    Accept,
526    /// Represents a send statement
527    /// Example: `send x;`
528    Send {
529        identifier_name: WithMetaData<NodeVariableIdentifier>,
530    },
531    /// Represents a create event statement
532    /// Example: `create event x;`
533    CreateEvnt {
534        identifier_name: WithMetaData<NodeVariableIdentifier>,
535    },
536    /// Represents a throw statement
537    /// Example: `throw x;`
538    Throw {
539        error_variable: Option<WithMetaData<NodeVariableIdentifier>>,
540    },
541    /// Represents a match statement
542    /// Example: `match x with | Nil => "nil" | Cons a b => "cons" end`
543    MatchStmt {
544        variable: WithMetaData<NodeVariableIdentifier>,
545        clauses: Vec<WithMetaData<NodePatternMatchClause>>,
546    },
547    /// Represents a call procedure statement
548    /// Example: `call proc x;`
549    CallProc {
550        component_id: WithMetaData<NodeComponentId>,
551        arguments: Vec<WithMetaData<NodeVariableIdentifier>>,
552    },
553    /// Represents an iterate statement
554    /// Example: `iterate x over y;`
555    Iterate {
556        identifier_name: WithMetaData<NodeVariableIdentifier>,
557        component_id: WithMetaData<NodeComponentId>,
558    },
559}
560
561/// NodeRemoteFetchStatement represents a remote fetch statement node in the AST
562/// It can be one of many different types of remote fetch statements
563#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
564pub enum NodeRemoteFetchStatement {
565    /// Represents a read state mutable statement
566    /// Example: `read x from state;`
567    ReadStateMutable(
568        WithMetaData<String>,
569        WithMetaData<String>,
570        WithMetaData<NodeVariableIdentifier>,
571    ),
572    /// Represents a read state mutable special id statement
573    /// Example: `read x from state with id;`
574    ReadStateMutableSpecialId(
575        WithMetaData<String>,
576        WithMetaData<String>,
577        WithMetaData<String>,
578    ),
579    /// Represents a read state mutable map access statement
580    /// Example: `read x from state with map access;`
581    ReadStateMutableMapAccess(
582        WithMetaData<String>,
583        WithMetaData<String>,
584        WithMetaData<String>,
585        Vec<WithMetaData<NodeMapAccess>>,
586    ),
587    /// Represents a read state mutable map access exists statement
588    /// Example: `read x from state with map access if exists;`
589    ReadStateMutableMapAccessExists(
590        WithMetaData<String>,
591        WithMetaData<String>,
592        WithMetaData<String>,
593        Vec<WithMetaData<NodeMapAccess>>,
594    ),
595    /// Represents a read state mutable cast address statement
596    /// Example: `read x from state with cast address;`
597    ReadStateMutableCastAddress(
598        WithMetaData<String>,
599        WithMetaData<NodeVariableIdentifier>,
600        WithMetaData<NodeAddressType>,
601    ),
602}
603
604/// NodeComponentId represents a component id node in the AST
605/// It can either be a WithTypeLikeName or a WithRegularId
606#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
607pub enum NodeComponentId {
608    /// Represents a component id with a type like name
609    /// Example: `component WithTypeLikeName;`
610    WithTypeLikeName(WithMetaData<NodeTypeNameIdentifier>),
611    /// Represents a component id with a regular id
612    /// Example: `component WithRegularId;`
613    WithRegularId(WithMetaData<String>),
614}
615
616/// NodeComponentParameters represents a component parameters node in the AST
617/// It contains a vector of parameters
618#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
619pub struct NodeComponentParameters {
620    /// The parameters of the component
621    pub parameters: Vec<WithMetaData<NodeParameterPair>>,
622}
623
624/// NodeParameterPair represents a parameter pair node in the AST
625/// It contains an identifier with type
626#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
627pub struct NodeParameterPair {
628    /// The identifier with type of the parameter pair
629    pub identifier_with_type: WithMetaData<NodeTypedIdentifier>,
630}
631
632/// NodeComponentBody represents a component body node in the AST
633/// It contains an optional statement block
634#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
635pub struct NodeComponentBody {
636    /// The statement block of the component body
637    pub statement_block: Option<WithMetaData<NodeStatementBlock>>,
638}
639
640/// NodeStatementBlock represents a statement block node in the AST
641/// It contains a vector of statements
642#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
643pub struct NodeStatementBlock {
644    /// The statements of the statement block
645    pub statements: Vec<NodeStatement>,
646}
647
648/// NodeTypedIdentifier represents a typed identifier node in the AST
649/// It contains an identifier name and an annotation
650#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
651pub struct NodeTypedIdentifier {
652    /// The identifier name of the typed identifier
653    pub identifier_name: WithMetaData<String>,
654    /// The annotation of the typed identifier
655    pub annotation: WithMetaData<NodeTypeAnnotation>,
656}
657
658/// NodeTypeAnnotation represents a type annotation node in the AST
659/// It contains a type name
660#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
661pub struct NodeTypeAnnotation {
662    /// The type name of the type annotation
663    pub type_name: WithMetaData<NodeScillaType>,
664}
665
666/// NodeProgram represents a program node in the AST
667/// It contains a version, optional import declarations, optional library definition and a contract definition
668#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
669pub struct NodeProgram {
670    /// The version of the program
671    pub version: WithMetaData<String>,
672    /// The import declarations of the program
673    pub import_declarations: Option<WithMetaData<NodeImportDeclarations>>,
674    /// The library definition of the program
675    pub library_definition: Option<WithMetaData<NodeLibraryDefinition>>,
676    /// The contract definition of the program
677    pub contract_definition: WithMetaData<NodeContractDefinition>,
678}
679
680/// NodeLibraryDefinition represents a library definition node in the AST
681/// It contains a name and a vector of definitions
682#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
683pub struct NodeLibraryDefinition {
684    /// The name of the library definition
685    pub name: WithMetaData<NodeTypeNameIdentifier>,
686    /// The definitions of the library definition
687    pub definitions: Vec<WithMetaData<NodeLibrarySingleDefinition>>,
688}
689
690/// NodeLibrarySingleDefinition represents a library single definition node in the AST
691/// It can either be a LetDefinition or a TypeDefinition
692#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
693pub enum NodeLibrarySingleDefinition {
694    /// Represents a let definition
695    /// Example: `let x = y;`
696    LetDefinition {
697        variable_name: WithMetaData<String>,
698        type_annotation: Option<WithMetaData<NodeTypeAnnotation>>,
699        expression: WithMetaData<NodeFullExpression>,
700    },
701    /// Represents a type definition
702    /// Example: `type x = y;`
703    TypeDefinition(
704        // TODO: Enum definition
705        WithMetaData<NodeTypeNameIdentifier>,
706        Option<Vec<WithMetaData<NodeTypeAlternativeClause>>>,
707    ),
708}
709
710/// NodeContractDefinition represents a contract definition node in the AST
711/// It contains a contract name, parameters, optional constraint, fields and components
712#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
713pub struct NodeContractDefinition {
714    /// The contract name of the contract definition
715    pub contract_name: WithMetaData<NodeTypeNameIdentifier>,
716    /// The parameters of the contract definition
717    pub parameters: WithMetaData<NodeComponentParameters>,
718    /// The constraint of the contract definition
719    pub constraint: Option<WithMetaData<NodeWithConstraint>>,
720    /// The fields of the contract definition
721    pub fields: Vec<WithMetaData<NodeContractField>>,
722    /// The components of the contract definition
723    pub components: Vec<WithMetaData<NodeComponentDefinition>>,
724}
725
726/// NodeContractField represents a contract field node in the AST
727/// It contains a typed identifier and a right hand side
728#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
729pub struct NodeContractField {
730    /// The typed identifier of the contract field
731    pub typed_identifier: WithMetaData<NodeTypedIdentifier>,
732    /// The right hand side of the contract field
733    pub right_hand_side: WithMetaData<NodeFullExpression>,
734}
735
736/// NodeWithConstraint represents a with constraint node in the AST
737/// It contains an expression
738#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
739pub struct NodeWithConstraint {
740    /// The expression of the with constraint
741    pub expression: Box<WithMetaData<NodeFullExpression>>,
742}
743
744/// NodeComponentDefinition represents a component definition node in the AST
745/// It can either be a TransitionComponent or a ProcedureComponent
746#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
747pub enum NodeComponentDefinition {
748    /// Represents a transition component
749    /// Example: `transition x;`
750    TransitionComponent(Box<WithMetaData<NodeTransitionDefinition>>),
751    /// Represents a procedure component
752    /// Example: `procedure x;`
753    ProcedureComponent(Box<WithMetaData<NodeProcedureDefinition>>),
754}
755
756/// NodeProcedureDefinition represents a procedure definition node in the AST
757/// It contains a name, parameters and a body
758#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
759pub struct NodeProcedureDefinition {
760    /// The name of the procedure definition
761    pub name: WithMetaData<NodeComponentId>,
762    /// The parameters of the procedure definition
763    pub parameters: WithMetaData<NodeComponentParameters>,
764    /// The body of the procedure definition
765    pub body: WithMetaData<NodeComponentBody>,
766}
767
768/// NodeTransitionDefinition represents a transition definition node in the AST
769/// It contains a name, parameters and a body
770/// Example: `transition Transfer (from: ByStr20, to: ByStr20, amount: Uint128) = ...`
771#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
772pub struct NodeTransitionDefinition {
773    /// The name of the transition definition
774    pub name: WithMetaData<NodeComponentId>,
775    /// The parameters of the transition definition
776    pub parameters: WithMetaData<NodeComponentParameters>,
777    /// The body of the transition definition
778    pub body: WithMetaData<NodeComponentBody>,
779}
780
781/// NodeTypeAlternativeClause represents an alternative clause node in the AST
782/// It can either be a ClauseType or a ClauseTypeWithArgs
783#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
784pub enum NodeTypeAlternativeClause {
785    /// Represents a clause type
786    /// Example: `match x with | ClauseType => ...`
787    ClauseType(WithMetaData<NodeTypeNameIdentifier>),
788    /// Represents a clause type with arguments
789    /// Example: `match x with | ClauseType arg1 arg2 => ...`
790    ClauseTypeWithArgs(
791        WithMetaData<NodeTypeNameIdentifier>,
792        Vec<WithMetaData<NodeTypeArgument>>,
793    ),
794}
795
796/// NodeTypeMapValueArguments represents map value arguments node in the AST
797/// It can either be an EnclosedTypeMapValue, a GenericMapValueArgument or a MapKeyValueType
798#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
799pub enum NodeTypeMapValueArguments {
800    /// Represents an enclosed type map value
801    /// Example: `let x: Map ((KeyType), ValueType) = Emp;`
802    EnclosedTypeMapValue(Box<WithMetaData<NodeTypeMapValueAllowingTypeArguments>>),
803    /// Represents a generic map value argument
804    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
805    GenericMapValueArgument(WithMetaData<NodeMetaIdentifier>),
806    /// Represents a map key value type
807    /// Example: `let x: Map ((ByStr20), ValueType) = Emp;`
808    MapKeyValueType(WithMetaData<NodeTypeMapKey>, WithMetaData<NodeTypeMapValue>),
809}
810
811/// NodeTypeMapValueAllowingTypeArguments represents a map value allowing type arguments node in the AST
812/// It can either be a TypeMapValueNoArgs or a TypeMapValueWithArgs
813#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
814pub enum NodeTypeMapValueAllowingTypeArguments {
815    /// Represents a type map value with no arguments
816    /// Example: `let x: Map (KeyType, ValueType) = Emp;`
817    TypeMapValueNoArgs(WithMetaData<NodeTypeMapValue>),
818    /// Represents a type map value with arguments
819    /// Example: `let x: Map ((KeyType), ValueType) = Emp;`
820    TypeMapValueWithArgs(
821        WithMetaData<NodeMetaIdentifier>,
822        Vec<WithMetaData<NodeTypeMapValueArguments>>,
823    ),
824}