compiler/libec2: Initial go at a handwritten Recursive Descent parser
[sdk] / compiler / libec2 / src / externals.ec
1 import "statements"
2
3 public class ASTDeclaration : ASTStmtOrDecl
4 {
5 public:
6    DeclarationType type;
7
8    ASTDeclaration ::parse(SpecsList specs, InitDeclList decls)
9    {
10       if(peekToken().type == ';')
11          readToken();
12       return DeclarationInit { specifiers = specs, declarators = decls };
13    }
14 }
15
16 public class DeclarationInit : ASTDeclaration
17 {
18 public:
19    SpecsList specifiers;
20    InitDeclList declarators;
21
22    void print()
23    {
24       if(specifiers)
25       {
26          for(s : specifiers)
27             s.print();
28          Print(" ");
29       }
30       if(declarators)
31          declarators.print();
32       Print(";");
33    }
34 }
35
36 public class ASTFunctionDefinition : ASTNode
37 {
38 public:
39    SpecsList specifiers;
40    ASTDeclarator declarator;
41    List<ASTDeclaration> oldStyleDeclarations;
42    StmtCompound body;
43
44    void print()
45    {
46       PrintLn("");
47       if(specifiers) 
48       {
49          for(s : specifiers)
50             s.print();
51          Print(" ");
52       }
53       if(declarator)
54          declarator.print();
55       PrintLn("");
56       if(body)
57          body.print();
58    }
59
60    ASTFunctionDefinition ::parse(SpecsList specs, InitDeclList decls)
61    {
62       ASTFunctionDefinition function { };
63       ASTDeclarator decl = (decls && decls[0]) ? decls[0].declarator : null;
64       if(decl && decls[0]) decls[0].declarator = null;
65       delete decls;
66       function.specifiers = (void *)specs;         // TOFIX: #768
67       function.declarator = decl;
68       function.body = StmtCompound::parse();
69       return function;
70    }
71    /*
72    Class _class;
73    OldList attached;    // For IDE
74    AccessMode declMode;
75
76    Type type;
77    Symbol propSet;
78
79    int tempCount;
80    bool propertyNoThis; // Not used yet; might use to support both this = and return syntax for conversion properties
81    */
82 };
83
84 /*
85    union
86    {
87       FunctionDefinition function;
88       ClassDefinition _class;
89       Declaration declaration;
90       char * importString;
91       Identifier id;
92       DBTableDef table;
93    };
94    ImportType importType;
95 };
96 */
97
98 public class AST : ASTList<ASTNode>
99 {
100    ASTNode ::ParseExternalDeclaration()
101    {
102       SpecsList specs = SpecsList::parse();
103       InitDeclList decls = InitDeclList::parse();
104
105       if(peekToken().type == '{')
106          return ASTFunctionDefinition::parse(specs, decls);
107       else if(specs || decls)
108          return ASTDeclaration::parse(specs, decls);
109       else
110       {
111          readToken(); // Error
112          return null;
113       }
114    }
115 public:
116    AST ::parse()
117    {
118       AST ast = null;
119       while(peekToken().type)
120       {
121          ASTNode n = ParseExternalDeclaration();
122          if(n)
123          {
124             if(!ast) ast = { };
125             ast.Add(n);
126          }
127       }
128       return ast;
129    }
130
131    void print()
132    {
133       for(n : this)
134       {
135          n.print();
136          PrintLn("");
137       }
138    }
139 }