aleph_syntax_tree/
syntax.rs

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    HexLiteral{value: String},
22    Figurative{
23        #[serde(alias="figurativeType")]
24        figurative_type: String
25    },
26    Tuple{elems: Vec<Box<AlephTree>>},
27    Array{elems: Vec<Box<AlephTree>>},
28    Record{fields: Vec<Box<AlephTree>>},
29    Field{name: String, value: Box<AlephTree>},
30    Neg{expr: Box<AlephTree>},
31    Not{
32        #[serde(alias="boolExpr")]
33        bool_expr: Box<AlephTree>
34    },
35    BitNot{expr: Box<AlephTree>},
36    Abs{expr: Box<AlephTree>},
37    Add{
38        #[serde(alias="numberExpr1")]
39        number_expr1: Box<AlephTree>,
40        #[serde(alias="numberExpr2")]
41        number_expr2: Box<AlephTree>
42    },
43    Sub{
44        #[serde(alias="numberExpr1")]
45        number_expr1: Box<AlephTree>,
46        #[serde(alias="numberExpr2")]
47        number_expr2: Box<AlephTree>
48    },
49    Mul{
50        #[serde(alias="numberExpr1")]
51        number_expr1: Box<AlephTree>,
52        #[serde(alias="numberExpr2")]
53        number_expr2: Box<AlephTree>
54    },
55    Div{
56        #[serde(alias="numberExpr1")]
57        number_expr1: Box<AlephTree>,
58        #[serde(alias="numberExpr2")]
59        number_expr2: Box<AlephTree>
60    },
61    Mod{
62        #[serde(alias="numberExpr1")]
63        number_expr1: Box<AlephTree>,
64        #[serde(alias="numberExpr2")]
65        number_expr2: Box<AlephTree>
66    },
67    DivMod{
68        #[serde(alias="numberExpr1", alias="dividend")]
69        dividend: Box<AlephTree>,
70        #[serde(alias="numberExpr2", alias="divisor")]
71        divisor: Box<AlephTree>
72    },
73    MulDiv{
74        n1: Box<AlephTree>,
75        n2: Box<AlephTree>,
76        n3: Box<AlephTree>
77    },
78    MulDivMod{
79        n1: Box<AlephTree>,
80        n2: Box<AlephTree>,
81        n3: Box<AlephTree>
82    },
83    Pow{base: Box<AlephTree>, exponent: Box<AlephTree>},
84    Min{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
85    Max{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
86    And{
87        #[serde(alias="boolExpr1")]
88        bool_expr1: Box<AlephTree>,
89        #[serde(alias="boolExpr2")]
90        bool_expr2: Box<AlephTree>
91    },
92    Or{
93        #[serde(alias="boolExpr1")]
94        bool_expr1: Box<AlephTree>,
95        #[serde(alias="boolExpr2")]
96        bool_expr2: Box<AlephTree>
97    },
98    Xor{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
99    BitAnd{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
100    BitOr{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
101    BitXor{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
102    LShift{expr: Box<AlephTree>, amount: Box<AlephTree>},
103    RShift{expr: Box<AlephTree>, amount: Box<AlephTree>},
104    Eq{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
105    NotEq{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
106    LT{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
107    LE{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
108    GT{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
109    GE{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
110    In{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
111    If{
112        condition: Box<AlephTree>,
113        then: Box<AlephTree>,
114        #[serde(alias="else")]
115        els: Box<AlephTree>
116    },
117    While{
118        #[serde(alias="initExpr")]
119        init_expr: Box<AlephTree>,
120        condition: Box<AlephTree>,
121        #[serde(alias="loopExpr")]
122        loop_expr: Box<AlephTree>,
123        #[serde(alias="postExpr")]
124        post_expr: Box<AlephTree>
125    },
126    For{
127        var: String,
128        start: Box<AlephTree>,
129        end: Box<AlephTree>,
130        step: Option<Box<AlephTree>>,
131        body: Box<AlephTree>,
132        reverse: bool
133    },
134    Loop{
135        name: Option<String>,
136        body: Vec<Box<AlephTree>>
137    },
138    DoLoop{
139        #[serde(alias="loopVar")]
140        loop_var: Option<String>,
141        #[serde(alias="startIndex")]
142        start: Option<Box<AlephTree>>,
143        #[serde(alias="endIndex")]
144        end: Option<Box<AlephTree>>,
145        by: Option<Box<AlephTree>>,
146        #[serde(alias="whileCond")]
147        while_cond: Option<Box<AlephTree>>,
148        #[serde(alias="untilCond")]
149        until_cond: Option<Box<AlephTree>>,
150        body: Vec<Box<AlephTree>>
151    },
152    Case{
153        expr: Box<AlephTree>,
154        #[serde(alias="caseList", alias="whenClauses", alias="alternatives", alias="ofClauses")]
155        cases: Vec<Box<AlephTree>>,
156        #[serde(alias="whenOther", alias="otherwise", alias="default")]
157        default_case: Option<Box<AlephTree>>
158    },
159    CaseBranch{
160        #[serde(alias="condition", alias="selectionObject", alias="choices", alias="value")]
161        pattern: Box<AlephTree>,
162        #[serde(alias="caseExpr", alias="body", alias="statements")]
163        body: Vec<Box<AlephTree>>
164    },
165    Match{
166        expr: Box<AlephTree>,
167        #[serde(alias="caseList")]
168        case_list: Vec<Box<AlephTree>>
169    },
170    MatchLine{
171        condition: Box<AlephTree>,
172        #[serde(alias="caseExpr")]
173        case_expr: Box<AlephTree>
174    },
175    ProcedureDef{
176        name: String,
177        #[serde(alias="procedureType")]
178        proc_type: Option<String>, // "procedure", "function", "word", "entry", "main"
179        parameters: Vec<Box<AlephTree>>,
180        #[serde(alias="returnType")]
181        return_type: Option<Box<AlephTree>>,
182        attributes: Vec<String>,
183        declarations: Vec<Box<AlephTree>>,
184        body: Vec<Box<AlephTree>>
185    },
186    Parameter{
187        name: String,
188        #[serde(alias="paramType", alias="param_type")]
189        param_type: Option<Box<AlephTree>>,
190        mode: Option<String>, // "in", "out", "in out", "ref", "value", "by reference"
191        default: Option<Box<AlephTree>>
192    },
193    VarDecl{
194        name: String,
195        #[serde(alias="levelNumber")]
196        level: Option<String>, // For COBOL level numbers
197        #[serde(alias="varType", alias="var_type", alias="objectType", alias="picture")]
198        var_type: Option<Box<AlephTree>>,
199        #[serde(alias="initialValue", alias="initial_value")]
200        initial_value: Option<Box<AlephTree>>,
201        #[serde(alias="isConstant", alias="is_constant")]
202        is_constant: bool,
203        #[serde(alias="isAliased", alias="is_aliased")]
204        is_aliased: bool,
205        storage: Option<String>,
206        #[serde(alias="occursClause")]
207        occurs: Option<String>,
208        usage: Option<String>,
209        attributes: Vec<String>
210    },
211    StructDecl{
212        name: String,
213        #[serde(alias="levelNumber")]
214        level: Option<String>,
215        members: Vec<Box<AlephTree>>,
216        attributes: Vec<String>
217    },
218    TypeDecl{
219        name: String,
220        definition: Box<AlephTree>,
221        attributes: Vec<String>
222    },
223    Let{
224        var: String,
225        #[serde(alias="isPointer")]
226        is_pointer: String,
227        value: Box<AlephTree>,
228        expr: Box<AlephTree>
229    },
230    LetRec{
231        name: String,
232        args: Vec<Box<AlephTree>>,
233        body: Box<AlephTree>
234    },
235    Var{
236        var: String,
237        #[serde(alias="isPointer")]
238        is_pointer: String
239    },
240    TypeRef{
241        name: String,
242        #[serde(alias="qualifierList")]
243        qualifiers: Vec<String>
244    },
245    ArrayType{
246        #[serde(alias="elementType")]
247        element_type: Box<AlephTree>,
248        dimensions: Vec<Box<AlephTree>>
249    },
250    PointerType{
251        #[serde(alias="targetType")]
252        target_type: Box<AlephTree>,
253        #[serde(alias="isAllAccess")]
254        is_all: bool
255    },
256    RangeType{
257        start: Box<AlephTree>,
258        end: Box<AlephTree>
259    },
260    EnumType{
261        values: Vec<String>
262    },
263    RecordType{
264        fields: Vec<Box<AlephTree>>
265    },
266    FieldDecl{
267        name: String,
268        #[serde(alias="fieldType")]
269        field_type: Box<AlephTree>,
270        attributes: Vec<String>
271    },
272    SubtypeDecl{
273        name: String,
274        #[serde(alias="baseType")]
275        base_type: Box<AlephTree>,
276        constraint: Option<Box<AlephTree>>
277    },
278    Get{
279        #[serde(alias="arrayName")]
280        array_name: String,
281        elem: Box<AlephTree>
282    },
283    Put{
284        #[serde(alias="arrayName")]
285        array_name: String,
286        elem: Box<AlephTree>,
287        value: Box<AlephTree>,
288        insert: String
289    },
290    Remove{
291        #[serde(alias="arrayName")]
292        array_name: String,
293        elem: Box<AlephTree>,
294        #[serde(alias="isValue")]
295        is_value: String
296    },
297    Length{var: String},
298    Slice{
299        array: Box<AlephTree>,
300        start: Option<Box<AlephTree>>,
301        end: Option<Box<AlephTree>>
302    },
303    Alloc{
304        var: Box<AlephTree>,
305        #[serde(alias="setPointer", alias="typeOrExpr")]
306        target: Option<Box<AlephTree>>
307    },
308    Free{
309        var: Box<AlephTree>
310    },
311    Fetch{
312        addr: Box<AlephTree>,
313        #[serde(alias="fetchType")]
314        fetch_type: Option<String> // "byte", "word", "cell"
315    },
316    Store{
317        value: Box<AlephTree>,
318        addr: Box<AlephTree>,
319        #[serde(alias="storeType")]
320        store_type: Option<String> // "byte", "word", "cell"
321    },
322    StoreOp{
323        value: Box<AlephTree>,
324        addr: Box<AlephTree>,
325        op: String // "+", "-", etc. for +=, -=
326    },
327    App{
328        #[serde(alias="objectName")]
329        object_name: String,
330        fun: Box<AlephTree>,
331        #[serde(alias="paramList")]
332        param_list: Vec<Box<AlephTree>>
333    },
334    Call{
335        #[serde(alias="programName", alias="entryName")]
336        target: Box<AlephTree>,
337        #[serde(alias="usingParameters")]
338        parameters: Option<Vec<Box<AlephTree>>>,
339        #[serde(alias="givingParameter")]
340        returning: Option<Box<AlephTree>>,
341        #[serde(alias="onException")]
342        on_error: Option<Box<AlephTree>>
343    },
344    Stmts{expr1: Box<AlephTree>, expr2: Box<AlephTree>},
345    Block{statements: Vec<Box<AlephTree>>},
346    Assignment{target: Box<AlephTree>, value: Box<AlephTree>},
347    #[serde(alias="Return")]
348    Return{value: Box<AlephTree>},
349    GoTo{
350        #[serde(alias="targetParagraph", alias="target")]
351        target: String,
352        #[serde(alias="dependingOn")]
353        depending_on: Option<Box<AlephTree>>
354    },
355    Label{
356        name: String,
357        #[serde(alias="labelType")]
358        label_type: Option<String> // "paragraph", "section", "entry"
359    },
360    Exit,
361    Move{
362        source: Box<AlephTree>,
363        #[serde(alias="targetList")]
364        targets: Vec<Box<AlephTree>>
365    },
366    Compute{
367        target: Box<AlephTree>,
368        expression: Box<AlephTree>,
369        #[serde(alias="onSizeError")]
370        on_error: Option<Box<AlephTree>>
371    },
372    Print{
373        #[serde(alias="itemList", alias="items")]
374        items: Vec<Box<AlephTree>>,
375        #[serde(alias="uponDevice", alias="toFile")]
376        destination: Option<String>,
377        #[serde(alias="formatItems")]
378        format: Option<Vec<Box<AlephTree>>>,
379        options: Vec<String>
380    },
381    Input{
382        #[serde(alias="target", alias="variables")]
383        targets: Vec<Box<AlephTree>>,
384        #[serde(alias="fromDevice", alias="fromFile")]
385        source: Option<String>,
386        options: Vec<String>
387    },
388    FileOpen{
389        #[serde(alias="fileName", alias="file")]
390        file: String,
391        mode: String,
392        attributes: Vec<String>
393    },
394    FileClose{
395        #[serde(alias="fileList", alias="files")]
396        files: Vec<String>
397    },
398    FileRead{
399        #[serde(alias="fileName")]
400        file_name: String,
401        #[serde(alias="intoClause")]
402        into: Option<Box<AlephTree>>,
403        #[serde(alias="keyClause")]
404        key: Option<Box<AlephTree>>,
405        #[serde(alias="atEndClause", alias="onEnd")]
406        on_end: Option<Box<AlephTree>>,
407        #[serde(alias="notAtEndClause")]
408        not_on_end: Option<Box<AlephTree>>
409    },
410    FileWrite{
411        #[serde(alias="recordName")]
412        record_name: String,
413        #[serde(alias="fromClause")]
414        from: Option<Box<AlephTree>>,
415        #[serde(alias="advancingClause")]
416        options: Vec<String>
417    },
418    StringOp{
419        operation: String, // "concat", "inspect", "unstring", "replace"
420        #[serde(alias="sourceItems", alias="sourceItem")]
421        sources: Vec<Box<AlephTree>>,
422        #[serde(alias="delimitedBy")]
423        delimiter: Option<Box<AlephTree>>,
424        #[serde(alias="intoItem", alias="intoItems")]
425        targets: Vec<Box<AlephTree>>,
426        #[serde(alias="withPointer")]
427        pointer: Option<Box<AlephTree>>,
428        #[serde(alias="onOverflow", alias="tallyingClause", alias="replacingClause")]
429        clauses: Vec<Box<AlephTree>>
430    },
431    #[serde(alias="Import")]
432    Iprt{
433        name: String,
434        items: Vec<String>
435    },
436    Module{
437        name: String,
438        #[serde(alias="moduleType")]
439        module_type: String, // "package", "program", "unit", "interface", "spec", "body"
440        #[serde(alias="programId")]
441        id: Option<String>,
442        declarations: Vec<Box<AlephTree>>,
443        body: Option<Vec<Box<AlephTree>>>,
444        initialization: Option<Vec<Box<AlephTree>>>
445    },
446    Division{
447        #[serde(alias="divisionType")]
448        division_type: String, // "environment", "data", "procedure"
449        sections: Vec<Box<AlephTree>>
450    },
451    Section{
452        name: String,
453        #[serde(alias="sectionType")]
454        section_type: Option<String>,
455        content: Vec<Box<AlephTree>>
456    },
457    #[serde(alias="Class")]
458    Clss{
459        name: String,
460        #[serde(alias="attributList")]
461        attribute_list: Vec<String>,
462        body: Box<AlephTree>
463    },
464    TryCatch{
465        #[serde(alias="tryBlock")]
466        try_block: Box<AlephTree>,
467        #[serde(alias="catchClauses", alias="handlers")]
468        catch_clauses: Vec<Box<AlephTree>>,
469        #[serde(alias="finallyBlock")]
470        finally_block: Option<Box<AlephTree>>
471    },
472    CatchClause{
473        #[serde(alias="exceptionType", alias="exceptionChoices")]
474        exception_types: Vec<String>,
475        var: Option<String>,
476        body: Box<AlephTree>
477    },
478    OnCondition{
479        condition: String, // "SIZE", "OVERFLOW", "ENDFILE", etc.
480        #[serde(alias="snapOption")]
481        options: Vec<String>,
482        handler: Box<AlephTree>
483    },
484    Raise{
485        #[serde(alias="exception")]
486        condition: Box<AlephTree>
487    },
488    Signal{
489        condition: String
490    },
491    Revert{
492        condition: String
493    },
494    ExceptionDecl{
495        name: String
496    },
497    #[serde(alias="Comment")]
498    Comment{value: String},
499    #[serde(alias="CommentMulti")]
500    CommentMulti{value: String},
501    Assert{
502        condition: Box<AlephTree>,
503        message: Box<AlephTree>
504    },
505    Generic{
506        name: String,
507        #[serde(alias="genericType")]
508        generic_type: String,
509        #[serde(alias="genericParams")]
510        generic_params: Vec<Box<AlephTree>>,
511        body: Box<AlephTree>
512    },
513    GenericParam{
514        name: String,
515        #[serde(alias="paramKind")]
516        param_kind: String,
517        constraint: Option<Box<AlephTree>>,
518        default: Option<Box<AlephTree>>
519    },
520    Instantiation{
521        name: String,
522        #[serde(alias="genericName")]
523        generic_name: String,
524        #[serde(alias="actualParams")]
525        actual_params: Vec<Box<AlephTree>>
526    },
527    Attribute{
528        prefix: Box<AlephTree>,
529        attribute: String,
530        args: Option<Vec<Box<AlephTree>>>
531    },
532    Pragma{
533        name: String,
534        args: Vec<Box<AlephTree>>
535    },
536    RepresentationClause{
537        name: String,
538        #[serde(alias="clauseType")]
539        clause_type: String,
540        specification: Box<AlephTree>
541    },
542    Renaming{
543        #[serde(alias="newName")]
544        new_name: String,
545        #[serde(alias="renamedEntity", alias="redefinedItem")]
546        old_name: Box<AlephTree>,
547        #[serde(alias="entityType")]
548        rename_type: Option<Box<AlephTree>>
549    },
550    Execute{
551        target: Box<AlephTree>,
552        #[serde(alias="executionType")]
553        exec_type: Option<String> // "word", "token", "xt"
554    },
555    Perform{
556        #[serde(alias="targetParagraph")]
557        target: Option<String>,
558        #[serde(alias="fromParagraph")]
559        from: Option<String>,
560        #[serde(alias="throughParagraph")]
561        through: Option<String>,
562        #[serde(alias="timesClause")]
563        times: Option<Box<AlephTree>>,
564        #[serde(alias="untilClause")]
565        until: Option<Box<AlephTree>>,
566        #[serde(alias="varyingClause")]
567        varying: Option<Box<AlephTree>>,
568        #[serde(alias="inlineStatements")]
569        inline: Option<Vec<Box<AlephTree>>>
570    },
571    // ===== COBOL-specific (irreducible) =====
572    PicClause{
573        #[serde(alias="dataName")]
574        data_name: String,
575        #[serde(alias="levelNumber")]
576        level_number: String,
577        picture: String,
578        #[serde(alias="initialValue")]
579        initial_value: Option<Box<AlephTree>>,
580        #[serde(alias="occursClause")]
581        occurs_clause: Option<String>,
582        usage: Option<String>
583    },
584    FileDescription{
585        #[serde(alias="fileName")]
586        file_name: String,
587        #[serde(alias="recordDescription")]
588        record_description: Vec<Box<AlephTree>>,
589        #[serde(alias="blockContains")]
590        block_contains: Option<String>,
591        #[serde(alias="recordContains")]
592        record_contains: Option<String>
593    },
594    SelectStatement{
595        #[serde(alias="fileName")]
596        file_name: String,
597        #[serde(alias="assignTo")]
598        assign_to: String,
599        #[serde(alias="accessMode")]
600        access_mode: Option<String>,
601        #[serde(alias="organizationMode")]
602        organization_mode: Option<String>
603    },
604    Inspect{
605        #[serde(alias="inspectingItem")]
606        inspecting_item: Box<AlephTree>,
607        #[serde(alias="tallyingClause")]
608        tallying_clause: Option<Box<AlephTree>>,
609        #[serde(alias="replacingClause")]
610        replacing_clause: Option<Box<AlephTree>>
611    },
612    Accept{target: Box<AlephTree>, #[serde(alias="fromDevice")] from_device: Option<String>},
613    Display{#[serde(alias="itemList")] item_list: Vec<Box<AlephTree>>, #[serde(alias="uponDevice")] upon_device: Option<String>},
614    Open{mode: String, #[serde(alias="fileList")] file_list: Vec<String>},
615    Close{#[serde(alias="fileList")] file_list: Vec<String>},
616    Read{
617        #[serde(alias="fileName")] file_name: String,
618        #[serde(alias="intoClause")] into_clause: Option<Box<AlephTree>>,
619        #[serde(alias="keyClause")] key_clause: Option<Box<AlephTree>>,
620        #[serde(alias="atEndClause")] at_end_clause: Option<Box<AlephTree>>,
621        #[serde(alias="notAtEndClause")] not_at_end_clause: Option<Box<AlephTree>>
622    },
623    Write{
624        #[serde(alias="recordName")] record_name: String,
625        #[serde(alias="fromClause")] from_clause: Option<Box<AlephTree>>,
626        #[serde(alias="advancingClause")] advancing_clause: Option<String>
627    },
628    Stop{#[serde(alias="stopType")] stop_type: String},
629    Paragraph{name: String, statements: Vec<Box<AlephTree>>},
630    Evaluate{
631        #[serde(alias="selectionSubject")] selection_subject: Box<AlephTree>,
632        #[serde(alias="whenClauses")] when_clauses: Vec<Box<AlephTree>>,
633        #[serde(alias="whenOther")] when_other: Option<Box<AlephTree>>
634    },
635    WhenClause{
636        #[serde(alias="selectionObject")] selection_object: Box<AlephTree>,
637        statements: Vec<Box<AlephTree>>
638    },
639    StringStmt{
640        #[serde(alias="sourceItems")] source_items: Vec<Box<AlephTree>>,
641        #[serde(alias="delimitedBy")] delimited_by: Box<AlephTree>,
642        #[serde(alias="intoItem")] into_item: Box<AlephTree>,
643        #[serde(alias="withPointer")] with_pointer: Option<Box<AlephTree>>,
644        #[serde(alias="onOverflow")] on_overflow: Option<Box<AlephTree>>
645    },
646    Unstring{
647        #[serde(alias="sourceItem")] source_item: Box<AlephTree>,
648        #[serde(alias="delimitedBy")] delimited_by: Box<AlephTree>,
649        #[serde(alias="intoItems")] into_items: Vec<Box<AlephTree>>,
650        #[serde(alias="withPointer")] with_pointer: Option<Box<AlephTree>>,
651        #[serde(alias="onOverflow")] on_overflow: Option<Box<AlephTree>>
652    },
653    OnSizeError{statements: Vec<Box<AlephTree>>},
654    NotOnSizeError{statements: Vec<Box<AlephTree>>},
655    QualifiedName{
656        #[serde(alias="dataName")] data_name: String,
657        #[serde(alias="qualifierList")] qualifier_list: Vec<String>
658    },
659    Subscript{
660        #[serde(alias="dataName")] data_name: String,
661        #[serde(alias="subscriptList")] subscript_list: Vec<Box<AlephTree>>
662    },
663    ClassCondition{
664        #[serde(alias="dataItem")] data_item: Box<AlephTree>,
665        #[serde(alias="className")] class_name: String
666    },
667    SignCondition{
668        #[serde(alias="dataItem")] data_item: Box<AlephTree>,
669        sign: String
670    },
671    OccursClause{
672        #[serde(alias="minOccurs")] min_occurs: Option<String>,
673
674        #[serde(alias="maxOccurs")] max_occurs: String,
675        #[serde(alias="dependingOn")] depending_on: Option<String>,
676        #[serde(alias="indexedBy")] indexed_by: Option<Vec<String>>
677    },
678    UsageClause{
679        #[serde(alias="usageType")] usage_type: String
680    },
681    ForthProgram{definitions: Vec<Box<AlephTree>>},
682    ForthSequence{words: Vec<Box<AlephTree>>},
683    ForthDup, ForthDrop, ForthSwap, ForthOver, ForthRot,
684    ForthMinusRot, ForthNip, ForthTuck,
685    ForthPick{depth: Box<AlephTree>},
686    ForthRoll{depth: Box<AlephTree>},
687    ForthTwoDup, ForthTwoDrop, ForthTwoSwap, ForthTwoOver,
688    ForthToR, ForthFromR, ForthRFetch,
689    ForthCells{n: Box<AlephTree>},
690    ForthAllot{n: Box<AlephTree>},
691    ForthComma{value: Box<AlephTree>},
692    ForthCComma{value: Box<AlephTree>},
693    ForthHere,
694    ForthDot{value: Box<AlephTree>},
695    ForthEmit{char: Box<AlephTree>},
696    ForthCR, ForthSpace,
697    ForthSpaces{count: Box<AlephTree>},
698    ForthType{addr: Box<AlephTree>, count: Box<AlephTree>},
699    ForthKey,
700    ForthAccept{addr: Box<AlephTree>, #[serde(alias="maxLen")] max_len: Box<AlephTree>},
701    ForthDotQuote{text: String},
702    ForthSQuote{text: String},
703    ForthBeginUntil{body: Vec<Box<AlephTree>>, condition: Box<AlephTree>},
704    ForthBeginWhileRepeat{
705        condition: Box<AlephTree>,
706        #[serde(alias="whileBody")] while_body: Vec<Box<AlephTree>>,
707        #[serde(alias="repeatBody")] repeat_body: Vec<Box<AlephTree>>
708    },
709    ForthBeginAgain{body: Vec<Box<AlephTree>>},
710    ForthLeave,
711    ForthI, ForthJ,
712    ForthTick{word: String},
713    ForthBracketTick{word: String},
714    ForthLiteral{value: Box<AlephTree>},
715    ForthPostpone{word: String},
716    ForthBracket, ForthBracketClose,
717    ForthImmediate, ForthRecursive,
718    ForthForget{word: String},
719    ForthWords,
720    ForthSee{word: String},
721    ForthEvaluate{addr: Box<AlephTree>, count: Box<AlephTree>},
722    ForthSToD{value: Box<AlephTree>},
723    ForthDToS{value: Box<AlephTree>},
724    ForthQuit, ForthAbort,
725    ForthAbortQuote{message: String},
726    ForthCreate{
727        name: String,
728        #[serde(alias="allotSize")] allot_size: Option<Box<AlephTree>>,
729        #[serde(alias="doesBody")] does_body: Option<Vec<Box<AlephTree>>>
730    },
731    AdaTaskType{
732        name: String,
733        discriminants: Option<Vec<Box<AlephTree>>>,
734        entries: Vec<Box<AlephTree>>,
735        body: Vec<Box<AlephTree>>
736    },
737    AdaProtectedType{
738        name: String,
739        discriminants: Option<Vec<Box<AlephTree>>>,
740        declarations: Vec<Box<AlephTree>>
741    },
742    AdaProtectedBody{
743        name: String,
744        bodies: Vec<Box<AlephTree>>
745    },
746    AdaAccept{
747        #[serde(alias="entryName")] entry_name: String,
748        parameters: Option<Vec<Box<AlephTree>>>,
749        body: Option<Vec<Box<AlephTree>>>
750    },
751    AdaSelect{
752        alternatives: Vec<Box<AlephTree>>,
753        #[serde(alias="elseClause")] else_clause: Option<Vec<Box<AlephTree>>>
754    },
755    AdaSelectiveAccept{
756        #[serde(alias="guardCondition")] guard_condition: Option<Box<AlephTree>>,
757        #[serde(alias="acceptStmt")] accept_stmt: Box<AlephTree>,
758        statements: Vec<Box<AlephTree>>
759    },
760    AdaDelay{
761        #[serde(alias="delayType")] delay_type: String,
762        expression: Box<AlephTree>
763    },
764    AdaAbort{tasks: Vec<String>},
765    AdaAggregate{
766        components: Vec<Box<AlephTree>>
767    },
768    AdaComponentAssoc{
769        choices: Option<Vec<Box<AlephTree>>>,
770        expression: Box<AlephTree>
771    },
772    AdaQualified{
773        #[serde(alias="typeName")] type_name: Box<AlephTree>,
774        expression: Box<AlephTree>
775    },
776    AdaWith{packages: Vec<String>},
777}
778
779pub fn json_parse(source: String) -> AlephTree {
780    serde_json::from_str(&source).unwrap()
781}
782
783pub fn to_json(ast: AlephTree) -> String {
784    serde_json::to_string_pretty(&ast).unwrap()
785}
786
787impl FromIterator<AlephTree> for Vec<Box<AlephTree>> {
788    fn from_iter<I: IntoIterator<Item=AlephTree>>(iter : I) -> Self {
789        let mut result: Vec<Box<AlephTree>> = Vec::new();
790        for node in iter {
791            result.push(Box::new(node));
792        }
793        result
794    }
795}
796
797impl fmt::Display for AlephTree {
798    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
799        match self {
800            e => write!(f, "{:?}", e),
801        }
802    }
803}
804
805impl AlephTree {
806    pub fn to_string_value(&self) -> String {
807        match self {
808            AlephTree::Bool { value } => value.to_string(),
809            AlephTree::Int { value } => value.to_string(),
810            AlephTree::Float { value } => value.to_string(),
811            AlephTree::String { value } => value.to_string(),
812            AlephTree::Ident { value } => value.to_string(),
813            AlephTree::Bytes { elems } => match std::str::from_utf8(elems) {
814                Ok(s) => s.to_string(),
815                Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
816            },
817            AlephTree::Figurative { figurative_type } => figurative_type.to_string(),
818            AlephTree::HexLiteral { value } => value.to_string(),
819            _ => {
820                println!("Can't evaluate to_string_value : {}", self);
821                panic!()
822            }
823        }
824    }
825}