66a3284b0382863a0324ee44c1db687efc275dec
[sdk] / compiler / libec2 / src / declarators.ec
1 import "expressions"
2
3 public class ASTPointer : ASTNode
4 {
5    SpecsList qualifiers;
6    ASTPointer pointer;
7
8    void print()
9    {
10       Print("*");
11       if(qualifiers) qualifiers.print();
12       if(pointer) pointer.print();
13    }
14
15    ASTPointer ::parse()
16    {
17       ASTPointer ptr { };
18       readToken();
19       while(peekToken().type == '*')
20       {
21          readToken();
22          ptr = { pointer = ptr };
23       }
24       return ptr;
25    }
26 }
27
28 public class ASTDeclarator : ASTNode
29 {
30 public:
31    DeclaratorType type;
32    // Symbol symbol;
33
34    ASTDeclarator ::parse()
35    {
36       ASTDeclarator decl = null;
37
38       if(peekToken().type == '*')
39          decl = DeclPointer::parse();
40       else
41       {
42          if(peekToken().type == IDENTIFIER)
43             decl = DeclIdentifier::parse();
44          else if(nextToken.type == '(')
45             decl = DeclBrackets::parse();
46          if(decl)
47          {
48             while(true)
49             {
50                if(peekToken().type == '[')
51                   decl = DeclArray::parse(decl);
52                else if(nextToken.type == '(')
53                   decl = DeclFunction::parse(decl);
54                else
55                   break;
56             }
57          }
58       }
59       return decl;
60    }
61 }
62
63 public class TypeNameList : ASTList<ASTTypeName>
64 {
65    TypeNameList ::parse()
66    {
67       TypeNameList list = null;
68       int a = pushAmbiguity();
69       while(true)
70       {
71          ASTTypeName e = ASTTypeName::parse();
72          peekToken();
73          if(e && (nextToken.type == ',' || nextToken.type == ')'))
74          {
75             if(!list) list = { };
76             list.Add(e);
77
78             clearAmbiguity();
79             if(nextToken.type == ',')
80             {
81                readToken();
82                a = pushAmbiguity();
83             }
84             else
85                break;
86          }
87          else
88          {
89             if(list)
90                list.Add({});
91             popAmbiguity(a);
92             break;
93          }
94       }
95       return list;
96       // return (TypeNameList)ASTList::parse(class(TypeNameList), ASTTypeName::parse, ',');
97    }
98 }
99
100 public class DeclFunction : ASTDeclarator
101 {
102 public:
103    ASTDeclarator declarator;
104    TypeNameList parameters;
105
106    void print()
107    {
108       if(declarator) declarator.print();
109       Print("(");
110       if(parameters) parameters.print();
111       Print(")");
112    }
113
114    DeclFunction ::parse(ASTDeclarator d)
115    {
116       DeclFunction decl { declarator = d };
117       readToken();
118       if(peekToken().type != ')') decl.parameters = TypeNameList::parse();
119       if(peekToken().type == ')')
120          readToken();
121       return decl;
122    }
123 }
124
125 public class DeclIdentifier : ASTDeclarator
126 {
127    ASTIdentifier identifier;
128
129    void print()
130    {
131       if(identifier) identifier.print();
132    }
133
134    DeclIdentifier ::parse()
135    {
136       return { identifier = ASTIdentifier::parse() };
137    }
138 }
139
140 public class DeclBrackets : ASTDeclarator
141 {
142    ASTDeclarator declarator;
143
144    void print()
145    {
146       Print("(");
147       if(declarator) declarator.print();
148       Print(")");
149    }
150
151    DeclBrackets ::parse()
152    {
153       DeclBrackets decl = null;
154       ASTDeclarator d;
155       readToken();
156       d = ASTDeclarator::parse();
157       if(d)
158          decl = { declarator = d };
159       if(peekToken().type == ')')
160          readToken();
161       return decl;
162    }
163 }
164
165 public class DeclArray : ASTDeclarator
166 {
167    ASTDeclarator declarator;
168    ASTExpression exp;
169    // ASTSpecifier enumClass;
170
171    void print()
172    {
173       if(declarator) declarator.print();
174       Print("[");
175       if(exp) exp.print();
176       Print("]");
177    }
178
179    DeclArray ::parse(ASTDeclarator d)
180    {
181       DeclArray decl { declarator = d };
182       readToken();
183       if(peekToken().type != ']') decl.exp = ExpConditional::parse();
184       if(peekToken().type == ']') readToken();
185       return decl;
186    }
187 }
188
189 public class DeclPointer : ASTDeclarator
190 {
191    ASTDeclarator declarator;
192    ASTPointer pointer;
193
194    void print()
195    {
196       if(pointer) pointer.print();
197       if(declarator) declarator.print();
198    }
199
200    DeclPointer ::parse()
201    {
202       return { pointer = ASTPointer::parse(), declarator = ASTDeclarator::parse() };
203    }
204 }
205
206 public class DeclStruct : ASTDeclarator
207 {
208    ASTDeclarator declarator;
209    ASTExpression exp;
210    ASTExpression posExp;
211    ASTAttrib attrib;
212
213    DeclStruct ::parse()
214    {
215       return { declarator = ASTDeclarator::parse(); };
216    }
217 }
218
219 public class DeclExtended : ASTDeclarator
220 {
221    ExtDecl extended;
222 }
223
224 public class ASTInitializer : ASTNode
225 {
226    // bool isConstant;
227    ASTInitializer ::parse()
228    {
229       if(peekToken().type == '{')
230       {
231          InitList init;
232          readToken();
233          init = InitList::parse();
234          if(peekToken().type == '}') readToken();
235          return init;
236       }
237       else
238          return InitExp { exp = ASTExpression::parse() };
239    }
240 };
241
242 public class InitExp : ASTInitializer
243 {
244    ASTExpression exp;
245
246    void print()
247    {
248       if(exp)
249          exp.print();
250    }
251 };
252
253 public class InitList : ASTInitializer
254 {
255    ASTList<ASTInitializer> list;
256
257    void print()
258    {
259       if(list)
260       {
261          Print("{ ");
262          list.print();
263          Print(" }");
264       }
265    }
266
267    InitList ::parse()
268    {
269       ASTList<ASTInitializer> list = (ASTList<ASTInitializer>)ASTList::parse(class(ASTList<ASTInitializer>), ASTInitializer::parse, ',');
270       return list ? { list = (void *)list } : null;
271    }
272 };
273
274 public class ASTInitDeclarator : ASTNode
275 {
276    ASTDeclarator declarator;
277    ASTInitializer initializer;
278
279    void print()
280    {
281       if(declarator) declarator.print();
282       if(initializer)
283       {
284          Print(" = ");
285          initializer.print();
286       }
287    }
288
289    ASTInitDeclarator ::parse()
290    {
291       ASTDeclarator decl = ASTDeclarator::parse();
292       if(decl)
293       {
294          ASTInitializer init = null;
295          if(peekToken().type == '=')
296          {
297             readToken();
298             init = ASTInitializer::parse();
299          }
300          return { declarator = decl, initializer = init };
301       }
302       return null;
303    }
304 };
305
306 public class InitDeclList : ASTList<ASTInitDeclarator>
307 {
308    InitDeclList ::parse()
309    {
310       return (InitDeclList)ASTList::parse(class(InitDeclList), ASTInitDeclarator::parse, ',');
311    }
312 }