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    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}