compiler/libec2: Support for instantiations
[sdk] / compiler / libec2 / src / externals.ec
1 import "statements"
2
3 public class ASTDeclaration : ASTStmtOrDecl
4 {
5 public:
6    DeclarationType type;
7    // ASTSpecifier extStorage;
8    // Symbol symbol;
9    // AccessMode declMode;
10
11    ASTDeclaration ::parse(SpecsList specs, InitDeclList decls)
12    {
13       peekToken();
14       if(nextToken.type == '{')
15          return DeclarationInstance::parse(specs, decls);
16       else if(nextToken.type == ';')
17          readToken();
18       return DeclarationInit { specifiers = specs, declarators = decls };
19    }
20 }
21
22 public class DeclarationInit : ASTDeclaration
23 {
24 public:
25    SpecsList specifiers;
26    InitDeclList declarators;
27
28    void print()
29    {
30       if(specifiers)
31       {
32          specifiers.print();
33          if(declarators) Print(" ");
34       }
35       if(declarators) declarators.print();
36       Print(";");
37    }
38 }
39
40 public class DeclarationInstance : ASTDeclaration
41 {
42    ASTInstantiation inst;
43
44    DeclarationInstance ::parse(SpecsList specs, InitDeclList decls)
45    {
46       ASTInstantiation inst = ASTInstantiation::parse(specs, decls);
47       if(peekToken().type == ';')
48          readToken();
49       if(inst)
50       {
51          return { inst = inst };
52       }
53       return null;
54    }
55
56    void print()
57    {
58       if(inst)
59       {
60          inst.print();
61          Print(";");
62       }
63    }
64 }
65
66 public class DeclarationDefine : ASTDeclaration
67 {
68    ASTIdentifier id;
69    ASTExpression exp;
70 }
71
72 public class ASTFunctionDefinition : ASTNode
73 {
74 public:
75    SpecsList specifiers;
76    ASTDeclarator declarator;
77    List<ASTDeclaration> oldStyleDeclarations;
78    StmtCompound body;
79
80    void print()
81    {
82       // PrintLn("");
83       printIndent();
84       if(specifiers) 
85       {
86          for(s : specifiers)
87             s.print();
88          Print(" ");
89       }
90       if(declarator)
91          declarator.print();
92       PrintLn("");
93       if(body)
94          body.print();
95    }
96
97    ASTFunctionDefinition ::parse(SpecsList specs, InitDeclList decls)
98    {
99       ASTFunctionDefinition function { };
100       ASTDeclarator decl = (decls && decls[0]) ? decls[0].declarator : null;
101       if(decl && decls[0]) decls[0].declarator = null;
102       delete decls;
103       function.specifiers = specs;
104       function.declarator = decl;
105       function.body = StmtCompound::parse();
106       return function;
107    }
108    /*
109    Class _class;
110    OldList attached;    // For IDE
111    AccessMode declMode;
112
113    Type type;
114    Symbol propSet;
115
116    int tempCount;
117    bool propertyNoThis; // Not used yet; might use to support both this = and return syntax for conversion properties
118    */
119 };
120
121 class ASTImport : ASTNode
122 {
123    String importString;
124
125    void print()
126    {
127       Print("import ");
128       PrintLn(importString);
129    }
130 }
131
132 /*
133    union
134    {
135       ASTFunctionDefinition function;
136       SpecClass _class;
137       ASTDeclaration declaration;
138       ASTIdentifier id;
139       DBTableDef table;
140    };
141 };
142 */
143
144 /*
145 class External
146 {
147    ImportType importType;
148 }
149 */
150
151 public ASTDeclarator GetFuncDecl(ASTDeclarator decl)
152 {
153    ASTDeclarator funcDecl = null;
154    while(decl && decl._class != class(DeclIdentifier))
155    {
156       if(decl._class == class(DeclFunction))
157          funcDecl = decl;
158       decl = decl.declarator;
159    }
160    return funcDecl;
161 }
162
163 public class AST : ASTList<ASTNode>
164 {
165    ASTNode ::ParseExternalDeclaration()
166    {
167       SpecsList specs = null; 
168       InitDeclList decls = null;
169
170       peekToken();
171       if(nextToken.type == IMPORT)
172       {
173          ASTImport astImport { };
174          readToken();
175          peekToken();
176          if(nextToken.type == STATIC)
177          {
178             readToken();
179          }
180          else if(nextToken.type == IDENTIFIER)
181          {
182             readToken();
183          }
184          peekToken();
185          if(nextToken.type == STRING_LITERAL)
186          {
187             readToken();
188             astImport.importString = CopyString(token.text);
189          }
190          return astImport;
191       }
192       else
193       {
194          specs = SpecsList::parse();
195          decls = InitDeclList::parse();
196          if(nextToken.type == '{')
197          {
198             ASTDeclarator funcDecl = GetFuncDecl((decls && decls[0]) ? decls[0].declarator : null);
199             if(funcDecl)
200                return ASTFunctionDefinition::parse(specs, decls);
201             else
202                return ASTDeclaration::parse(specs, decls);
203          }
204          else if(specs || decls)
205             return ASTDeclaration::parse(specs, decls);
206          else
207          {
208             readToken(); // Error
209             return null;
210          }
211       }
212    }
213 public:
214    AST ::parse()
215    {
216       AST ast = null;
217       while(peekToken().type)
218       {
219          ASTNode n = ParseExternalDeclaration();
220          if(n)
221          {
222             if(!ast) ast = { };
223             ast.Add(n);
224          }
225       }
226       return ast;
227    }
228
229    void print()
230    {
231       for(n : this)
232       {
233          n.print();
234          PrintLn("");
235       }
236    }
237 }