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    // === Forth-specific nodes ===
494
495    // Forth word definition
496    ForthDef {
497        name: String,
498        body: Vec<Box<AlephTree>>,
499        #[serde(alias="isImmediate")]
500        is_immediate: bool,
501    },
502
503    // Forth constant
504    ForthConst {
505        name: String,
506        value: Box<AlephTree>,
507    },
508
509    // Forth variable
510    ForthVar {
511        name: String,
512    },
513
514    // Forth CREATE...DOES>
515    ForthCreate {
516        name: String,
517        allot_size: Option<Box<AlephTree>>,
518        does_body: Option<Vec<Box<AlephTree>>>,
519    },
520
521    // Stack operations
522    ForthDup,      // DUP ( n -- n n )
523    ForthDrop,     // DROP ( n -- )
524    ForthSwap,     // SWAP ( n1 n2 -- n2 n1 )
525    ForthOver,     // OVER ( n1 n2 -- n1 n2 n1 )
526    ForthRot,      // ROT ( n1 n2 n3 -- n2 n3 n1 )
527    ForthMinusRot, // -ROT ( n1 n2 n3 -- n3 n1 n2 )
528    ForthNip,      // NIP ( n1 n2 -- n2 )
529    ForthTuck,     // TUCK ( n1 n2 -- n2 n1 n2 )
530    ForthPick {    // PICK ( ... n -- ... x )
531        depth: Box<AlephTree>,
532    },
533    ForthRoll {    // ROLL ( ... n -- ... )
534        depth: Box<AlephTree>,
535    },
536
537    // Double stack operations
538    ForthTwoDup,   // 2DUP
539    ForthTwoDrop,  // 2DROP
540    ForthTwoSwap,  // 2SWAP
541    ForthTwoOver,  // 2OVER
542
543    // Return stack operations
544    ForthToR,      // >R ( n -- ) ( R: -- n )
545    ForthFromR,    // R> ( -- n ) ( R: n -- )
546    ForthRFetch,   // R@ ( -- n ) ( R: n -- n )
547
548    // Arithmetic operations (reuse existing Add, Sub, Mul, Div when possible)
549    ForthMod,      // MOD
550    ForthDivMod,   // /MOD
551    ForthMulDiv,   // */
552    ForthMulDivMod,// */MOD
553    ForthOnePlus,  // 1+
554    ForthOneMinus, // 1-
555    ForthTwoMul,   // 2*
556    ForthTwoDiv,   // 2/
557    ForthAbs,      // ABS
558    ForthNegate,   // NEGATE (can reuse Neg)
559    ForthMin,      // MIN
560    ForthMax,      // MAX
561
562    // Bitwise operations (can reuse And, Or when possible)
563    ForthXor,      // XOR
564    ForthInvert,   // INVERT
565    ForthLShift,   // LSHIFT
566    ForthRShift,   // RSHIFT
567
568    // Comparison operations (can reuse Eq, LE when possible)
569    ForthNotEq,    // <>
570    ForthLessThan, // <
571    ForthGreater,  // >
572    ForthGreaterEq,// >=
573    ForthZeroEq,   // 0=
574    ForthZeroNotEq,// 0<>
575    ForthZeroLess, // 0<
576    ForthZeroGreater, // 0>
577
578    // Memory operations
579    ForthFetch,    // @ ( addr -- n )
580    ForthStore,    // ! ( n addr -- )
581    ForthPlusStore,// +! ( n addr -- )
582    ForthCFetch,   // C@ ( addr -- c )
583    ForthCStore,   // C! ( c addr -- )
584    ForthCells,    // CELLS ( n -- n*cell_size )
585    ForthAllot,    // ALLOT ( n -- )
586    ForthComma,    // , ( n -- )
587    ForthCComma,   // C, ( c -- )
588    ForthHere,     // HERE ( -- addr )
589
590    // I/O operations
591    ForthDot,      // . ( n -- )
592    ForthEmit,     // EMIT ( c -- )
593    ForthCR,       // CR ( -- )
594    ForthSpace,    // SPACE ( -- )
595    ForthSpaces {  // SPACES ( n -- )
596        count: Box<AlephTree>,
597    },
598    ForthType {    // TYPE ( addr u -- )
599        addr: Box<AlephTree>,
600        count: Box<AlephTree>,
601    },
602    ForthKey,      // KEY ( -- c )
603    ForthAccept {  // ACCEPT ( addr +n1 -- +n2 )
604        addr: Box<AlephTree>,
605        max_len: Box<AlephTree>,
606    },
607    ForthDotQuote {// ." text"
608        text: String
609    },
610    ForthSQuote {  // S" text"
611        text: String
612    },
613
614    // Control structures
615    ForthBeginUntil {  // BEGIN...UNTIL
616        body: Vec<Box<AlephTree>>,
617        condition: Box<AlephTree>,
618    },
619
620    ForthBeginWhileRepeat {  // BEGIN...WHILE...REPEAT
621        condition: Box<AlephTree>,
622        while_body: Vec<Box<AlephTree>>,
623        repeat_body: Vec<Box<AlephTree>>,
624    },
625
626    ForthBeginAgain {  // BEGIN...AGAIN (infinite loop)
627        body: Vec<Box<AlephTree>>,
628    },
629
630    ForthDoLoop {      // DO...LOOP
631        body: Vec<Box<AlephTree>>,
632    },
633
634    ForthDoPlusLoop {  // DO...+LOOP
635        body: Vec<Box<AlephTree>>,
636        increment: Box<AlephTree>,
637    },
638
639    ForthLeave,        // LEAVE
640
641    ForthCase {        // CASE...ENDCASE
642        #[serde(alias="whenClauses")]
643        when_clauses: Vec<Box<AlephTree>>,
644        default: Option<Vec<Box<AlephTree>>>,
645    },
646
647    ForthOf {          // OF...ENDOF
648        value: Box<AlephTree>,
649        body: Vec<Box<AlephTree>>,
650    },
651
652    // Loop index access
653    ForthI,            // I (current loop index)
654    ForthJ,            // J (outer loop index)
655
656    // Execution tokens
657    ForthTick {        // ' (tick)
658        word: String,
659    },
660
661    ForthBracketTick { // [']
662        word: String,
663    },
664
665    ForthExecute {     // EXECUTE ( xt -- )
666        xt: Box<AlephTree>,
667    },
668
669    // Compilation words
670    ForthLiteral {     // LITERAL
671        value: Box<AlephTree>,
672    },
673
674    ForthPostpone {    // POSTPONE
675        word: String,
676    },
677
678    ForthBracket,      // [ (enter interpretation mode)
679    ForthBracketClose, // ] (enter compilation mode)
680
681    ForthImmediate,    // IMMEDIATE
682
683    ForthRecursive,    // RECURSIVE
684
685    // Dictionary manipulation
686    ForthForget {      // FORGET
687        word: String,
688    },
689
690    ForthWords,        // WORDS (list all words)
691
692    ForthSee {         // SEE (decompile word)
693        word: String,
694    },
695
696    // String operations
697    ForthEvaluate {    // EVALUATE ( addr u -- )
698        addr: Box<AlephTree>,
699        count: Box<AlephTree>,
700    },
701
702    // Conversion operations
703    ForthSToD,         // S>D (single to double)
704    ForthDToS,         // D>S (double to single)
705
706    // Program control
707    ForthQuit,         // QUIT (outer interpreter loop)
708    ForthAbort,        // ABORT
709    ForthAbortQuote {  // ABORT" message"
710        message: String,
711    },
712
713    // Comment (Forth-style)
714    ForthComment {     // ( comment )
715        text: String,
716    },
717
718    ForthLineComment { // \ comment
719        text: String,
720    },
721
722    // Hexadecimal number
723    ForthHex {         // 0x prefix or HEX mode
724        value: String,
725    },
726
727    // Program structure
728    ForthProgram {
729        definitions: Vec<Box<AlephTree>>,
730    },
731
732    ForthSequence {    // Sequence of Forth words
733        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}