6 static TokenType2 opPrec[][4] =
11 { '<', '>', leOp, geOp },
20 static define numPrec = sizeof(opPrec) / sizeof(opPrec[0]);
22 static bool isPrecedence(TokenType2 this, int l)
24 // TO OPTIMIZE: return opPrec[this] == l
28 for(o = 0; o < sizeof(opPrec[0]) / sizeof(opPrec[0][0]); o++)
30 TokenType2 op = opPrec[l][o];
40 public class ASTIdentifier : ASTNode
53 ASTIdentifier ::parse()
56 return { string = CopyString(token.text) };
60 public class ASTTypeName : ASTNode
64 ASTDeclarator declarator;
65 ClassObjectType classObjectType;
66 ASTExpression bitCount;
70 SpecsList specs = SpecsList::parse();
71 ASTDeclarator decl = ASTDeclarator::parse();
73 return { qualifiers = specs, declarator = decl };
79 if(qualifiers) qualifiers.print();
80 if(declarator) { if(qualifiers) Print(" "); declarator.print(); }
85 public class ASTExpression : ASTNode
90 virtual float Compute();
99 // *** COMPILING DATA ***
111 ASTExpression ::parse()
113 return ExpAssignment::parse();
137 public class ExpList : ASTList<ASTExpression>
141 return (ExpList)ASTList::parse(class(ExpList), ASTExpression::parse, ',');
146 public class ExpCompound : ASTExpression
148 ASTStatement compound;
152 static ASTExpression parseSimplePrimaryExpression()
155 simple_primary_expression:
156 instantiation_unnamed { $$ = MkExpInstance($1); $$.loc = @$; }
157 | EXTENSION '(' compound_statement ')' { $$ = MkExpExtensionCompound($3); $$.loc = @$; }
158 | EXTENSION '(' expression ')' { $$ = MkExpExtensionExpression($3); $$.loc = @$; }
159 | EXTENSION '(' type_name ')' initializer { $$ = MkExpExtensionInitializer($3, $5); $$.loc = @$; }
160 | EXTENSION '(' type_name ')' '(' type_name ')' initializer { $$ = MkExpExtensionInitializer($3, MkInitializerAssignment(MkExpExtensionInitializer($6, $8))); $$.loc = @$; }
162 | '(' ')' { Expression exp = MkExpDummy(); exp.loc.start = @1.end; exp.loc.end = @2.start; $$ = MkExpBrackets(MkListOne(exp)); $$.loc = @$; yyerror(); }
163 | NEWOP new_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,$3), $5); $$.loc = @$; }
164 | NEWOP new_specifiers abstract_declarator_noarray '[' constant_expression_error ']' { $$ = MkExpNew(MkTypeName($2,$3), $5); $$.loc = @$; }
165 | NEWOP new_specifiers '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,null), $4); $$.loc = @$; }
166 | NEWOP new_specifiers '[' constant_expression_error ']' { $$ = MkExpNew(MkTypeName($2,null), $4); $$.loc = @$; }
167 | NEW0OP new_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,$3), $5); $$.loc = @$; }
168 | NEW0OP new_specifiers abstract_declarator_noarray '[' constant_expression_error ']' { $$ = MkExpNew0(MkTypeName($2,$3), $5); $$.loc = @$; }
169 | NEW0OP new_specifiers '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,null), $4); $$.loc = @$; }
170 | NEW0OP new_specifiers '[' constant_expression_error ']' { $$ = MkExpNew0(MkTypeName($2,null), $4); $$.loc = @$; }
171 | RENEW constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,$4), $6); $$.loc = @$; }
172 | RENEW constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression_error ']' { $$ = MkExpRenew($2, MkTypeName($3,$4), $6); $$.loc = @$; }
173 | RENEW constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,null), $5); $$.loc = @$; }
174 | RENEW constant_expression renew_specifiers '[' constant_expression_error ']' { $$ = MkExpRenew($2, MkTypeName($3,null), $5); $$.loc = @$; }
175 | RENEW0 constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,$4), $6); $$.loc = @$; }
176 | RENEW0 constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression_error ']' { $$ = MkExpRenew0($2, MkTypeName($3,$4), $6); $$.loc = @$; }
177 | RENEW0 constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,null), $5); $$.loc = @$; }
178 | RENEW0 constant_expression renew_specifiers '[' constant_expression_error ']' { $$ = MkExpRenew0($2, MkTypeName($3,null), $5); $$.loc = @$; }
179 | CLASS '(' declaration_specifiers ')' { $$ = MkExpClass($3, null); $$.loc = @$; }
180 | CLASS '(' declaration_specifiers abstract_declarator ')' { $$ = MkExpClass($3, $4); $$.loc = @$; }
181 | CLASS '(' identifier ')' { $$ = MkExpClass(MkListOne(MkSpecifierName($3.string)), null); FreeIdentifier($3); $$.loc = @$; }
182 | VAARG '(' assignment_expression ',' type_name ')' { $$ = MkExpVaArg($3, $5); $$.loc = @$; }
184 | CLASS_DATA '(' identifier ')' { $$ = MkExpClassData($3); $$.loc = @$; }
190 | '[' argument_expression_list ']' { $$ = MkExpArray($2); $$.loc = @$; }
193 if(peekToken().type == constant)
194 return ExpConstant::parse();
195 else if(nextToken.type == identifier)
197 ExpIdentifier exp = ExpIdentifier::parse();
198 if(peekToken().type == '{')
201 specs.Add(SpecName { name = exp.identifier.string });
202 return ExpInstance::parse(specs, null);
206 else if(nextToken.type == stringLiteral)
207 return ExpString::parse();
208 else if(nextToken.type == '{')
209 return ExpInstance::parse(null, null);
214 static ASTExpression parsePrimaryExpression()
216 if(peekToken().type == '(')
220 exp.list = ExpList::parse();
221 if(peekToken().type == ')')
226 return parseSimplePrimaryExpression();
229 static ASTExpression parsePostfixExpression()
231 ASTExpression exp = parsePrimaryExpression();
234 if(peekToken().type == '[')
235 exp = ExpIndex::parse(exp);
236 else if(nextToken.type == '(')
237 exp = ExpCall::parse(exp);
238 else if(nextToken.type == '.')
239 exp = ExpMember::parse(exp);
240 else if(nextToken.type == ptrOp)
241 exp = ExpPointer::parse(exp);
242 else if(nextToken.type == incOp || nextToken.type == decOp)
245 exp = ExpOperation { exp1 = exp, op = token.type };
253 static ASTExpression parseUnaryExpression()
256 if(nextToken.type == incOp || nextToken.type == decOp)
259 return ExpOperation { op = token.type, exp2 = parseUnaryExpression() };
261 else if(nextToken.type.isUnaryOperator)
264 return ExpOperation { op = token.type, exp2 = ExpCast::parse() };
267 else if(nextToken.type == SIZEOF)
268 return ExpSizeof::parse();
269 else if(nextToken.type == ALIGNOF)
270 return ExpAlignOf::parse();
273 return parsePostfixExpression();
276 public class ExpConstant : ASTExpression
285 ExpConstant ::parse()
287 return { constant = CopyString(readToken().text); };
292 return (float)atof(constant);
296 public class ExpString : ASTExpression
307 return { string = CopyString(readToken().text) };
311 public class ExpIdentifier : ASTExpression
313 ASTIdentifier identifier;
320 ExpIdentifier ::parse()
322 return { identifier = ASTIdentifier::parse() };
326 public class ExpOperation : ASTExpression
329 ASTExpression exp1, exp2;
333 if(exp1) { exp1.print(); if(exp2) Print(" "); }
335 if(exp2) { if(exp1) Print(" "); exp2.print(); }
338 ASTExpression ::parse(int prec)
340 ASTExpression exp = (prec > 0) ? parse(prec-1) : ExpCast::parse();
341 while(isPrecedence(peekToken().type, prec))
342 exp = ExpOperation { exp1 = exp, op = readToken().type, exp2 = (prec > 0) ? parse(prec-1) : ExpCast::parse() };
352 case '*': return exp1.Compute() * exp2.Compute();
353 case '/': return exp1.Compute() / exp2.Compute();
354 case '-': return exp1.Compute() - exp2.Compute();
355 case '+': return exp1.Compute() + exp2.Compute();
362 case '-': return -exp2.Compute();
363 case '+': return exp2.Compute();
370 public class ExpAssignment : ExpOperation
372 ASTExpression ::parse()
374 ASTExpression exp = ExpConditional::parse();
375 if(peekToken().type.isAssignmentOperator)
376 exp = ExpAssignment { exp1 = exp, op = readToken().type, exp2 = ExpAssignment::parse() };
381 public class ExpBrackets : ASTExpression
389 if(list) list.print();
395 return (list && list.lastIterator.data) ? list.lastIterator.data.Compute() : 0;
399 public class ExpConditional : ASTExpression
402 ASTExpression condition;
404 ASTExpression elseExp;
408 if(condition) condition.print();
410 if(expList) expList.print();
416 ASTExpression ::parse()
418 ASTExpression exp = ExpOperation::parse(numPrec-1);
419 if(peekToken().type == '?')
421 exp = ExpConditional { condition = exp, expList = ExpList::parse() };
422 if(peekToken().type == ':')
423 ((ExpConditional)exp).elseExp = ExpConditional::parse();
429 public class ExpIndex : ASTExpression
438 if(index) index.print();
442 ExpIndex ::parse(ASTExpression e)
446 exp = ExpIndex { exp = e, index = ExpList::parse() };
447 if(peekToken().type == ']')
453 public class ExpMember : ASTExpression
456 ASTIdentifier member;
457 // MemberType memberType;
468 ExpMember ::parse(ASTExpression e)
471 return { exp = e, member = ASTIdentifier::parse() };
475 public class ExpPointer : ExpMember
485 ExpPointer ::parse(ASTExpression e)
488 return { exp = e, member = ASTIdentifier::parse() };
492 public class ExpCall : ASTExpression
502 if(arguments) arguments.print();
506 ExpCall ::parse(ASTExpression e)
510 exp = ExpCall { exp = e, arguments = ExpList::parse() };
511 if(peekToken().type == ')')
517 public class ExpCast : ASTExpression
519 ASTTypeName typeName;
522 ASTExpression ::parse()
524 ASTExpression exp = parseUnaryExpression();
525 // TODO: Deal with cast ambiguity
530 public class ExpInstance : ASTExpression
532 ASTInstantiation instance;
534 ExpInstance ::parse(SpecsList specs, InitDeclList decls)
536 return { instance = ASTInstantiation::parse(specs, decls) };
541 if(instance) instance.print();
545 public class ExpSizeOf : ASTExpression
547 ASTTypeName typeName;
555 public class ExpAlignOf : ASTExpression
557 ASTTypeName typeName;
569 OldList * specifiers;
602 Initializer initializer;
613 public class InstanceInit : ASTNode
615 InstanceInit ::parse()
617 int a = pushAmbiguity();
618 SpecsList specs = SpecsList::parse();
619 InitDeclList decls = InitDeclList::parse();
622 if(nextToken.type == '{' || (specs && decls))
625 return InstInitFunction::parse(specs, decls);
627 else if(nextToken.type != '}')
630 return InstInitMember::parse();
636 public class InstInitMember : InstanceInit
638 MemberInitList members;
640 InstInitMember ::parse()
642 MemberInitList list = MemberInitList::parse();
644 return { members = list };
649 if(members) members.print();
653 public class InstInitFunction : InstanceInit
655 ASTClassFunction function;
657 InstInitFunction ::parse(SpecsList specs, InitDeclList decls)
659 return { function = ASTClassFunction::parse(specs, decls) };
664 if(function) function.print();
668 public class InstInitList : ASTList<InstanceInit>
670 InstInitList ::parse()
672 return (InstInitList)ASTList::parse(class(InstInitList), InstanceInit::parse, 0);
681 public class ASTInstantiation : ASTNode
687 InstInitList members;
692 Location nameLoc, insideLoc;
695 ASTInstantiation ::parse(SpecsList specs, InitDeclList decls)
697 ASTInstantiation inst { };
698 if(specs && specs[0])
699 inst._class = specs[0];
701 if(decls && decls[0] && decls[0].declarator && decls[0].declarator._class == class(DeclIdentifier))
702 inst.exp = ExpIdentifier { identifier = ((DeclIdentifier)decls[0].declarator).identifier };
705 inst.members = InstInitList::parse();
706 if(peekToken().type == '}')
713 bool multiLine = false;
716 for(m : members; m._class == class(InstInitFunction))
723 if(_class) { _class.print(); if(!multiLine || exp) Print(" "); }
724 if(exp) { exp.print(); if(!multiLine) Print(" "); }
736 if(members && members[0])
740 Iterator<InstanceInit> it { members };
743 InstanceInit init = it.data;
744 Link nextLink = (Link)members.GetNext(it.pointer);
745 if(init._class != class(InstInitFunction))
748 if(init._class == class(InstInitMember))
752 InstanceInit next = nextLink ? (InstanceInit)nextLink.data : null;
754 if(next._class == class(InstInitFunction))
757 else if(init._class != class(InstInitFunction))