1use std::fmt;
2use strum_macros::EnumString;
3use serde::{Deserialize, Serialize};
4use crate::types::Type;
5use crate::effects::EffectSet;
6
7#[derive(Default, PartialEq, Debug, Serialize, Deserialize, Clone, EnumString)]
8#[serde(tag="type")]
9pub enum AlephTree {
10 #[default]
11 Unit,
12 Break,
13 Continue,
14 Ellipsis,
15 #[serde(alias="Integer")]
16 Int{value: String},
17 Float{value: String},
18 Bool{value: String},
19 String{value: String},
20 Ident{value: String},
21 Bytes{elems: Vec<u8>},
22 Complex{real: String, imag: String},
23 HexLiteral{value: String},
24 Figurative{
25 #[serde(alias="figurativeType")]
26 figurative_type: String
27 },
28 Tuple{elems: Vec<Box<AlephTree>>},
29 Array{elems: Vec<Box<AlephTree>>},
30 Record{fields: Vec<Box<AlephTree>>},
31 Field{name: String, value: Box<AlephTree>},
32 Neg{expr: Box<AlephTree>},
33 Not{
34 #[serde(alias="boolExpr")]
35 bool_expr: Box<AlephTree>
36 },
37 BitNot{expr: Box<AlephTree>},
38 Abs{expr: Box<AlephTree>},
39 Add{
40 #[serde(alias="numberExpr1")]
41 number_expr1: Box<AlephTree>,
42 #[serde(alias="numberExpr2")]
43 number_expr2: Box<AlephTree>
44 },
45 Sub{
46 #[serde(alias="numberExpr1")]
47 number_expr1: Box<AlephTree>,
48 #[serde(alias="numberExpr2")]
49 number_expr2: Box<AlephTree>
50 },
51 Mul{
52 #[serde(alias="numberExpr1")]
53 number_expr1: Box<AlephTree>,
54 #[serde(alias="numberExpr2")]
55 number_expr2: Box<AlephTree>
56 },
57 Div{
58 #[serde(alias="numberExpr1")]
59 number_expr1: Box<AlephTree>,
60 #[serde(alias="numberExpr2")]
61 number_expr2: Box<AlephTree>
62 },
63 Mod{
64 #[serde(alias="numberExpr1")]
65 number_expr1: Box<AlephTree>,
66 #[serde(alias="numberExpr2")]
67 number_expr2: Box<AlephTree>
68 },
69 DivMod{
70 #[serde(alias="numberExpr1", alias="dividend")]
71 dividend: Box<AlephTree>,
72 #[serde(alias="numberExpr2", alias="divisor")]
73 divisor: Box<AlephTree>
74 },
75 MulDiv{
76 n1: Box<AlephTree>,
77 n2: Box<AlephTree>,
78 n3: Box<AlephTree>
79 },
80 MulDivMod{
81 n1: Box<AlephTree>,
82 n2: Box<AlephTree>,
83 n3: Box<AlephTree>
84 },
85 Pow{base: Box<AlephTree>, exponent: Box<AlephTree>},
86 Min{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
87 Max{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
88 And{
89 #[serde(alias="boolExpr1")]
90 bool_expr1: Box<AlephTree>,
91 #[serde(alias="boolExpr2")]
92 bool_expr2: Box<AlephTree>
93 },
94 Or{
95 #[serde(alias="boolExpr1")]
96 bool_expr1: Box<AlephTree>,
97 #[serde(alias="boolExpr2")]
98 bool_expr2: Box<AlephTree>
99 },
100 Xor{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
101 BitAnd{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
102 BitOr{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
103 BitXor{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
104 LShift{expr: Box<AlephTree>, amount: Box<AlephTree>},
105 RShift{expr: Box<AlephTree>, amount: Box<AlephTree>},
106 Eq{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
107 NotEq{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
108 LT{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
109 LE{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
110 GT{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
111 GE{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
112 In{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
113 If{
114 condition: Box<AlephTree>,
115 then: Box<AlephTree>,
116 #[serde(alias="else")]
117 els: Box<AlephTree>
118 },
119 While{
120 #[serde(alias="initExpr")]
121 init_expr: Box<AlephTree>,
122 condition: Box<AlephTree>,
123 #[serde(alias="loopExpr")]
124 loop_expr: Box<AlephTree>,
125 #[serde(alias="postExpr")]
126 post_expr: Box<AlephTree>
127 },
128 For{
129 var: String,
130 start: Box<AlephTree>,
131 end: Box<AlephTree>,
132 step: Option<Box<AlephTree>>,
133 body: Box<AlephTree>,
134 reverse: bool
135 },
136 Loop{
137 name: Option<String>,
138 body: Vec<Box<AlephTree>>
139 },
140 DoLoop{
141 #[serde(alias="loopVar")]
142 loop_var: Option<String>,
143 #[serde(alias="startIndex")]
144 start: Option<Box<AlephTree>>,
145 #[serde(alias="endIndex")]
146 end: Option<Box<AlephTree>>,
147 by: Option<Box<AlephTree>>,
148 #[serde(alias="whileCond")]
149 while_cond: Option<Box<AlephTree>>,
150 #[serde(alias="untilCond")]
151 until_cond: Option<Box<AlephTree>>,
152 body: Vec<Box<AlephTree>>
153 },
154 Case{
155 expr: Box<AlephTree>,
156 #[serde(alias="caseList", alias="whenClauses", alias="alternatives", alias="ofClauses")]
157 cases: Vec<Box<AlephTree>>,
158 #[serde(alias="whenOther", alias="otherwise", alias="default")]
159 default_case: Option<Box<AlephTree>>
160 },
161 CaseBranch{
162 #[serde(alias="condition", alias="selectionObject", alias="choices", alias="value")]
163 pattern: Box<AlephTree>,
164 #[serde(alias="caseExpr", alias="body", alias="statements")]
165 body: Vec<Box<AlephTree>>
166 },
167 Match{
168 expr: Box<AlephTree>,
169 #[serde(alias="caseList")]
170 case_list: Vec<Box<AlephTree>>
171 },
172 MatchLine{
173 condition: Box<AlephTree>,
174 #[serde(alias="caseExpr")]
175 case_expr: Box<AlephTree>
176 },
177 ProcedureDef{
178 name: String,
179 #[serde(alias="procedureType")]
180 proc_type: Option<String>,
181 parameters: Vec<Box<AlephTree>>,
182 #[serde(alias="returnType")]
183 return_type: Option<Box<AlephTree>>,
184 attributes: Vec<String>,
185 declarations: Vec<Box<AlephTree>>,
186 body: Vec<Box<AlephTree>>
187 },
188 Parameter{
189 name: String,
190 #[serde(alias="paramType", alias="param_type")]
191 param_type: Option<Box<AlephTree>>,
192 mode: Option<String>,
193 default: Option<Box<AlephTree>>
194 },
195 VarDecl{
196 name: String,
197 #[serde(alias="levelNumber")]
198 level: Option<String>,
199 #[serde(alias="varType", alias="var_type", alias="objectType", alias="picture")]
200 var_type: Option<Box<AlephTree>>,
201 #[serde(alias="initialValue", alias="initial_value")]
202 initial_value: Option<Box<AlephTree>>,
203 #[serde(alias="isConstant", alias="is_constant")]
204 is_constant: bool,
205 #[serde(alias="isAliased", alias="is_aliased")]
206 is_aliased: bool,
207 storage: Option<String>,
208 #[serde(alias="occursClause")]
209 occurs: Option<String>,
210 usage: Option<String>,
211 attributes: Vec<String>
212 },
213 StructDecl{
214 name: String,
215 #[serde(alias="levelNumber")]
216 level: Option<String>,
217 members: Vec<Box<AlephTree>>,
218 attributes: Vec<String>
219 },
220 TypeDecl{
221 name: String,
222 definition: Box<AlephTree>,
223 attributes: Vec<String>
224 },
225 Let{
226 var: String,
227 #[serde(alias="isPointer")]
228 is_pointer: String,
229 value: Box<AlephTree>,
230 expr: Box<AlephTree>
231 },
232 LetRec{
233 name: String,
234 args: Vec<Box<AlephTree>>,
235 body: Box<AlephTree>
236 },
237 Var{
238 var: String,
239 #[serde(alias="isPointer")]
240 is_pointer: String
241 },
242 TypeRef{
243 name: String,
244 #[serde(alias="qualifierList")]
245 qualifiers: Vec<String>
246 },
247 ArrayType{
248 #[serde(alias="elementType")]
249 element_type: Box<AlephTree>,
250 dimensions: Vec<Box<AlephTree>>
251 },
252 PointerType{
253 #[serde(alias="targetType")]
254 target_type: Box<AlephTree>,
255 #[serde(alias="isAllAccess")]
256 is_all: bool
257 },
258 RangeType{
259 start: Box<AlephTree>,
260 end: Box<AlephTree>
261 },
262 EnumType{
263 values: Vec<String>
264 },
265 RecordType{
266 fields: Vec<Box<AlephTree>>
267 },
268 FieldDecl{
269 name: String,
270 #[serde(alias="fieldType")]
271 field_type: Box<AlephTree>,
272 attributes: Vec<String>
273 },
274 SubtypeDecl{
275 name: String,
276 #[serde(alias="baseType")]
277 base_type: Box<AlephTree>,
278 constraint: Option<Box<AlephTree>>
279 },
280 Get{
281 #[serde(alias="arrayName")]
282 array_name: String,
283 elem: Box<AlephTree>
284 },
285 Put{
286 #[serde(alias="arrayName")]
287 array_name: String,
288 elem: Box<AlephTree>,
289 value: Box<AlephTree>,
290 insert: String
291 },
292 Remove{
293 #[serde(alias="arrayName")]
294 array_name: String,
295 elem: Box<AlephTree>,
296 #[serde(alias="isValue")]
297 is_value: String
298 },
299 Length{var: String},
300 Slice{
301 array: Box<AlephTree>,
302 start: Option<Box<AlephTree>>,
303 end: Option<Box<AlephTree>>
304 },
305 Alloc{
306 var: Box<AlephTree>,
307 #[serde(alias="setPointer", alias="typeOrExpr")]
308 target: Option<Box<AlephTree>>
309 },
310 Free{
311 var: Box<AlephTree>
312 },
313 Fetch{
314 addr: Box<AlephTree>,
315 #[serde(alias="fetchType")]
316 fetch_type: Option<String>
317 },
318 Store{
319 value: Box<AlephTree>,
320 addr: Box<AlephTree>,
321 #[serde(alias="storeType")]
322 store_type: Option<String>
323 },
324 StoreOp{
325 value: Box<AlephTree>,
326 addr: Box<AlephTree>,
327 op: String
328 },
329 App{
330 #[serde(alias="objectName")]
331 object_name: String,
332 fun: Box<AlephTree>,
333 #[serde(alias="paramList")]
334 param_list: Vec<Box<AlephTree>>
335 },
336 Call{
337 #[serde(alias="programName", alias="entryName")]
338 target: Box<AlephTree>,
339 #[serde(alias="usingParameters")]
340 parameters: Option<Vec<Box<AlephTree>>>,
341 #[serde(alias="givingParameter")]
342 returning: Option<Box<AlephTree>>,
343 #[serde(alias="onException")]
344 on_error: Option<Box<AlephTree>>
345 },
346 Stmts{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
347 Block{statements: Vec<Box<AlephTree>>},
348 Assignment{target: Box<AlephTree>, value: Box<AlephTree>},
349 #[serde(alias="Return")]
350 Return{value: Box<AlephTree>},
351 GoTo{
352 #[serde(alias="targetParagraph", alias="target")]
353 target: String,
354 #[serde(alias="dependingOn")]
355 depending_on: Option<Box<AlephTree>>
356 },
357 Label{
358 name: String,
359 #[serde(alias="labelType")]
360 label_type: Option<String>
361 },
362 Exit,
363 Move{
364 source: Box<AlephTree>,
365 #[serde(alias="targetList")]
366 targets: Vec<Box<AlephTree>>
367 },
368 Compute{
369 target: Box<AlephTree>,
370 expression: Box<AlephTree>,
371 #[serde(alias="onSizeError")]
372 on_error: Option<Box<AlephTree>>
373 },
374 Print{
375 #[serde(alias="itemList", alias="items")]
376 items: Vec<Box<AlephTree>>,
377 #[serde(alias="uponDevice", alias="toFile")]
378 destination: Option<String>,
379 #[serde(alias="formatItems")]
380 format: Option<Vec<Box<AlephTree>>>,
381 options: Vec<String>
382 },
383 Input{
384 #[serde(alias="target", alias="variables")]
385 targets: Vec<Box<AlephTree>>,
386 #[serde(alias="fromDevice", alias="fromFile")]
387 source: Option<String>,
388 options: Vec<String>
389 },
390 FileOpen{
391 #[serde(alias="fileName", alias="file")]
392 file: String,
393 mode: String,
394 attributes: Vec<String>
395 },
396 FileClose{
397 #[serde(alias="fileList", alias="files")]
398 files: Vec<String>
399 },
400 FileRead{
401 #[serde(alias="fileName")]
402 file_name: String,
403 #[serde(alias="intoClause")]
404 into: Option<Box<AlephTree>>,
405 #[serde(alias="keyClause")]
406 key: Option<Box<AlephTree>>,
407 #[serde(alias="atEndClause", alias="onEnd")]
408 on_end: Option<Box<AlephTree>>,
409 #[serde(alias="notAtEndClause")]
410 not_on_end: Option<Box<AlephTree>>
411 },
412 FileWrite{
413 #[serde(alias="recordName")]
414 record_name: String,
415 #[serde(alias="fromClause")]
416 from: Option<Box<AlephTree>>,
417 #[serde(alias="advancingClause")]
418 options: Vec<String>
419 },
420 FileConfig{
421 #[serde(alias="fileName")]
422 file_name: String,
423 #[serde(alias="assignTo")]
424 assign_to: Option<String>,
425 #[serde(alias="accessMode")]
426 access_mode: Option<String>,
427 #[serde(alias="organizationMode")]
428 organization_mode: Option<String>,
429 #[serde(alias="recordDescription")]
430 record_description: Option<Vec<Box<AlephTree>>>,
431 #[serde(alias="blockContains")]
432 block_contains: Option<String>,
433 #[serde(alias="recordContains")]
434 record_contains: Option<String>
435 },
436 StringOp{
437 operation: String,
438 #[serde(alias="sourceItems", alias="sourceItem")]
439 sources: Vec<Box<AlephTree>>,
440 #[serde(alias="delimitedBy")]
441 delimiter: Option<Box<AlephTree>>,
442 #[serde(alias="intoItem", alias="intoItems")]
443 targets: Vec<Box<AlephTree>>,
444 #[serde(alias="withPointer")]
445 pointer: Option<Box<AlephTree>>,
446 #[serde(alias="onOverflow", alias="tallyingClause", alias="replacingClause")]
447 clauses: Vec<Box<AlephTree>>
448 },
449 #[serde(alias="Import")]
450 Iprt{
451 name: String,
452 items: Vec<String>
453 },
454 Export{
455 items: Vec<Box<AlephTree>>,
456 #[serde(alias="exportType")]
457 export_type: Option<String>
458 },
459 Module{
460 name: String,
461 #[serde(alias="moduleType")]
462 module_type: String,
463 #[serde(alias="programId")]
464 id: Option<String>,
465 declarations: Vec<Box<AlephTree>>,
466 body: Option<Vec<Box<AlephTree>>>,
467 initialization: Option<Vec<Box<AlephTree>>>
468 },
469 Division{
470 #[serde(alias="divisionType")]
471 division_type: String,
472 sections: Vec<Box<AlephTree>>
473 },
474 Section{
475 name: String,
476 #[serde(alias="sectionType")]
477 section_type: Option<String>,
478 content: Vec<Box<AlephTree>>
479 },
480 #[serde(alias="Class")]
481 Clss{
482 name: String,
483 #[serde(alias="attributList")]
484 attribute_list: Vec<String>,
485 #[serde(alias="extends")]
486 extends: Option<Box<AlephTree>>,
487 #[serde(alias="implements")]
488 implements: Vec<Box<AlephTree>>,
489 body: Box<AlephTree>
490 },
491 New{
492 constructor: Box<AlephTree>,
493 args: Vec<Box<AlephTree>>
494 },
495 This,
496 Super{
497 #[serde(alias="memberAccess")]
498 member: Option<String>
499 },
500 Member{
501 object: Box<AlephTree>,
502 member: String,
503 #[serde(alias="isOptional")]
504 is_optional: bool
505 },
506 Spread{
507 expr: Box<AlephTree>,
508 #[serde(alias="spreadType")]
509 spread_type: String
510 },
511 Destructure{
512 pattern: Box<AlephTree>,
513 value: Box<AlephTree>,
514 #[serde(alias="destructureType")]
515 destructure_type: String
516 },
517 TryCatch{
518 #[serde(alias="tryBlock")]
519 try_block: Box<AlephTree>,
520 #[serde(alias="catchClauses", alias="handlers")]
521 catch_clauses: Vec<Box<AlephTree>>,
522 #[serde(alias="finallyBlock")]
523 finally_block: Option<Box<AlephTree>>
524 },
525 CatchClause{
526 #[serde(alias="exceptionType", alias="exceptionChoices")]
527 exception_types: Vec<String>,
528 var: Option<String>,
529 body: Box<AlephTree>
530 },
531 OnCondition{
532 condition: String,
533 #[serde(alias="snapOption")]
534 options: Vec<String>,
535 handler: Box<AlephTree>
536 },
537 Raise{
538 #[serde(alias="exception")]
539 condition: Box<AlephTree>
540 },
541 Signal{
542 condition: String
543 },
544 Revert{
545 condition: String
546 },
547 ExceptionDecl{
548 name: String
549 },
550 #[serde(alias="Comment")]
551 Comment{value: String},
552 #[serde(alias="CommentMulti")]
553 CommentMulti{value: String},
554 Assert{
555 condition: Box<AlephTree>,
556 message: Box<AlephTree>
557 },
558 Generic{
559 name: String,
560 #[serde(alias="genericType")]
561 generic_type: String,
562 #[serde(alias="genericParams")]
563 generic_params: Vec<Box<AlephTree>>,
564 body: Box<AlephTree>
565 },
566 GenericParam{
567 name: String,
568 #[serde(alias="paramKind")]
569 param_kind: String,
570 constraint: Option<Box<AlephTree>>,
571 default: Option<Box<AlephTree>>
572 },
573 Instantiation{
574 name: String,
575 #[serde(alias="genericName")]
576 generic_name: String,
577 #[serde(alias="actualParams")]
578 actual_params: Vec<Box<AlephTree>>
579 },
580 Attribute{
581 prefix: Box<AlephTree>,
582 attribute: String,
583 args: Option<Vec<Box<AlephTree>>>
584 },
585 Pragma{
586 name: String,
587 args: Vec<Box<AlephTree>>
588 },
589 RepresentationClause{
590 name: String,
591 #[serde(alias="clauseType")]
592 clause_type: String,
593 specification: Box<AlephTree>
594 },
595 Renaming{
596 #[serde(alias="newName")]
597 new_name: String,
598 #[serde(alias="renamedEntity", alias="redefinedItem")]
599 old_name: Box<AlephTree>,
600 #[serde(alias="entityType")]
601 rename_type: Option<Box<AlephTree>>
602 },
603 Execute{
604 target: Box<AlephTree>,
605 #[serde(alias="executionType")]
606 exec_type: Option<String>
607 },
608 Perform{
609 #[serde(alias="targetParagraph")]
610 target: Option<String>,
611 #[serde(alias="fromParagraph")]
612 from: Option<String>,
613 #[serde(alias="throughParagraph")]
614 through: Option<String>,
615 #[serde(alias="timesClause")]
616 times: Option<Box<AlephTree>>,
617 #[serde(alias="untilClause")]
618 until: Option<Box<AlephTree>>,
619 #[serde(alias="varyingClause")]
620 varying: Option<Box<AlephTree>>,
621 #[serde(alias="inlineStatements")]
622 inline: Option<Vec<Box<AlephTree>>>
623 },
624 StackOp{
625 operation: String,
626 #[serde(alias="operands")]
627 args: Vec<Box<AlephTree>>
628 },
629 TaskType{
630 name: String,
631 #[serde(alias="discriminants")]
632 parameters: Option<Vec<Box<AlephTree>>>,
633 entries: Vec<Box<AlephTree>>,
634 body: Vec<Box<AlephTree>>
635 },
636 ProtectedType{
637 name: String,
638 #[serde(alias="discriminants")]
639 parameters: Option<Vec<Box<AlephTree>>>,
640 declarations: Vec<Box<AlephTree>>
641 },
642 ProtectedBody{
643 name: String,
644 bodies: Vec<Box<AlephTree>>
645 },
646 Accept{
647 #[serde(alias="entryName")]
648 entry_name: String,
649 parameters: Option<Vec<Box<AlephTree>>>,
650 body: Option<Vec<Box<AlephTree>>>
651 },
652 Select{
653 alternatives: Vec<Box<AlephTree>>,
654 #[serde(alias="elseClause")]
655 else_clause: Option<Vec<Box<AlephTree>>>
656 },
657 SelectiveAccept{
658 #[serde(alias="guardCondition")]
659 guard_condition: Option<Box<AlephTree>>,
660 #[serde(alias="acceptStmt")]
661 accept_stmt: Box<AlephTree>,
662 statements: Vec<Box<AlephTree>>
663 },
664 Delay{
665 #[serde(alias="delayType")]
666 delay_type: String,
667 expression: Box<AlephTree>
668 },
669 Abort{
670 targets: Vec<String>
671 },
672 Aggregate{
673 components: Vec<Box<AlephTree>>
674 },
675 ComponentAssoc{
676 choices: Option<Vec<Box<AlephTree>>>,
677 expression: Box<AlephTree>
678 },
679 Qualified{
680 #[serde(alias="typeName")]
681 type_name: Box<AlephTree>,
682 expression: Box<AlephTree>
683 },
684 MemoryOp{
685 operation: String,
686 #[serde(alias="operands")]
687 args: Vec<Box<AlephTree>>
688 },
689 DataOp{
690 operation: String,
691 value: Box<AlephTree>
692 },
693 Emit{
694 #[serde(alias="content")]
695 value: Box<AlephTree>,
696 #[serde(alias="emitType")]
697 emit_type: Option<String>
698 },
699 Immediate,
700 Recursive,
701 Forget{
702 target: String
703 },
704 Postpone{
705 word: String
706 },
707 Literal{
708 value: Box<AlephTree>
709 },
710 CompileTime{
711 expression: Box<AlephTree>
712 },
713 CreateDoes{
714 name: String,
715 #[serde(alias="allotSize")]
716 allot_size: Option<Box<AlephTree>>,
717 #[serde(alias="doesBody")]
718 does_body: Option<Vec<Box<AlephTree>>>
719 },
720 Introspect{
721 operation: String,
722 target: Option<String>
723 },
724 Convert{
725 value: Box<AlephTree>,
726 #[serde(alias="fromType")]
727 from_type: String,
728 #[serde(alias="toType")]
729 to_type: String
730 },
731 Await{
732 expr: Box<AlephTree>
733 },
734 Async{
735 body: Box<AlephTree>
736 },
737 Yield{
738 value: Option<Box<AlephTree>>
739 },
740 Typeof{
741 expr: Box<AlephTree>
742 },
743 Instanceof{
744 expr: Box<AlephTree>,
745 type_expr: Box<AlephTree>
746 },
747 Nullish{
748 expr: Box<AlephTree>,
749 default: Box<AlephTree>
750 },
751 Optional{
752 base: Box<AlephTree>,
753 #[serde(alias="optionalType")]
754 optional_type: String
755 },
756 Decorator{
757 name: String,
758 args: Vec<Box<AlephTree>>,
759 target: Box<AlephTree>
760 },
761 TableOp{
762 operation: String,
763 table: Box<AlephTree>,
764 index: Option<Box<AlephTree>>,
765 value: Option<Box<AlephTree>>
766 },
767 Global{
768 name: String,
769 #[serde(alias="globalType")]
770 global_type: Box<AlephTree>,
771 mutable: bool,
772 #[serde(alias="initialValue")]
773 initial_value: Option<Box<AlephTree>>
774 },
775 Local{
776 name: String,
777 #[serde(alias="localType")]
778 local_type: Box<AlephTree>
779 },
780 Br{
781 depth: Box<AlephTree>,
782 condition: Option<Box<AlephTree>>
783 },
784 Unreachable,
785 Nop,
786 UnionType{
787 variants: Vec<Box<AlephTree>>
788 },
789 Trait{
790 name: String,
791 #[serde(alias="typeParams")]
792 type_params: Vec<Box<AlephTree>>,
793 #[serde(alias="superTraits")]
794 super_traits: Vec<Box<AlephTree>>,
795 items: Vec<Box<AlephTree>>
796 },
797 Impl{
798 trait_ref: Option<Box<AlephTree>>,
799 #[serde(alias="forType")]
800 for_type: Box<AlephTree>,
801 items: Vec<Box<AlephTree>>
802 },
803 Channel{
804 name: String,
805 #[serde(alias="channelType")]
806 channel_type: Box<AlephTree>,
807 capacity: Option<Box<AlephTree>>
808 },
809 Send{
810 channel: Box<AlephTree>,
811 value: Box<AlephTree>
812 },
813 Receive{
814 channel: Box<AlephTree>,
815 timeout: Option<Box<AlephTree>>
816 },
817 Spawn{
818 target: Box<AlephTree>,
819 args: Vec<Box<AlephTree>>
820 },
821 Macro{
822 name: String,
823 parameters: Vec<Box<AlephTree>>,
824 body: Box<AlephTree>,
825 #[serde(alias="macroType")]
826 macro_type: Option<String>
827 },
828 MacroInvoke{
829 name: String,
830 args: Vec<Box<AlephTree>>
831 },
832 Pipe{
833 expr: Box<AlephTree>,
834 operations: Vec<Box<AlephTree>>
835 },
836 Comprehension{
837 #[serde(alias="compType")]
838 comp_type: String,
839 expr: Box<AlephTree>,
840 clauses: Vec<Box<AlephTree>>
841 },
842 CompClause{
843 #[serde(alias="clauseType")]
844 clause_type: String,
845 pattern: Option<Box<AlephTree>>,
846 iter: Option<Box<AlephTree>>,
847 condition: Option<Box<AlephTree>>
848 },
849 With{
850 resources: Vec<Box<AlephTree>>,
851 body: Box<AlephTree>
852 },
853 Query{
854 #[serde(alias="queryType")]
855 query_type: String,
856 #[serde(alias="selectClause")]
857 select: Option<Box<AlephTree>>,
858 #[serde(alias="fromClause")]
859 from: Option<Vec<Box<AlephTree>>>,
860 #[serde(alias="whereClause")]
861 where_clause: Option<Box<AlephTree>>,
862 #[serde(alias="joinClauses")]
863 joins: Vec<Box<AlephTree>>,
864 #[serde(alias="groupByClause")]
865 group_by: Option<Vec<Box<AlephTree>>>,
866 #[serde(alias="havingClause")]
867 having: Option<Box<AlephTree>>,
868 #[serde(alias="orderByClause")]
869 order_by: Option<Vec<Box<AlephTree>>>,
870 limit: Option<Box<AlephTree>>,
871 offset: Option<Box<AlephTree>>
872 },
873 Join{
874 #[serde(alias="joinType")]
875 join_type: String,
876 source: Box<AlephTree>,
877 condition: Box<AlephTree>
878 },
879 Constraint{
880 #[serde(alias="constraintType")]
881 constraint_type: String,
882 expressions: Vec<Box<AlephTree>>
883 },
884 Clause{
885 head: Box<AlephTree>,
886 body: Vec<Box<AlephTree>>
887 },
888 Unify{
889 expr1: Box<AlephTree>,
890 expr2: Box<AlephTree>
891 },
892 Lifetime{
893 name: String,
894 constraint: Option<Box<AlephTree>>
895 },
896 Borrow{
897 expr: Box<AlephTree>,
898 mutable: bool,
899 lifetime: Option<String>
900 },
901 Unsafe{
902 body: Box<AlephTree>
903 },
904
905 Intend{
909 name: String,
910 params: Vec<Box<AlephTree>>,
911 body: Box<AlephTree>
912 },
913
914 Suggest{
916 var: String,
917 context: Box<AlephTree>,
918 options: Vec<Box<AlephTree>>,
919 fallback: Option<Box<AlephTree>>
920 },
921
922 Act{
924 intention: Box<AlephTree>,
925 effect: Option<Box<AlephTree>>
926 },
927
928 Remember{
930 key: Box<AlephTree>,
931 value: Box<AlephTree>,
932 ttl: Option<Box<AlephTree>>
933 },
934
935 Perceive{
937 source: Box<AlephTree>,
938 pattern: Option<Box<AlephTree>>,
939 var: Option<String>
940 },
941
942 Typed{
949 inner: Box<AlephTree>,
950 ty: Type
951 },
952
953 TypeDef{
958 name: String,
959 variants: Vec<crate::types::Variant>
960 },
961
962 WithEffects{
965 inner: Box<AlephTree>,
966 effects: EffectSet
967 },
968}
969
970pub fn json_parse(source: String) -> AlephTree {
971 serde_json::from_str(&source).unwrap()
972}
973
974pub fn to_json(ast: AlephTree) -> String {
975 serde_json::to_string_pretty(&ast).unwrap()
976}
977
978impl FromIterator<AlephTree> for Vec<Box<AlephTree>> {
979 fn from_iter<I: IntoIterator<Item=AlephTree>>(iter : I) -> Self {
980 let mut result: Vec<Box<AlephTree>> = Vec::new();
981 for node in iter {
982 result.push(Box::new(node));
983 }
984 result
985 }
986}
987
988impl fmt::Display for AlephTree {
989 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
990 match self {
991 e => write!(f, "{:?}", e),
992 }
993 }
994}
995
996impl AlephTree {
997 pub fn to_string_value(&self) -> String {
998 match self {
999 AlephTree::Bool { value } => value.to_string(),
1000 AlephTree::Int { value } => value.to_string(),
1001 AlephTree::Float { value } => value.to_string(),
1002 AlephTree::String { value } => value.to_string(),
1003 AlephTree::Ident { value } => value.to_string(),
1004 AlephTree::Bytes { elems } => match std::str::from_utf8(elems) {
1005 Ok(s) => s.to_string(),
1006 Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
1007 },
1008 AlephTree::Figurative { figurative_type } => figurative_type.to_string(),
1009 AlephTree::HexLiteral { value } => value.to_string(),
1010 _ => {
1011 println!("Can't evaluate to_string_value : {}", self);
1012 panic!()
1013 }
1014 }
1015 }
1016}
1017
1018#[cfg(test)]
1019mod tests {
1020 use super::*;
1021 use crate::effects::Effect;
1022 use crate::types::{Type, Variant};
1023
1024 #[test]
1025 fn typed_node_round_trips_through_json() {
1026 let node = AlephTree::Typed {
1027 inner: Box::new(AlephTree::Ident { value: "n".to_string() }),
1028 ty: Type::Int,
1029 };
1030 let json = to_json(node.clone());
1031 let back = json_parse(json);
1032 assert_eq!(node, back);
1033 }
1034
1035 #[test]
1036 fn typed_node_wire_format_is_locked() {
1037 let node = AlephTree::Typed {
1038 inner: Box::new(AlephTree::Ident { value: "n".to_string() }),
1039 ty: Type::Int,
1040 };
1041 assert_eq!(
1042 to_json(node),
1043 "{\n \"type\": \"Typed\",\n \"inner\": {\n \"type\": \"Ident\",\n \"value\": \"n\"\n },\n \"ty\": {\n \"type\": \"Int\"\n }\n}"
1044 );
1045 }
1046
1047 #[test]
1048 fn type_def_round_trips_through_json() {
1049 let node = AlephTree::TypeDef {
1050 name: "Shape".to_string(),
1051 variants: vec![
1052 Variant { name: "Circle".to_string(), fields: vec![Type::Float] },
1053 Variant { name: "Rect".to_string(), fields: vec![Type::Float, Type::Float] },
1054 ],
1055 };
1056 let json = to_json(node.clone());
1057 let back = json_parse(json);
1058 assert_eq!(node, back);
1059 }
1060
1061 #[test]
1062 fn with_effects_node_round_trips_through_json() {
1063 let node = AlephTree::WithEffects {
1064 inner: Box::new(AlephTree::App {
1065 object_name: "".to_string(),
1066 fun: Box::new(AlephTree::Ident { value: "print".to_string() }),
1067 param_list: Vec::new(),
1068 }),
1069 effects: crate::effects::EffectSet::from([Effect::Io, Effect::Net]),
1070 };
1071 let json = to_json(node.clone());
1072 let back = json_parse(json);
1073 assert_eq!(node, back);
1074 }
1075}