compiler/libec2: Support for class value initializers, error recovery before initiali...
[sdk] / compiler / libec2 / src / classes.ec
1 import "externals"
2
3 public class ASTMemberInit : ASTNode
4 {
5 public:
6    Location realLoc;
7    List<ASTIdentifier> identifiers;
8    ASTInitializer initializer;
9
10    // COMPILE DATA
11    bool used;
12    bool variable;
13    bool takeOutExp;
14
15    ASTMemberInit ::parse()
16    {
17       ASTMemberInit init { };
18       while(true)
19       {
20          ASTIdentifier id = ASTIdentifier::parse();
21          if(id)
22          {
23             if(!init.identifiers) init.identifiers = { };
24             init.identifiers.Add(id);
25             if(peekToken().type != '.')
26                break;
27          }
28       }
29       if(peekToken().type == '=')
30       {
31          readToken();
32          init.initializer = ASTInitializer::parse();
33       }
34       return init;
35    }
36
37    void print()
38    {
39       if(identifiers)
40       {
41          Iterator<ASTIdentifier> it { identifiers };
42          while(it.Next())
43          {
44             it.data.print();
45             if(identifiers.GetNext(it.pointer))
46                Print(".");
47          }
48       }
49       Print(" = ");
50       if(initializer) initializer.print();
51    }
52 };
53
54 public class MemberInitList : ASTList<ASTMemberInit>
55 {
56    MemberInitList ::parse()
57    {
58       MemberInitList list = (MemberInitList)ASTList::parse(class(MemberInitList), ASTMemberInit::parse, ',');
59       if(peekToken().type == ';')
60          readToken();
61       return list;
62    }
63 }
64
65 public class ASTPropertyDef : ASTNode
66 {
67    SpecsList specifiers;
68    ASTDeclarator declarator;
69    ASTIdentifier id;
70    ASTStatement getStmt;
71    ASTStatement setStmt;
72    ASTStatement issetStmt;
73    Symbol symbol;
74    bool conversion;
75    bool isWatchable;
76    ASTExpression category;
77 };
78
79 public class ClassDefList : ASTList<ASTClassDef>
80 {
81    ClassDefList ::parse()
82    {
83       return (ClassDefList)ASTList::parse(class(ClassDefList), ASTClassDef::parse, 0);
84    }
85
86    void printSep()
87    {
88    }
89 }
90
91 public class ASTClassDef : ASTNode
92 {
93 public:
94    AccessMode memberAccess;
95
96    // IDE
97    void * object;
98
99    ASTClassDef ::parse()
100    {
101       SpecsList specs = null;
102       InitDeclList decls = null;
103       int a = -1;
104
105       peekToken();
106       if(nextToken.type == '}')
107          return null;
108
109       if(nextToken.type == IDENTIFIER)
110          a = pushAmbiguity();
111
112       specs = SpecsList::parse();
113       decls = InitDeclList::parse();
114       peekToken();
115       if(nextToken.type == '{' || (decls && decls[0] && decls[0].declarator && decls[0].declarator._class == class(DeclFunction)))
116          return ClassDefFunction::parse(specs, decls);
117       else if((specs || decls) && (nextToken.type != '.' && nextToken.type != '='))
118       {
119          if(a > -1) clearAmbiguity();
120          return ClassDefDeclaration::parse(specs, decls);
121       }
122       else if(a > -1)
123       {
124          ClassDefInitialization init;
125          popAmbiguity(a);
126
127          init = ClassDefInitialization::parse();
128          if(init)
129             return init;
130       }
131       readToken(); // Error
132       return null;
133    }
134 };
135
136 public class ClassDefClassPropertyValue : ASTClassDef
137 {
138    ASTIdentifier id;
139    ASTInitializer initializer;
140 }
141
142 public class ClassDefDeclaration : ASTClassDef
143 {
144    ASTDeclaration decl;
145
146    ClassDefDeclaration ::parse(SpecsList specs, InitDeclList decls)
147    {
148       ASTDeclaration decl = ASTDeclaration::parse(specs, decls);
149       if(decl)
150       {
151          return { decl = decl };
152       }
153       return null;
154    }
155
156    void print()
157    {
158       printIndent();
159       if(decl) decl.print();
160       PrintLn("");
161    }
162 }
163
164 public class ASTClassFunction : ASTFunctionDefinition
165 {
166 public:
167    Class _class;
168    //List attached;    // For IDE
169    AccessMode declMode;
170    
171    // COMPILING DATA
172    Type type;
173    Symbol propSet;
174
175    bool isVirtual;
176    bool isConstructor, isDestructor;
177    bool dontMangle;
178    // int id, idCode;
179
180    ASTClassFunction ::parse(SpecsList specs, InitDeclList decls)
181    {
182       return (ASTClassFunction)ASTFunctionDefinition::parse(specs, decls);
183    }
184 };
185
186 public class ClassDefFunction : ASTClassDef
187 {
188    ASTClassFunction function;
189
190    ClassDefFunction ::parse(SpecsList specs, InitDeclList decls)
191    {
192       ASTClassFunction function = ASTClassFunction::parse(specs, decls);
193       if(function)
194          return { function = function };
195       return null;
196    }
197
198    void print()
199    {
200       if(function) function.print();
201    }
202 }
203
204 public class ClassDefInitialization : ASTClassDef
205 {
206    MemberInitList defValues;
207
208    ClassDefInitialization ::parse()
209    {
210       MemberInitList defValues = MemberInitList::parse();
211       if(defValues)
212          return { defValues = defValues };
213       return null;
214    }
215
216    void print()
217    {
218       if(defValues)
219       {
220          printIndent();
221          defValues.print();
222          PrintLn(";");
223       }
224    }
225 }
226
227 public class ClassDefProperty : ASTClassDef
228 {
229    ASTPropertyDef propertyDef;
230 }
231
232 public class ClassDefPropertyWatch : ASTClassDef
233 {
234    ASTPropertyWatch propertyWatch;
235 }
236
237 public class ClassDefDesigner : ASTClassDef
238 {
239    String designer;
240 }
241
242 public class ClassDefDefaultProperty : ASTClassDef
243 {
244    ASTIdentifier defaultProperty;
245 }