1use std::fmt;
2use strum_macros::EnumString;
3use serde::{Deserialize, Serialize};
4
5#[derive(Default, PartialEq, Debug, Serialize, Deserialize, Clone, EnumString)]
6#[serde(tag="type")]
7pub enum AlephTree {
8 #[default]
9 Unit,
10 Break,
11 Continue,
12 Ellipsis,
13 #[serde(alias="Integer")]
14 Int{value:String},
15 Float{value:String},
16 Bool{value:String},
17 String{value:String},
18 Ident{value:String},
19 Bytes{elems: Vec<u8>},
20 Complex{real: String, imag: String},
21 Tuple {
22 elems: Vec<Box<AlephTree>>
23 },
24 Array {
25 elems: Vec<Box<AlephTree>>
26 },
27 Neg{
28 expr:Box<AlephTree>,
29 },
30 Not{
31 #[serde(alias="boolExpr")]
32 bool_expr:Box<AlephTree>,
33 },
34 And{
35 #[serde(alias="boolExpr1")]
36 bool_expr1:Box<AlephTree>,
37 #[serde(alias="boolExpr2")]
38 bool_expr2:Box<AlephTree>
39 },
40 Or{
41 #[serde(alias="boolExpr1")]
42 bool_expr1:Box<AlephTree>,
43 #[serde(alias="boolExpr2")]
44 bool_expr2:Box<AlephTree>
45 },
46 Add{
47 #[serde(alias="numberExpr1")]
48 number_expr1:Box<AlephTree>,
49 #[serde(alias="numberExpr2")]
50 number_expr2:Box<AlephTree>
51 },
52 Sub{
53 #[serde(alias="numberExpr1")]
54 number_expr1:Box<AlephTree>,
55 #[serde(alias="numberExpr2")]
56 number_expr2:Box<AlephTree>
57 },
58 Mul{
59 #[serde(alias="numberExpr1")]
60 number_expr1:Box<AlephTree>,
61 #[serde(alias="numberExpr2")]
62 number_expr2:Box<AlephTree>
63 },
64 Div{
65 #[serde(alias="numberExpr1")]
66 number_expr1:Box<AlephTree>,
67 #[serde(alias="numberExpr2")]
68 number_expr2:Box<AlephTree>
69 },
70 Eq{
71 expr1: Box<AlephTree>,
72 expr2: Box<AlephTree>,
73 },
74 LE{
75 expr1: Box<AlephTree>,
76 expr2: Box<AlephTree>,
77 },
78 In{
79 expr1: Box<AlephTree>,
80 expr2: Box<AlephTree>,
81 },
82 If{
83 condition: Box<AlephTree>,
84 then: Box<AlephTree>,
85 #[serde(alias="else")]
86 els: Box<AlephTree>
87 },
88 While{
89 #[serde(alias="initExpr")]
90 init_expr: Box<AlephTree>,
91 condition: Box<AlephTree>,
92 #[serde(alias="loopExpr")]
93 loop_expr: Box<AlephTree>,
94 #[serde(alias="postExpr")]
95 post_expr: Box<AlephTree>,
96 },
97 Let{
98 var: String,
99 #[serde(alias="isPointer")]
100 is_pointer: String,
101 value: Box<AlephTree>,
102 expr: Box<AlephTree>
103 },
104 LetRec{
105 name: String,
106 args: Vec<Box<AlephTree>>,
107 body: Box<AlephTree>
108 },
109 Get{
110 #[serde(alias="arrayName")]
111 array_name: String,
112 elem: Box<AlephTree>
113 },
114 Put{
115 #[serde(alias="arrayName")]
116 array_name: String,
117 elem: Box<AlephTree>,
118 value: Box<AlephTree>,
119 insert: String
120 },
121 Remove{
122 #[serde(alias="arrayName")]
123 array_name: String,
124 elem: Box<AlephTree>,
125 #[serde(alias="isValue")]
126 is_value: String,
127 },
128 Length{
129 var:String
130 },
131 Match{
132 expr: Box<AlephTree>,
133 #[serde(alias="caseList")]
134 case_list: Vec<Box<AlephTree>>
135 },
136 MatchLine {
137 condition: Box<AlephTree>,
138 #[serde(alias="caseExpr")]
139 case_expr: Box<AlephTree>
140 },
141 Var{
142 var: String,
143 #[serde(alias="isPointer")]
144 is_pointer: String,
145 },
146 App{
147 #[serde(alias="objectName")]
148 object_name: String,
149 fun: Box<AlephTree>,
150 #[serde(alias="paramList")]
151 param_list: Vec<Box<AlephTree>>
152 },
153 Stmts {
154 expr1: Box<AlephTree>,
155 expr2: Box<AlephTree>
156 },
157 #[serde(alias="Import")]
158 Iprt{
159 name: String
160 },
161 #[serde(alias="Class")]
162 Clss{
163 name: String,
164 #[serde(alias="attributList")]
165 attribute_list: Vec<String>,
166 body: Box<AlephTree>
167 },
168 #[serde(alias="Return")]
169 Return{
170 value: Box<AlephTree>
171 },
172 #[serde(alias="Comment")]
173 Comment{
174 value: String
175 },
176 #[serde(alias="CommentMulti")]
177 CommentMulti{
178 value: String
179 },
180 Assert {
181 condition: Box<AlephTree>,
182 message: Box<AlephTree>
183 },
184
185 CobolProgram {
186 #[serde(alias="programId")]
187 program_id: String,
188 #[serde(alias="environmentDiv")]
189 environment_div: Option<Box<AlephTree>>,
190 #[serde(alias="dataDiv")]
191 data_div: Option<Box<AlephTree>>,
192 #[serde(alias="procedureDiv")]
193 procedure_div: Box<AlephTree>
194 },
195
196 EnvironmentDivision {
197 #[serde(alias="configSection")]
198 config_section: Option<Box<AlephTree>>,
199 #[serde(alias="ioControlSection")]
200 io_control_section: Option<Box<AlephTree>>
201 },
202
203 DataDivision {
204 #[serde(alias="fileSection")]
205 file_section: Option<Box<AlephTree>>,
206 #[serde(alias="workingStorageSection")]
207 working_storage_section: Option<Box<AlephTree>>,
208 #[serde(alias="linkageSection")]
209 linkage_section: Option<Box<AlephTree>>
210 },
211
212 ProcedureDivision {
213 #[serde(alias="usingClause")]
214 using_clause: Option<Vec<String>>,
215 statements: Vec<Box<AlephTree>>
216 },
217
218 PicClause {
219 #[serde(alias="dataName")]
220 data_name: String,
221 #[serde(alias="levelNumber")]
222 level_number: String,
223 picture: String,
224 #[serde(alias="initialValue")]
225 initial_value: Option<Box<AlephTree>>,
226 #[serde(alias="occursClause")]
227 occurs_clause: Option<String>,
228 usage: Option<String>
229 },
230
231 GroupItem {
232 #[serde(alias="dataName")]
233 data_name: String,
234 #[serde(alias="levelNumber")]
235 level_number: String,
236 #[serde(alias="subItems")]
237 sub_items: Vec<Box<AlephTree>>
238 },
239
240 Redefines {
241 #[serde(alias="dataName")]
242 data_name: String,
243 #[serde(alias="levelNumber")]
244 level_number: String,
245 #[serde(alias="redefinedItem")]
246 redefined_item: String,
247 picture: Option<String>
248 },
249
250 FileDescription {
251 #[serde(alias="fileName")]
252 file_name: String,
253 #[serde(alias="recordDescription")]
254 record_description: Vec<Box<AlephTree>>,
255 #[serde(alias="blockContains")]
256 block_contains: Option<String>,
257 #[serde(alias="recordContains")]
258 record_contains: Option<String>
259 },
260
261 SelectStatement {
262 #[serde(alias="fileName")]
263 file_name: String,
264 #[serde(alias="assignTo")]
265 assign_to: String,
266 #[serde(alias="accessMode")]
267 access_mode: Option<String>,
268 #[serde(alias="organizationMode")]
269 organization_mode: Option<String>
270 },
271
272 Move {
273 source: Box<AlephTree>,
274 #[serde(alias="targetList")]
275 target_list: Vec<Box<AlephTree>>
276 },
277
278 Compute {
279 target: Box<AlephTree>,
280 expression: Box<AlephTree>,
281 #[serde(alias="onSizeError")]
282 on_size_error: Option<Box<AlephTree>>
283 },
284
285 Perform {
286 #[serde(alias="targetParagraph")]
287 target_paragraph: Option<String>,
288 #[serde(alias="fromParagraph")]
289 from_paragraph: Option<String>,
290 #[serde(alias="throughParagraph")]
291 through_paragraph: Option<String>,
292 #[serde(alias="timesClause")]
293 times_clause: Option<Box<AlephTree>>,
294 #[serde(alias="untilClause")]
295 until_clause: Option<Box<AlephTree>>,
296 #[serde(alias="varyingClause")]
297 varying_clause: Option<Box<AlephTree>>,
298 #[serde(alias="inlineStatements")]
299 inline_statements: Option<Vec<Box<AlephTree>>>
300 },
301
302 Accept {
303 target: Box<AlephTree>,
304 #[serde(alias="fromDevice")]
305 from_device: Option<String>
306 },
307
308 Display {
309 #[serde(alias="itemList")]
310 item_list: Vec<Box<AlephTree>>,
311 #[serde(alias="uponDevice")]
312 upon_device: Option<String>
313 },
314
315 Open {
316 mode: String,
317 #[serde(alias="fileList")]
318 file_list: Vec<String>
319 },
320
321 Close {
322 #[serde(alias="fileList")]
323 file_list: Vec<String>
324 },
325
326 Read {
327 #[serde(alias="fileName")]
328 file_name: String,
329 #[serde(alias="intoClause")]
330 into_clause: Option<Box<AlephTree>>,
331 #[serde(alias="keyClause")]
332 key_clause: Option<Box<AlephTree>>,
333 #[serde(alias="atEndClause")]
334 at_end_clause: Option<Box<AlephTree>>,
335 #[serde(alias="notAtEndClause")]
336 not_at_end_clause: Option<Box<AlephTree>>
337 },
338
339 Write {
340 #[serde(alias="recordName")]
341 record_name: String,
342 #[serde(alias="fromClause")]
343 from_clause: Option<Box<AlephTree>>,
344 #[serde(alias="advancingClause")]
345 advancing_clause: Option<String>
346 },
347
348 GoTo {
349 #[serde(alias="targetParagraph")]
350 target_paragraph: String,
351 #[serde(alias="dependingOn")]
352 depending_on: Option<Box<AlephTree>>
353 },
354
355 Stop {
356 #[serde(alias="stopType")]
357 stop_type: String
358 },
359
360 Exit,
361
362 Paragraph {
363 name: String,
364 statements: Vec<Box<AlephTree>>
365 },
366
367 Section {
368 name: String,
369 paragraphs: Vec<Box<AlephTree>>
370 },
371
372 Evaluate {
373 #[serde(alias="selectionSubject")]
374 selection_subject: Box<AlephTree>,
375 #[serde(alias="whenClauses")]
376 when_clauses: Vec<Box<AlephTree>>,
377 #[serde(alias="whenOther")]
378 when_other: Option<Box<AlephTree>>
379 },
380
381 WhenClause {
382 #[serde(alias="selectionObject")]
383 selection_object: Box<AlephTree>,
384 statements: Vec<Box<AlephTree>>
385 },
386
387 Inspect {
388 #[serde(alias="inspectingItem")]
389 inspecting_item: Box<AlephTree>,
390 #[serde(alias="tallyingClause")]
391 tallying_clause: Option<Box<AlephTree>>,
392 #[serde(alias="replacingClause")]
393 replacing_clause: Option<Box<AlephTree>>
394 },
395
396 StringStmt {
397 #[serde(alias="sourceItems")]
398 source_items: Vec<Box<AlephTree>>,
399 #[serde(alias="delimitedBy")]
400 delimited_by: Box<AlephTree>,
401 #[serde(alias="intoItem")]
402 into_item: Box<AlephTree>,
403 #[serde(alias="withPointer")]
404 with_pointer: Option<Box<AlephTree>>,
405 #[serde(alias="onOverflow")]
406 on_overflow: Option<Box<AlephTree>>
407 },
408
409 Unstring {
410 #[serde(alias="sourceItem")]
411 source_item: Box<AlephTree>,
412 #[serde(alias="delimitedBy")]
413 delimited_by: Box<AlephTree>,
414 #[serde(alias="intoItems")]
415 into_items: Vec<Box<AlephTree>>,
416 #[serde(alias="withPointer")]
417 with_pointer: Option<Box<AlephTree>>,
418 #[serde(alias="onOverflow")]
419 on_overflow: Option<Box<AlephTree>>
420 },
421
422 OnSizeError {
423 statements: Vec<Box<AlephTree>>
424 },
425
426 NotOnSizeError {
427 statements: Vec<Box<AlephTree>>
428 },
429
430 Call {
431 #[serde(alias="programName")]
432 program_name: Box<AlephTree>,
433 #[serde(alias="usingParameters")]
434 using_parameters: Option<Vec<Box<AlephTree>>>,
435 #[serde(alias="givingParameter")]
436 giving_parameter: Option<Box<AlephTree>>,
437 #[serde(alias="onException")]
438 on_exception: Option<Box<AlephTree>>
439 },
440
441 QualifiedName {
442 #[serde(alias="dataName")]
443 data_name: String,
444 #[serde(alias="qualifierList")]
445 qualifier_list: Vec<String>
446 },
447
448 Subscript {
449 #[serde(alias="dataName")]
450 data_name: String,
451 #[serde(alias="subscriptList")]
452 subscript_list: Vec<Box<AlephTree>>
453 },
454
455 Figurative {
456 #[serde(alias="figurativeType")]
457 figurative_type: String
458 },
459
460 ClassCondition {
461 #[serde(alias="dataItem")]
462 data_item: Box<AlephTree>,
463 #[serde(alias="className")]
464 class_name: String
465 },
466
467 SignCondition {
468 #[serde(alias="dataItem")]
469 data_item: Box<AlephTree>,
470 sign: String
471 },
472
473 OccursClause {
474 #[serde(alias="minOccurs")]
475 min_occurs: Option<String>,
476 #[serde(alias="maxOccurs")]
477 max_occurs: String,
478 #[serde(alias="dependingOn")]
479 depending_on: Option<String>,
480 #[serde(alias="indexedBy")]
481 indexed_by: Option<Vec<String>>
482 },
483
484 HexLiteral {
485 value: String
486 },
487
488 UsageClause {
489 #[serde(alias="usageType")]
490 usage_type: String
491 },
492
493 ForthDef {
497 name: String,
498 body: Vec<Box<AlephTree>>,
499 #[serde(alias="isImmediate")]
500 is_immediate: bool,
501 },
502
503 ForthConst {
505 name: String,
506 value: Box<AlephTree>,
507 },
508
509 ForthVar {
511 name: String,
512 },
513
514 ForthCreate {
516 name: String,
517 allot_size: Option<Box<AlephTree>>,
518 does_body: Option<Vec<Box<AlephTree>>>,
519 },
520
521 ForthDup, ForthDrop, ForthSwap, ForthOver, ForthRot, ForthMinusRot, ForthNip, ForthTuck, ForthPick { depth: Box<AlephTree>,
532 },
533 ForthRoll { depth: Box<AlephTree>,
535 },
536
537 ForthTwoDup, ForthTwoDrop, ForthTwoSwap, ForthTwoOver, ForthToR, ForthFromR, ForthRFetch, ForthMod, ForthDivMod, ForthMulDiv, ForthMulDivMod,ForthOnePlus, ForthOneMinus, ForthTwoMul, ForthTwoDiv, ForthAbs, ForthNegate, ForthMin, ForthMax, ForthXor, ForthInvert, ForthLShift, ForthRShift, ForthNotEq, ForthLessThan, ForthGreater, ForthGreaterEq,ForthZeroEq, ForthZeroNotEq,ForthZeroLess, ForthZeroGreater, ForthFetch, ForthStore, ForthPlusStore,ForthCFetch, ForthCStore, ForthCells, ForthAllot, ForthComma, ForthCComma, ForthHere, ForthDot, ForthEmit, ForthCR, ForthSpace, ForthSpaces { count: Box<AlephTree>,
597 },
598 ForthType { addr: Box<AlephTree>,
600 count: Box<AlephTree>,
601 },
602 ForthKey, ForthAccept { addr: Box<AlephTree>,
605 max_len: Box<AlephTree>,
606 },
607 ForthDotQuote {text: String
609 },
610 ForthSQuote { text: String
612 },
613
614 ForthBeginUntil { body: Vec<Box<AlephTree>>,
617 condition: Box<AlephTree>,
618 },
619
620 ForthBeginWhileRepeat { condition: Box<AlephTree>,
622 while_body: Vec<Box<AlephTree>>,
623 repeat_body: Vec<Box<AlephTree>>,
624 },
625
626 ForthBeginAgain { body: Vec<Box<AlephTree>>,
628 },
629
630 ForthDoLoop { body: Vec<Box<AlephTree>>,
632 },
633
634 ForthDoPlusLoop { body: Vec<Box<AlephTree>>,
636 increment: Box<AlephTree>,
637 },
638
639 ForthLeave, ForthCase { #[serde(alias="whenClauses")]
643 when_clauses: Vec<Box<AlephTree>>,
644 default: Option<Vec<Box<AlephTree>>>,
645 },
646
647 ForthOf { value: Box<AlephTree>,
649 body: Vec<Box<AlephTree>>,
650 },
651
652 ForthI, ForthJ, ForthTick { word: String,
659 },
660
661 ForthBracketTick { word: String,
663 },
664
665 ForthExecute { xt: Box<AlephTree>,
667 },
668
669 ForthLiteral { value: Box<AlephTree>,
672 },
673
674 ForthPostpone { word: String,
676 },
677
678 ForthBracket, ForthBracketClose, ForthImmediate, ForthRecursive, ForthForget { word: String,
688 },
689
690 ForthWords, ForthSee { word: String,
694 },
695
696 ForthEvaluate { addr: Box<AlephTree>,
699 count: Box<AlephTree>,
700 },
701
702 ForthSToD, ForthDToS, ForthQuit, ForthAbort, ForthAbortQuote { message: String,
711 },
712
713 ForthComment { text: String,
716 },
717
718 ForthLineComment { text: String,
720 },
721
722 ForthHex { value: String,
725 },
726
727 ForthProgram {
729 definitions: Vec<Box<AlephTree>>,
730 },
731
732 ForthSequence { words: Vec<Box<AlephTree>>,
734 }
735}
736
737pub fn json_parse(source: String) -> AlephTree {
738 serde_json::from_str(&source).unwrap()
739}
740
741pub fn to_json(ast: AlephTree) -> String {
742 serde_json::to_string_pretty(&ast).unwrap()
743}
744
745impl FromIterator<AlephTree> for Vec<Box<AlephTree>> {
746 fn from_iter<I: IntoIterator<Item=AlephTree>>(iter : I) -> Self {
747 let mut result: Vec<Box<AlephTree>> = Vec::new();
748 for node in iter {
749 result.push(Box::new(node));
750 }
751 result
752 }
753}
754
755impl fmt::Display for AlephTree {
756 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
757 match self {
758 e => write!(f, "{:?}", e),
759 }
760 }
761}
762
763impl AlephTree {
764 pub fn to_string_value(&self) -> String {
765 match self {
766 AlephTree::Bool { value } => value.to_string(),
767 AlephTree::Int { value } => value.to_string(),
768 AlephTree::Float { value } => value.to_string(),
769 AlephTree::String { value } => value.to_string(),
770 AlephTree::Ident { value } => value.to_string(),
771 AlephTree::Bytes { elems } => match std::str::from_utf8(elems) {
772 Ok(s) => s.to_string(),
773 Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
774 },
775 AlephTree::Figurative { figurative_type } => figurative_type.to_string(),
776 AlephTree::HexLiteral { value } => value.to_string(),
777 _ => {
778 println!("Can't evaluate to_string_value : {}", self);
779 panic!()
780 }
781 }
782 }
783}