6 static TokenType opPrec[][4] =
10 { LEFT_OP, RIGHT_OP },
11 { '<', '>', LE_OP, GE_OP },
20 static define numPrec = sizeof(opPrec) / sizeof(opPrec[0]);
22 static bool isPrecedence(TokenType this, int l)
24 // TO OPTIMIZE: return opPrec[this] == l
28 for(o = 0; o < sizeof(opPrec[0]) / sizeof(opPrec[0][0]); o++)
30 TokenType 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)
196 return ExpIdentifier::parse();
197 else if(nextToken.type == STRING_LITERAL)
198 return ExpString::parse();
203 static ASTExpression parsePrimaryExpression()
205 if(peekToken().type == '(')
209 exp.list = ExpList::parse();
210 if(peekToken().type == ')')
215 return parseSimplePrimaryExpression();
218 static ASTExpression parsePostfixExpression()
220 ASTExpression exp = parsePrimaryExpression();
223 if(peekToken().type == '[')
224 exp = ExpIndex::parse(exp);
225 else if(nextToken.type == '(')
226 exp = ExpCall::parse(exp);
227 else if(nextToken.type == '.')
228 exp = ExpMember::parse(exp);
229 else if(nextToken.type == PTR_OP)
230 exp = ExpPointer::parse(exp);
231 else if(nextToken.type == INC_OP || nextToken.type == DEC_OP)
234 exp = ExpOperation { exp1 = exp, op = token.type };
242 static ASTExpression parseUnaryExpression()
245 if(nextToken.type == INC_OP || nextToken.type == DEC_OP)
248 return ExpOperation { op = token.type, exp2 = parseUnaryExpression() };
250 else if(nextToken.type.isUnaryOperator)
253 return ExpOperation { op = token.type, exp2 = ExpCast::parse() };
256 else if(nextToken.type == SIZEOF)
257 return ExpSizeof::parse();
258 else if(nextToken.type == ALIGNOF)
259 return ExpAlignOf::parse();
262 return parsePostfixExpression();
265 public class ExpConstant : ASTExpression
274 ExpConstant ::parse()
276 return { constant = CopyString(readToken().text); };
281 return (float)atof(constant);
285 public class ExpString : ASTExpression
296 return { string = CopyString(readToken().text) };
300 public class ExpIdentifier : ASTExpression
302 ASTIdentifier identifier;
309 ExpIdentifier ::parse()
311 return { identifier = ASTIdentifier::parse() };
315 public class ExpOperation : ASTExpression
318 ASTExpression exp1, exp2;
322 if(exp1) { exp1.print(); if(exp2) Print(" "); }
324 if(exp2) { if(exp1) Print(" "); exp2.print(); }
327 ASTExpression ::parse(int prec)
329 ASTExpression exp = (prec > 0) ? parse(prec-1) : ExpCast::parse();
330 while(isPrecedence(peekToken().type, prec))
331 exp = ExpOperation { exp1 = exp, op = readToken().type, exp2 = (prec > 0) ? parse(prec-1) : ExpCast::parse() };
341 case '*': return exp1.Compute() * exp2.Compute();
342 case '/': return exp1.Compute() / exp2.Compute();
343 case '-': return exp1.Compute() - exp2.Compute();
344 case '+': return exp1.Compute() + exp2.Compute();
351 case '-': return -exp2.Compute();
352 case '+': return exp2.Compute();
359 public class ExpAssignment : ExpOperation
361 ASTExpression ::parse()
363 ASTExpression exp = ExpConditional::parse();
364 if(peekToken().type.isAssignmentOperator)
365 exp = ExpAssignment { exp1 = exp, op = readToken().type, exp2 = ExpAssignment::parse() };
370 public class ExpBrackets : ASTExpression
378 if(list) list.print();
384 return (list && list.lastIterator.data) ? list.lastIterator.data.Compute() : 0;
388 public class ExpConditional : ASTExpression
391 ASTExpression condition;
393 ASTExpression elseExp;
397 if(condition) condition.print();
399 if(expList) expList.print();
405 ASTExpression ::parse()
407 ASTExpression exp = ExpOperation::parse(numPrec-1);
408 if(peekToken().type == '?')
410 exp = ExpConditional { condition = exp, expList = ExpList::parse() };
411 if(peekToken().type == ':')
412 ((ExpConditional)exp).elseExp = ExpConditional::parse();
418 public class ExpIndex : ASTExpression
427 if(index) index.print();
431 ExpIndex ::parse(ASTExpression e)
435 exp = ExpIndex { exp = e, index = ExpList::parse() };
436 if(peekToken().type == ']')
442 public class ExpMember : ASTExpression
445 ASTIdentifier member;
446 // MemberType memberType;
457 ExpMember ::parse(ASTExpression e)
460 return { exp = e, member = ASTIdentifier::parse() };
464 public class ExpPointer : ExpMember
474 ExpPointer ::parse(ASTExpression e)
477 return { exp = e, member = ASTIdentifier::parse() };
481 public class ExpCall : ASTExpression
491 if(arguments) arguments.print();
495 ExpCall ::parse(ASTExpression e)
499 exp = ExpCall { exp = e, arguments = ExpList::parse() };
500 if(peekToken().type == ')')
506 public class ExpCast : ASTExpression
508 ASTTypeName typeName;
511 ASTExpression ::parse()
513 ASTExpression exp = parseUnaryExpression();
514 // TODO: Deal with cast ambiguity
519 public class ExpInstance : ASTExpression
521 ASTInstantiation instance;
524 public class ExpSizeOf : ASTExpression
526 ASTTypeName typeName;
534 public class ExpAlignOf : ASTExpression
536 ASTTypeName typeName;
548 OldList * specifiers;
581 Initializer initializer;
592 public class InstanceInit : ASTNode { }
594 public class InstInitMember : InstanceInit
596 MemberInitList members;
599 public class InstInitFunction : InstanceInit
601 ASTClassFunction function;
604 public class ASTInstantiation : ASTNode
609 List<InstanceInit> members;
614 Location nameLoc, insideLoc;