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
494pub fn json_parse(source: String) -> AlephTree {
495 serde_json::from_str(&source).unwrap()
496}
497
498pub fn to_json(ast: AlephTree) -> String {
499 serde_json::to_string_pretty(&ast).unwrap()
500}
501
502impl FromIterator<AlephTree> for Vec<Box<AlephTree>> {
503 fn from_iter<I: IntoIterator<Item=AlephTree>>(iter : I) -> Self {
504 let mut result: Vec<Box<AlephTree>> = Vec::new();
505 for node in iter {
506 result.push(Box::new(node));
507 }
508 result
509 }
510}
511
512impl fmt::Display for AlephTree {
513 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
514 match self {
515 e => write!(f, "{:?}", e),
516 }
517 }
518}
519
520impl AlephTree {
521 pub fn to_string_value(&self) -> String {
522 match self {
523 AlephTree::Bool { value } => value.to_string(),
524 AlephTree::Int { value } => value.to_string(),
525 AlephTree::Float { value } => value.to_string(),
526 AlephTree::String { value } => value.to_string(),
527 AlephTree::Ident { value } => value.to_string(),
528 AlephTree::Bytes { elems } => match std::str::from_utf8(elems) {
529 Ok(s) => s.to_string(),
530 Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
531 },
532 AlephTree::Figurative { figurative_type } => figurative_type.to_string(),
533 AlephTree::HexLiteral { value } => value.to_string(),
534 _ => {
535 println!("Can't evaluate to_string_value : {}", self);
536 panic!()
537 }
538 }
539 }
540}