1use crate::{
2 ast::{converting::AstConverting, nodes::*, visitor::AstVisitor},
3 parser::lexer::SourcePosition,
4 simplified_representation::primitives::*,
5 Contract, Field, FieldList, Transition,
6};
7
8use crate::ast::{TraversalResult, TreeTraversalMode};
9
10#[derive(Debug, Clone)]
11enum StackObject {
12 IrIdentifier(SrIdentifier),
13 VariableDeclaration(Field),
14 TypeDefinition(SrType),
15}
16
17#[derive(Default)]
20pub struct SrEmitter {
21 stack: Vec<StackObject>,
22 contract: Contract,
23}
24
25impl SrEmitter {
26 fn pop_ir_identifier(&mut self) -> Result<SrIdentifier, String> {
27 let ret = if let Some(candidate) = self.stack.pop() {
28 match candidate {
29 StackObject::IrIdentifier(n) => n,
30 _ => {
31 return Err(format!("Expected symbol name, but found {:?}.", candidate));
32 }
33 }
34 } else {
35 return Err("Expected symbol name, but found nothing.".to_string());
36 };
37
38 Ok(ret)
39 }
40
41 fn pop_variable_declaration(&mut self) -> Result<Field, String> {
42 let ret = if let Some(candidate) = self.stack.pop() {
43 match candidate {
44 StackObject::VariableDeclaration(n) => n,
45 _ => {
46 return Err(format!(
47 "Expected variable declaration, but found {:?}.",
48 candidate
49 ));
50 }
51 }
52 } else {
53 return Err("Expected variable declaration, but found nothing.".to_string());
54 };
55
56 Ok(ret)
57 }
58
59 fn pop_type_definition(&mut self) -> Result<SrType, String> {
60 let ret = if let Some(candidate) = self.stack.pop() {
61 match candidate {
62 StackObject::TypeDefinition(n) => n,
63 _ => {
64 return Err(format!(
65 "Expected type definition, but found {:?}.",
66 candidate
67 ));
68 }
69 }
70 } else {
71 return Err("Expected type definition, but found nothing.".to_string());
72 };
73
74 Ok(ret)
75 }
76 pub fn emit(mut self, node: &NodeProgram) -> Result<Contract, String> {
77 node.contract_definition.visit(&mut self)?;
78 Ok(self.contract)
79 }
80}
81
82impl AstConverting for SrEmitter {
83 fn push_source_position(&mut self, _start: &SourcePosition, _end: &SourcePosition) {}
84
85 fn pop_source_position(&mut self) {}
86
87 fn emit_byte_str(
88 &mut self,
89 _mode: TreeTraversalMode,
90 _node: &NodeByteStr,
91 ) -> Result<TraversalResult, String> {
92 Ok(TraversalResult::Continue)
93 }
94 fn emit_type_name_identifier(
95 &mut self,
96 mode: TreeTraversalMode,
97 node: &NodeTypeNameIdentifier,
98 ) -> Result<TraversalResult, String> {
99 match mode {
100 TreeTraversalMode::Enter => match node {
101 NodeTypeNameIdentifier::ByteStringType(bytestr) => {
102 let symbol = SrIdentifier::new(bytestr.to_string(), SrIdentifierKind::Unknown);
103
104 self.stack.push(StackObject::IrIdentifier(symbol));
105 }
106 NodeTypeNameIdentifier::EventType => {}
107 NodeTypeNameIdentifier::TypeOrEnumLikeIdentifier(name) => {
108 let symbol = SrIdentifier::new(name.to_string(), SrIdentifierKind::Unknown);
109
110 self.stack.push(StackObject::IrIdentifier(symbol));
111 }
112 },
113 TreeTraversalMode::Exit => (),
114 }
115 Ok(TraversalResult::Continue)
116 }
117 fn emit_imported_name(
118 &mut self,
119 _mode: TreeTraversalMode,
120 _node: &NodeImportedName,
121 ) -> Result<TraversalResult, String> {
122 unimplemented!();
123 }
124 fn emit_import_declarations(
125 &mut self,
126 _mode: TreeTraversalMode,
127 _node: &NodeImportDeclarations,
128 ) -> Result<TraversalResult, String> {
129 unimplemented!();
130 }
131 fn emit_meta_identifier(
132 &mut self,
133 _mode: TreeTraversalMode,
134 _node: &NodeMetaIdentifier,
135 ) -> Result<TraversalResult, String> {
136 Ok(TraversalResult::Continue)
137 }
138 fn emit_variable_identifier(
139 &mut self,
140 _mode: TreeTraversalMode,
141 _node: &NodeVariableIdentifier,
142 ) -> Result<TraversalResult, String> {
143 Ok(TraversalResult::SkipChildren)
144 }
145 fn emit_builtin_arguments(
146 &mut self,
147 _mode: TreeTraversalMode,
148 _node: &NodeBuiltinArguments,
149 ) -> Result<TraversalResult, String> {
150 unimplemented!();
151 }
152 fn emit_type_map_key(
153 &mut self,
154 _mode: TreeTraversalMode,
155 node: &NodeTypeMapKey,
156 ) -> Result<TraversalResult, String> {
157 match node {
158 NodeTypeMapKey::GenericMapKey(key) => key.visit(self)?,
159 NodeTypeMapKey::EnclosedGenericId(key) => key.visit(self)?,
160 NodeTypeMapKey::EnclosedAddressMapKeyType(key) => key.visit(self)?,
161 NodeTypeMapKey::AddressMapKeyType(key) => key.visit(self)?,
162 };
163 Ok(TraversalResult::SkipChildren)
164 }
165 fn emit_type_map_value(
166 &mut self,
167 mode: TreeTraversalMode,
168 node: &NodeTypeMapValue,
169 ) -> Result<TraversalResult, String> {
170 match mode {
171 TreeTraversalMode::Enter => {
172 match node {
173 NodeTypeMapValue::MapValueTypeOrEnumLikeIdentifier(value) => {
174 value.visit(self)?;
175 let value = self.pop_ir_identifier()?;
176 let key = self.pop_ir_identifier()?;
177 let map = SrType {
178 main_type: "Map".to_string(),
179 sub_types: vec![key.into(), value.into()],
180 address_type: None,
181 };
182 self.stack.push(StackObject::TypeDefinition(map));
183 }
184 NodeTypeMapValue::MapKeyValue(value) => {
185 value.visit(self)?;
186 }
187 NodeTypeMapValue::MapValueParenthesizedType(value) => {
188 value.visit(self)?;
189 let value = self.pop_type_definition()?;
190 let key = self.pop_ir_identifier()?;
191 let map = SrType {
192 main_type: "Map".to_string(),
193 sub_types: vec![key.into(), value],
194 address_type: None,
195 };
196 self.stack.push(StackObject::TypeDefinition(map));
197 }
198 NodeTypeMapValue::MapValueAddressType(_value) => unimplemented!(),
199 };
200 }
201 TreeTraversalMode::Exit => {}
202 }
203 Ok(TraversalResult::SkipChildren)
204 }
205 fn emit_type_argument(
206 &mut self,
207 _mode: TreeTraversalMode,
208 node: &NodeTypeArgument,
209 ) -> Result<TraversalResult, String> {
210 match node {
211 NodeTypeArgument::EnclosedTypeArgument(t) => {
212 let _ = t.visit(self)?;
213 }
214 NodeTypeArgument::GenericTypeArgument(n) => {
215 let _ = n.visit(self)?;
216 let identifier = self.pop_ir_identifier()?;
217 self.stack
218 .push(StackObject::TypeDefinition(identifier.into()));
219 }
220 NodeTypeArgument::TemplateTypeArgument(_) => {
221 unimplemented!();
222 }
223 NodeTypeArgument::AddressTypeArgument(_) => {
224 unimplemented!();
225 }
226 NodeTypeArgument::MapTypeArgument(_, _) => {
227 unimplemented!();
228 }
229 }
230 Ok(TraversalResult::SkipChildren)
231 }
232 fn emit_scilla_type(
233 &mut self,
234 _mode: TreeTraversalMode,
235 node: &NodeScillaType,
236 ) -> Result<TraversalResult, String> {
237 match node {
238 NodeScillaType::GenericTypeWithArgs(lead, args) => {
239 let _ = lead.visit(self)?;
240 let identifier = self.pop_ir_identifier()?;
241 self.stack
242 .push(StackObject::TypeDefinition(identifier.into()));
243 if !args.is_empty() {
244 let mut main_type = self.pop_type_definition()?;
245 for arg in args {
246 let _ = arg.visit(self)?;
247 let sub_type = self.pop_type_definition()?;
248 main_type.push_sub_type(sub_type);
249 }
250 self.stack.push(StackObject::TypeDefinition(main_type));
251 }
252 }
253 NodeScillaType::MapType(key, value) => {
254 let _ = key.visit(self)?;
255 let _ = value.visit(self)?;
256 }
257 NodeScillaType::FunctionType(_a, _b) => {
258 unimplemented!()
259 }
260
261 NodeScillaType::PolyFunctionType(_name, _a) => {
262 unimplemented!()
263 }
264 NodeScillaType::EnclosedType(a) => {
265 let _ = (*a).visit(self)?;
266 }
267 NodeScillaType::ScillaAddresseType(a) => {
268 let _ = (*a).visit(self)?;
269 }
270 NodeScillaType::TypeVarType(_name) => {
271 unimplemented!()
272 }
273 };
274 Ok(TraversalResult::SkipChildren)
275 }
276
277 fn emit_type_map_entry(
278 &mut self,
279 _mode: TreeTraversalMode,
280 _node: &NodeTypeMapEntry,
281 ) -> Result<TraversalResult, String> {
282 Ok(TraversalResult::Continue)
283 }
284 fn emit_address_type_field(
285 &mut self,
286 _mode: TreeTraversalMode,
287 node: &NodeAddressTypeField,
288 ) -> Result<TraversalResult, String> {
289 if let NodeVariableIdentifier::VariableName(n) = &node.identifier.node {
290 node.type_name.visit(self)?;
291 let typename = self.pop_type_definition()?;
292 let s = StackObject::VariableDeclaration(Field::new(&n.node, typename.into()));
293 self.stack.push(s);
294 }
295 Ok(TraversalResult::SkipChildren)
296 }
297 fn emit_address_type(
298 &mut self,
299 _mode: TreeTraversalMode,
300 node: &NodeAddressType,
301 ) -> Result<TraversalResult, String> {
302 node.identifier.visit(self)?;
303 let identifier = self.pop_ir_identifier()?;
304 self.stack
305 .push(StackObject::TypeDefinition(identifier.into()));
306 let mut main_type = self.pop_type_definition()?;
307 let mut fields = vec![];
308 for field in &node.address_fields {
309 field.visit(self)?;
310 let field = self.pop_variable_declaration()?;
311 fields.push(field);
312 }
313 main_type.address_type = Some(AddressType {
314 type_name: node.type_name.node.clone(),
315 fields: FieldList(fields),
316 });
317 self.stack.push(StackObject::TypeDefinition(main_type));
318 Ok(TraversalResult::SkipChildren)
319 }
320
321 fn emit_full_expression(
322 &mut self,
323 _mode: TreeTraversalMode,
324 _node: &NodeFullExpression,
325 ) -> Result<TraversalResult, String> {
326 Ok(TraversalResult::SkipChildren)
327 }
328
329 fn emit_message_entry(
330 &mut self,
331 _mode: TreeTraversalMode,
332 _node: &NodeMessageEntry,
333 ) -> Result<TraversalResult, String> {
334 unimplemented!();
335 }
336 fn emit_pattern_match_expression_clause(
337 &mut self,
338 _mode: TreeTraversalMode,
339 _node: &NodePatternMatchExpressionClause,
340 ) -> Result<TraversalResult, String> {
341 unimplemented!();
342 }
343 fn emit_atomic_expression(
344 &mut self,
345 _mode: TreeTraversalMode,
346 _node: &NodeAtomicExpression,
347 ) -> Result<TraversalResult, String> {
348 unimplemented!();
349 }
350 fn emit_contract_type_arguments(
351 &mut self,
352 _mode: TreeTraversalMode,
353 _node: &NodeContractTypeArguments,
354 ) -> Result<TraversalResult, String> {
355 unimplemented!();
356 }
357 fn emit_value_literal(
358 &mut self,
359 _mode: TreeTraversalMode,
360 _node: &NodeValueLiteral,
361 ) -> Result<TraversalResult, String> {
362 Ok(TraversalResult::SkipChildren)
363 }
364 fn emit_map_access(
365 &mut self,
366 _mode: TreeTraversalMode,
367 _node: &NodeMapAccess,
368 ) -> Result<TraversalResult, String> {
369 unimplemented!();
370 }
371 fn emit_pattern(
372 &mut self,
373 _mode: TreeTraversalMode,
374 _node: &NodePattern,
375 ) -> Result<TraversalResult, String> {
376 Ok(TraversalResult::SkipChildren)
377 }
378 fn emit_argument_pattern(
379 &mut self,
380 _mode: TreeTraversalMode,
381 _node: &NodeArgumentPattern,
382 ) -> Result<TraversalResult, String> {
383 unimplemented!();
384 }
385 fn emit_pattern_match_clause(
386 &mut self,
387 _mode: TreeTraversalMode,
388 _node: &NodePatternMatchClause,
389 ) -> Result<TraversalResult, String> {
390 unimplemented!();
391 }
392 fn emit_blockchain_fetch_arguments(
393 &mut self,
394 _mode: TreeTraversalMode,
395 _node: &NodeBlockchainFetchArguments,
396 ) -> Result<TraversalResult, String> {
397 unimplemented!();
398 }
399
400 fn emit_statement(
401 &mut self,
402 _mode: TreeTraversalMode,
403 _node: &NodeStatement,
404 ) -> Result<TraversalResult, String> {
405 Ok(TraversalResult::SkipChildren)
406 }
407
408 fn emit_remote_fetch_statement(
409 &mut self,
410 _mode: TreeTraversalMode,
411 _node: &NodeRemoteFetchStatement,
412 ) -> Result<TraversalResult, String> {
413 unimplemented!();
414 }
415 fn emit_component_id(
416 &mut self,
417 _mode: TreeTraversalMode,
418 node: &NodeComponentId,
419 ) -> Result<TraversalResult, String> {
420 match node {
421 NodeComponentId::WithRegularId(name) => {
422 self.stack.push(StackObject::IrIdentifier(SrIdentifier {
423 unresolved: name.to_string(),
424 resolved: None,
425 type_reference: None,
426 kind: SrIdentifierKind::ComponentName,
427 is_definition: false,
428 }));
429 }
430 NodeComponentId::WithTypeLikeName(name) => {
431 self.stack.push(StackObject::IrIdentifier(SrIdentifier {
432 unresolved: name.to_string(),
433 resolved: None,
434 type_reference: None,
435 kind: SrIdentifierKind::ComponentName,
436 is_definition: false,
437 }));
438 }
439 }
440
441 Ok(TraversalResult::SkipChildren)
442 }
443
444 fn emit_component_parameters(
445 &mut self,
446 mode: TreeTraversalMode,
447 node: &NodeComponentParameters,
448 ) -> Result<TraversalResult, String> {
449 match mode {
450 TreeTraversalMode::Enter => {
451 for param in node.parameters.iter() {
452 let _ = param.visit(self)?;
453 let init_param = self.pop_variable_declaration()?;
454 self.contract.init_params.push(init_param);
455 }
456 }
457 TreeTraversalMode::Exit => {}
458 }
459 Ok(TraversalResult::Continue)
460 }
461
462 fn emit_parameter_pair(
463 &mut self,
464 _mode: TreeTraversalMode,
465 _node: &NodeParameterPair,
466 ) -> Result<TraversalResult, String> {
467 Ok(TraversalResult::Continue)
469 }
470
471 fn emit_component_body(
472 &mut self,
473 _mode: TreeTraversalMode,
474 _node: &NodeComponentBody,
475 ) -> Result<TraversalResult, String> {
476 Ok(TraversalResult::SkipChildren)
477 }
478
479 fn emit_statement_block(
480 &mut self,
481 _node: TreeTraversalMode,
482 _mode: &NodeStatementBlock,
483 ) -> Result<TraversalResult, String> {
484 Ok(TraversalResult::Continue)
485 }
486 fn emit_typed_identifier(
487 &mut self,
488 _mode: TreeTraversalMode,
489 node: &NodeTypedIdentifier,
490 ) -> Result<TraversalResult, String> {
491 let name = node.identifier_name.clone();
492 let _ = node.annotation.visit(self)?;
493
494 let typename = self.pop_type_definition()?;
495
496 let s = StackObject::VariableDeclaration(Field::new(&name.node, typename.into()));
497 self.stack.push(s);
498
499 Ok(TraversalResult::SkipChildren)
500 }
501 fn emit_type_annotation(
502 &mut self,
503 _mode: TreeTraversalMode,
504 _node: &NodeTypeAnnotation,
505 ) -> Result<TraversalResult, String> {
506 Ok(TraversalResult::Continue)
508 }
509
510 fn emit_program(
511 &mut self,
512 _mode: TreeTraversalMode,
513 _node: &NodeProgram,
514 ) -> Result<TraversalResult, String> {
515 Ok(TraversalResult::Continue)
516 }
517
518 fn emit_library_definition(
519 &mut self,
520 _mode: TreeTraversalMode,
521 _node: &NodeLibraryDefinition,
522 ) -> Result<TraversalResult, String> {
523 unimplemented!()
524 }
525
526 fn emit_library_single_definition(
527 &mut self,
528 _mode: TreeTraversalMode,
529 _node: &NodeLibrarySingleDefinition,
530 ) -> Result<TraversalResult, String> {
531 unimplemented!()
532 }
533
534 fn emit_contract_definition(
535 &mut self,
536 _mode: TreeTraversalMode,
537 node: &NodeContractDefinition,
538 ) -> Result<TraversalResult, String> {
539 let _ = node.contract_name.visit(self)?;
540 self.contract.name = node.contract_name.to_string();
541
542 let _ = node.parameters.visit(self)?;
543
544 if let Some(constraint) = &node.constraint {
545 let _ = constraint.visit(self)?;
546 }
547
548 for field in node.fields.iter() {
549 let _ = field.visit(self)?;
550 }
551
552 for component in node.components.iter() {
553 let _ = component.visit(self)?;
554 }
555
556 Ok(TraversalResult::SkipChildren)
557 }
558
559 fn emit_contract_field(
560 &mut self,
561 _mode: TreeTraversalMode,
562 node: &NodeContractField,
563 ) -> Result<TraversalResult, String> {
564 let _ = node.typed_identifier.visit(self)?;
565
566 let field = self.pop_variable_declaration()?;
567 let _ = node.right_hand_side.visit(self)?;
568
569 self.contract.fields.push(field);
570
571 Ok(TraversalResult::SkipChildren)
572 }
573 fn emit_with_constraint(
574 &mut self,
575 _mode: TreeTraversalMode,
576 _node: &NodeWithConstraint,
577 ) -> Result<TraversalResult, String> {
578 Ok(TraversalResult::Continue)
579 }
580 fn emit_component_definition(
581 &mut self,
582 _mode: TreeTraversalMode,
583 _node: &NodeComponentDefinition,
584 ) -> Result<TraversalResult, String> {
585 Ok(TraversalResult::Continue)
586 }
587 fn emit_procedure_definition(
588 &mut self,
589 _mode: TreeTraversalMode,
590 _node: &NodeProcedureDefinition,
591 ) -> Result<TraversalResult, String> {
592 Ok(TraversalResult::SkipChildren)
593 }
594
595 fn emit_transition_definition(
596 &mut self,
597 _mode: TreeTraversalMode,
598 node: &NodeTransitionDefinition,
599 ) -> Result<TraversalResult, String> {
600 let _ = node.name.visit(self)?;
602
603 let arguments = node
604 .parameters
605 .node
606 .parameters
607 .iter()
608 .map(|arg| {
609 let _ = arg.visit(self)?;
610 self.pop_variable_declaration()
611 })
612 .collect::<Result<Vec<Field>, _>>()?;
613
614 let mut function_name = self.pop_ir_identifier()?;
615 assert!(function_name.kind == SrIdentifierKind::ComponentName);
616 function_name.kind = SrIdentifierKind::TransitionName;
617 function_name.is_definition = true;
618
619 self.contract.transitions.push(Transition::new(
620 &function_name.unresolved,
621 FieldList(arguments),
622 ));
623
624 Ok(TraversalResult::SkipChildren)
625 }
626
627 fn emit_type_alternative_clause(
628 &mut self,
629 _mode: TreeTraversalMode,
630 _node: &NodeTypeAlternativeClause,
631 ) -> Result<TraversalResult, String> {
632 Ok(TraversalResult::SkipChildren)
633 }
634 fn emit_type_map_value_arguments(
635 &mut self,
636 mode: TreeTraversalMode,
637 node: &NodeTypeMapValueArguments,
638 ) -> Result<TraversalResult, String> {
639 match mode {
640 TreeTraversalMode::Enter => {
641 match node {
642 NodeTypeMapValueArguments::EnclosedTypeMapValue(_) => todo!(),
643 NodeTypeMapValueArguments::GenericMapValueArgument(g) => {
644 g.visit(self)?;
645 let identifier = self.pop_ir_identifier()?;
646 self.stack
647 .push(StackObject::TypeDefinition(identifier.into()));
648 }
649 NodeTypeMapValueArguments::MapKeyValueType(_, _) => todo!(),
650 };
651 }
652 TreeTraversalMode::Exit => (),
653 }
654 Ok(TraversalResult::SkipChildren)
655 }
656 fn emit_type_map_value_allowing_type_arguments(
657 &mut self,
658 mode: TreeTraversalMode,
659 node: &NodeTypeMapValueAllowingTypeArguments,
660 ) -> Result<TraversalResult, String> {
661 match mode {
662 TreeTraversalMode::Enter => {
663 match node {
664 NodeTypeMapValueAllowingTypeArguments::TypeMapValueNoArgs(m) => {
665 m.visit(self)?;
666 }
667 NodeTypeMapValueAllowingTypeArguments::TypeMapValueWithArgs(m, args) => {
668 m.visit(self)?;
669 let identifier = self.pop_ir_identifier()?;
670 self.stack
671 .push(StackObject::TypeDefinition(identifier.into()));
672 if !args.is_empty() {
673 let mut main_type = self.pop_type_definition()?;
674 for arg in args {
675 let _ = arg.visit(self)?;
676 let sub_type = self.pop_type_definition()?;
677 main_type.push_sub_type(sub_type);
678 }
679 self.stack.push(StackObject::TypeDefinition(main_type));
680 }
681 }
682 };
683 }
684 TreeTraversalMode::Exit => (),
685 }
686 Ok(TraversalResult::SkipChildren)
687 }
688}