Bug Summary

File:platform/mac/avmshell/../../../eval/eval-parse-expr.cpp
Location:line 449, column 39
Description:Access to field 'hd' results in a dereference of a null pointer (loaded from variable 'arguments')

Annotated Source Code

1/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3/* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is [Open Source Virtual Machine.].
17 *
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
22 *
23 * Contributor(s):
24 * Adobe AS3 Team
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40#include "avmplus.h"
41
42#ifdef VMCFG_EVAL
43
44#include "eval.h"
45
46namespace avmplus
47{
48 namespace RTC
49 {
50 NameComponent::~NameComponent() {}
51
52 QualifiedName* Parser::typeExpression()
53 {
54 if (match(T_Multiply))
55 return NULL__null;
56 QualifiedName* n = nameExpression(falsefalse);
57 if ((n->qualifier != NULL__null && n->qualifier->tag() != TAG_simpleName) ||
58 n->name->tag() != TAG_simpleName)
59 compiler->syntaxError(n->pos, SYNTAXERR_ILLEGAL_TYPENAME);
60 if (hd() == T_LeftDotAngle)
61 compiler->internalError(position(), "Unimplemented: Cannot parse vector types");
62 return n;
63 }
64
65 QualifiedName* Parser::nameExpression(boolbool is_attr)
66 {
67 uint32_t pos = position();
68 Str* name = NULL__null;
69 NameComponent* n = NULL__null;
70 if (match(T_Multiply))
71 n = ALLOC(WildcardName, ())::new (allocator->alloc(sizeof(WildcardName))) WildcardName
()
;
72 else if (match(T_Public)) {
73 n = ALLOC(BuiltinNamespace, (T_Public))::new (allocator->alloc(sizeof(BuiltinNamespace))) BuiltinNamespace
(T_Public)
;
74 }
75 else if (match(T_Protected)) {
76 n = ALLOC(BuiltinNamespace, (T_Protected))::new (allocator->alloc(sizeof(BuiltinNamespace))) BuiltinNamespace
(T_Protected)
;
77 }
78 else if (match(T_Private)) {
79 n = ALLOC(BuiltinNamespace, (T_Private))::new (allocator->alloc(sizeof(BuiltinNamespace))) BuiltinNamespace
(T_Private)
;
80 }
81 else if (match(T_Internal)) {
82 n = ALLOC(BuiltinNamespace, (T_Internal))::new (allocator->alloc(sizeof(BuiltinNamespace))) BuiltinNamespace
(T_Internal)
;
83 }
84 else {
85 name = identifier();
86 n = ALLOC(SimpleName, (name))::new (allocator->alloc(sizeof(SimpleName))) SimpleName (name
)
;
87 }
88 if (match(T_DoubleColon)) {
89 if (match(T_Multiply))
90 return ALLOC(QualifiedName, (n, ALLOC(WildcardName, ()), is_attr, pos))::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(n, ::new (allocator->alloc(sizeof(WildcardName))) WildcardName
(), is_attr, pos)
;
91 if (match(T_LeftBracket)) {
92 Expr* e = commaExpression(0);
93 eat(T_RightBracket);
94 return ALLOC(QualifiedName, (n, ALLOC(ComputedName, (e)), is_attr, pos))::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(n, ::new (allocator->alloc(sizeof(ComputedName))) ComputedName
(e), is_attr, pos)
;
95 }
96 return ALLOC(QualifiedName, (n, ALLOC(SimpleName, (identifier())), is_attr, pos))::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(n, ::new (allocator->alloc(sizeof(SimpleName))) SimpleName
(identifier()), is_attr, pos)
;
97 }
98 else {
99 if (name == compiler->SYM_arguments)
100 setUsesArguments();
101 return ALLOC(QualifiedName, (NULL, n, is_attr, pos))::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(__null, n, is_attr, pos)
;
102 }
103 }
104
105 Expr* Parser::exprListToCommaExpr(Seq<Expr*>* es) {
106 Expr* expr = es->hd;
107 for ( es=es->tl ; es != NULL__null ; es = es->tl )
108 expr = ALLOC(BinaryExpr, (OPR_comma, expr, es->hd))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_comma
, expr, es->hd)
;
109 return expr;
110 }
111
112 Expr* Parser::objectInitializer ()
113 {
114 uint32_t pos = position();
115 eat (T_LeftBrace);
116 Seq<LiteralField*>* fields = fieldList();
117 eat (T_RightBrace);
118
119 return ALLOC(LiteralObject, (fields, pos))::new (allocator->alloc(sizeof(LiteralObject))) LiteralObject
(fields, pos)
;
120 }
121
122 Seq<LiteralField*>* Parser::fieldList ()
123 {
124 SeqBuilder<LiteralField*> fields(allocator);
125 if (hd () != T_RightBrace) {
126 do {
127 LiteralField* f = literalField();
128 if (f != NULL__null)
129 fields.addAtEnd(f);
130 } while (match(T_Comma));
131 }
132 return fields.get();
133 }
134
135 LiteralField* Parser::literalField()
136 {
137 Str* name = NULL__null;
138 QualifiedName* config = NULL__null;
139 again:
140 switch (hd ()) {
141 case T_StringLiteral:
142 name = stringValue();
143 break;
144
145 case T_IntLiteral:
146 name = doubleToStr(intValue());
147 break;
148
149 case T_UIntLiteral:
150 name = doubleToStr(uintValue());
151 break;
152
153 case T_DoubleLiteral:
154 name = doubleToStr(doubleValue());
155 break;
156
157 case T_Identifier: {
158 if (hd2() != T_DoubleColon) {
159 name = identValue();
160 break;
161 }
162 // This must be a program configuration expression
163 if (config != NULL__null)
164 compiler->syntaxError(position(), SYNTAXERR_DUPLICATE_CONFIG);
165 Expr* e = assignmentExpression(0);
166 if (!isConfigReference(e))
167 compiler->syntaxError(position(), SYNTAXERR_CONFIG_REQUIRED);
168 config = (QualifiedName*)e;
169 goto again;
170 }
171
172 default:
173 compiler->syntaxError(position(), SYNTAXERR_ILLEGAL_FIELDNAME);
174 break;
175 }
176 next();
177 match(T_Colon);
178 Expr* expr = assignmentExpression(0);
179 if (config == NULL__null || evaluateConfigReference(config))
180 return ALLOC(LiteralField, (name, expr))::new (allocator->alloc(sizeof(LiteralField))) LiteralField
(name, expr)
;
181 return NULL__null;
182 }
183
184 Expr* Parser::arrayInitializer ()
185 {
186 uint32_t pos = position();
187 eat (T_LeftBracket);
188 Seq<Expr*>* elts = elementList();
189 eat (T_RightBracket);
190 return ALLOC(LiteralArray, (elts, pos))::new (allocator->alloc(sizeof(LiteralArray))) LiteralArray
(elts, pos)
;
191 }
192
193 Seq<Expr*>* Parser::elementList()
194 {
195 SeqBuilder<Expr*> elts(allocator);
196 Expr* elt = NULL__null;
197
198 for (;;) {
199 switch (hd()) {
200 case T_RightBracket:
201 goto end_loop;
202
203 case T_Comma: {
204 eat(T_Comma);
205 if (elt == NULL__null)
206 elt = NULL__null;
207 elts.addAtEnd(elt);
208 elt = NULL__null;
209 break;
210 }
211
212 default:
213 if (elt != NULL__null)
214 eat(T_Comma);
215 elt = assignmentExpression(0);
216 if (hd() != T_RightBracket && hd() != T_Comma) {
217 // This must be a program configuration expression
218 if (!isConfigReference(elt))
219 compiler->syntaxError(position(), SYNTAXERR_CONFIG_REQUIRED);
220 boolbool result = evaluateConfigReference((QualifiedName*)elt);
221 elt = assignmentExpression(0);
222 if (!result)
223 elt = NULL__null;
224 }
225 break;
226 }
227 }
228 end_loop:
229 if (elt != NULL__null)
230 elts.addAtEnd(elt);
231
232 return elts.get();
233 }
234
235 Expr* Parser::functionExpression()
236 {
237 Qualifier qual;
238 return ALLOC(LiteralFunction, (functionGuts(&qual, false, false, true)))::new (allocator->alloc(sizeof(LiteralFunction))) LiteralFunction
(functionGuts(&qual, false, false, true))
;
239 }
240
241 Expr* Parser::primaryExpression()
242 {
243 if (hd() == T_BreakSlash)
244 regexp();
245
246 uint32_t pos = position(); // Record the source location before consuming the token
247 switch (hd ()) {
248 case T_Null:
249 next();
250 return ALLOC(LiteralNull, (pos))::new (allocator->alloc(sizeof(LiteralNull))) LiteralNull (
pos)
;
251
252 case T_True:
253 case T_False: {
254 boolbool flag = hd() == T_True;
255 next();
256 return ALLOC(LiteralBoolean, (flag, pos))::new (allocator->alloc(sizeof(LiteralBoolean))) LiteralBoolean
(flag, pos)
;
257 }
258
259 case T_IntLiteral: {
260 int32_t i = intValue();
261 next();
262 return ALLOC(LiteralInt, (i, pos))::new (allocator->alloc(sizeof(LiteralInt))) LiteralInt (i
, pos)
;
263 }
264
265 case T_UIntLiteral: {
266 uint32_t u = uintValue();
267 next();
268 return ALLOC(LiteralUInt, (u, pos))::new (allocator->alloc(sizeof(LiteralUInt))) LiteralUInt (
u, pos)
;
269 }
270
271 case T_DoubleLiteral: {
272 double d = doubleValue();
273 next();
274 return ALLOC(LiteralDouble, (d, pos))::new (allocator->alloc(sizeof(LiteralDouble))) LiteralDouble
(d, pos)
;
275 }
276
277 case T_StringLiteral: {
278 Str* s = stringValue();
279 next();
280 return ALLOC(LiteralString, (s, pos))::new (allocator->alloc(sizeof(LiteralString))) LiteralString
(s, pos)
;
281 }
282
283 case T_RegexpLiteral: {
284 Str* r = regexValue();
285 next();
286 return ALLOC(LiteralRegExp, (r, pos))::new (allocator->alloc(sizeof(LiteralRegExp))) LiteralRegExp
(r, pos)
;
287 }
288
289 case T_This:
290 next();
291 return ALLOC(ThisExpr, ())::new (allocator->alloc(sizeof(ThisExpr))) ThisExpr ();
292
293 case T_Super:
294 return superExpression();
295
296 case T_LeftParen:
297 return parenExpression();
298
299 case T_LeftBracket:
300 return arrayInitializer ();
301
302 case T_LeftBrace:
303 return objectInitializer ();
304
305 case T_Function:
306 return functionExpression ();
307
308 case T_BreakLeftAngle:
309 return xmlInitializer();
310
311 case T_AtSign:
312 return attributeIdentifier();
313
314 default:
315 break;
316 }
317
318 return nameExpression();
319 }
320
321 QualifiedName* Parser::attributeIdentifier()
322 {
323 eat(T_AtSign);
324 if (hd() == T_LeftBracket) {
325 eat(T_LeftBracket);
326 Expr* e = commaExpression(0);
327 eat(T_RightBracket);
328 return ALLOC(QualifiedName, (NULL, ALLOC(ComputedName, (e)), true, 0))::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(__null, ::new (allocator->alloc(sizeof(ComputedName))) ComputedName
(e), true, 0)
;
329 }
330 else
331 return nameExpression(truetrue);
332 }
333
334 QualifiedName* Parser::propertyIdentifier()
335 {
336 switch (hd()) {
337 case T_Multiply:
338 case T_AtSign:
339 case T_Identifier:
340 return (QualifiedName*)primaryExpression();
341 default:
342 compiler->syntaxError(position(), SYNTAXERR_ILLEGAL_PROPNAME);
343 /*NOTREACHED*/
344 return NULL__null;
345 }
346 }
347
348 Expr* Parser::propertyOperator(Expr* obj)
349 {
350 uint32_t pos = position();
351 switch (hd ()) {
352 case T_Dot: {
353 eat(T_Dot);
354 if (hd() == T_LeftParen)
355 return ALLOC(FilterExpr, (obj, parenExpression(), pos))::new (allocator->alloc(sizeof(FilterExpr))) FilterExpr (obj
, parenExpression(), pos)
;
356 if (hd() == T_AtSign)
357 return ALLOC(ObjectRef, (obj, attributeIdentifier(), pos))::new (allocator->alloc(sizeof(ObjectRef))) ObjectRef (obj
, attributeIdentifier(), pos)
;
358 // Begin keyword hacks
359 // FIXME
360 // Allow 'namespace' to be used as a property name
361 if (hd() == T_Namespace) {
362 eat(T_Namespace);
363 return ALLOC(ObjectRef, (obj, ALLOC(QualifiedName, (NULL, ALLOC(SimpleName, (compiler->SYM_namespace)), false, pos)), pos))::new (allocator->alloc(sizeof(ObjectRef))) ObjectRef (obj
, ::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(__null, ::new (allocator->alloc(sizeof(SimpleName))) SimpleName
(compiler->SYM_namespace), false, pos), pos)
;
364 }
365 // End keyword hacks
366 return ALLOC(ObjectRef, (obj, nameExpression(), pos))::new (allocator->alloc(sizeof(ObjectRef))) ObjectRef (obj
, nameExpression(), pos)
;
367 }
368 case T_DoubleDot: {
369 eat(T_DoubleDot);
370 return ALLOC(DescendantsExpr, (obj, propertyIdentifier(), pos))::new (allocator->alloc(sizeof(DescendantsExpr))) DescendantsExpr
(obj, propertyIdentifier(), pos)
;
371 };
372 case T_LeftBracket: {
373 eat(T_LeftBracket);
374 Expr* expr = commaExpression(0);
375 eat (T_RightBracket);
376 return ALLOC(ObjectRef, (obj, ALLOC(QualifiedName, (NULL, ALLOC(ComputedName, (expr)), false, pos)), pos))::new (allocator->alloc(sizeof(ObjectRef))) ObjectRef (obj
, ::new (allocator->alloc(sizeof(QualifiedName))) QualifiedName
(__null, ::new (allocator->alloc(sizeof(ComputedName))) ComputedName
(expr), false, pos), pos)
;
377 }
378 case T_LeftDotAngle:
379 compiler->internalError(position(), "Unimplemented: Cannot parse vector syntax");
380 default:
381 compiler->internalError(position(), "Unexpected token in propertyOperator: %d", (int)hd());
382 /*NOTREACHED*/
383 return NULL__null;
384 }
385 }
386
387 Seq<Expr*>* Parser::argumentList ()
388 {
389 SeqBuilder<Expr*> exprs(allocator);
390
391 eat(T_LeftParen);
392 if (hd() != T_RightParen) {
393 do {
394 exprs.addAtEnd(assignmentExpression(0));
395 } while (match(T_Comma));
396 }
397 eat(T_RightParen);
398 return exprs.get();
399 }
400
401 Expr* Parser::memberExpression ()
402 {
403 switch (hd ()) {
404 case T_New: {
405 next();
406 if (hd() == T_BreakLeftAngle) {
407 // vector initializer
408 compiler->internalError(position(), "Unimplemented: Cannot parse vector initializer");
409 }
410 Expr* object_expr = memberExpression ();
411 Seq<Expr*>* argument_exprs = argumentList();
412 return memberExpressionPrime (ALLOC(NewExpr, (object_expr, argument_exprs))::new (allocator->alloc(sizeof(NewExpr))) NewExpr (object_expr
, argument_exprs)
);
413 }
414
415 default: {
416 Expr* expr = primaryExpression ();
417 return memberExpressionPrime (expr);
418 }
419 }
420 }
421
422 Expr* Parser::memberExpressionPrime (Expr* expr)
423 {
424 switch (hd ()) {
425 case T_LeftBracket:
426 case T_Dot:
427 case T_DoubleDot:
428 case T_LeftDotAngle:
429 return memberExpressionPrime (propertyOperator (expr));
430 default:
431 return expr;
432 }
433 }
434
435 Expr* Parser::superExpression ()
436 {
437 eat (T_Super);
438 uint32_t pos = position();
439 Seq<Expr*>* arguments = NULL__null;
440 boolbool argsPresent = falsefalse;
441 if (hd() == T_LeftParen) {
1
Taking true branch
442 argsPresent = truetrue;
443 arguments = argumentList();
444 }
445 if (argsPresent && (arguments == NULL__null || arguments->tl != NULL__null))
2
Taking true branch
446 compiler->syntaxError(pos, SYNTAXERR_ONE_ARGUMENT_REQUIRED);
447 if (hd() != T_Dot && hd() != T_LeftBracket)
3
Taking false branch
448 compiler->syntaxError(pos, SYNTAXERR_PROPERTY_OPERATOR_REQUIRED);
449 Expr* obj = argsPresent ? arguments->hd : ALLOC(ThisExpr, ())::new (allocator->alloc(sizeof(ThisExpr))) ThisExpr ();
4
'?' condition is true
5
Access to field 'hd' results in a dereference of a null pointer (loaded from variable 'arguments')
450 return propertyOperator(ALLOC(SuperExpr, (obj))::new (allocator->alloc(sizeof(SuperExpr))) SuperExpr (obj
)
);
451 }
452
453 Expr* Parser::callExpression ()
454 {
455 uint32_t pos = position();
456 Expr* object_expr = memberExpression ();
457 Seq<Expr*>* argument_exprs = argumentList();
458
459 return callExpressionPrime (ALLOC(CallExpr, (object_expr, argument_exprs, pos))::new (allocator->alloc(sizeof(CallExpr))) CallExpr (object_expr
, argument_exprs, pos)
);
460 }
461
462 // shared among many
463 Expr* Parser::callExpressionPrime (Expr* call_expr)
464 {
465 switch (hd ()) {
466 case T_LeftParen:
467 {
468 uint32_t pos = position();
469 Seq<Expr*>* argument_exprs = argumentList();
470 return callExpressionPrime (ALLOC(CallExpr, (call_expr, argument_exprs, pos))::new (allocator->alloc(sizeof(CallExpr))) CallExpr (call_expr
, argument_exprs, pos)
);
471 }
472 case T_LeftBracket:
473 case T_Dot:
474 case T_LeftDotAngle:
475 return callExpressionPrime (propertyOperator (call_expr));
476 default:
477 return call_expr;
478 }
479 }
480
481 Expr* Parser::newExpression (int new_count)
482 {
483 Expr* call_expression;
484
485 boolbool is_new = match(T_New);
486 if (is_new) {
487 if (hd() == T_LessThan) {
488 // vector initializer
489 compiler->internalError(position(), "Unimplemented: Cannot parse vector initializer");
490 }
491 call_expression = newExpression (new_count+1);
492 }
493 else
494 call_expression = memberExpression();
495
496 if (hd() == T_LeftParen) { // No more new exprs so this paren must start a call expr
497 uint32_t pos = position();
498 Seq<Expr*>* argument_exprs = argumentList();
499 if (new_count > 0)
500 return ALLOC(NewExpr, (call_expression, argument_exprs))::new (allocator->alloc(sizeof(NewExpr))) NewExpr (call_expression
, argument_exprs)
;
501 return callExpressionPrime (ALLOC(CallExpr, (call_expression, argument_exprs, pos))::new (allocator->alloc(sizeof(CallExpr))) CallExpr (call_expression
, argument_exprs, pos)
);
502 }
503
504 if (new_count > 0)
505 return ALLOC(NewExpr, (call_expression, NULL))::new (allocator->alloc(sizeof(NewExpr))) NewExpr (call_expression
, __null)
;
506
507 if (is_new)
508 return memberExpressionPrime (call_expression);
509
510 return call_expression;
511 }
512
513 Expr* Parser::leftHandSideExpression ()
514 {
515 Expr* oper = (hd() == T_New) ? newExpression (0) : memberExpression ();
516 if (hd () == T_LeftParen) {
517 uint32_t pos = position();
518 Seq<Expr*>* args = argumentList();
519 return callExpressionPrime(ALLOC(CallExpr, (oper, args, pos))::new (allocator->alloc(sizeof(CallExpr))) CallExpr (oper,
args, pos)
);
520 }
521 return oper;
522 }
523
524 Expr* Parser::postfixExpression ()
525 {
526 Expr* expr = leftHandSideExpression ();
527 if (noNewline()) {
528 if (match(T_PlusPlus))
529 return ALLOC(UnaryExpr, (OPR_postIncr, expr))::new (allocator->alloc(sizeof(UnaryExpr))) UnaryExpr (OPR_postIncr
, expr)
;
530 if (match(T_MinusMinus))
531 return ALLOC(UnaryExpr, (OPR_postDecr, expr))::new (allocator->alloc(sizeof(UnaryExpr))) UnaryExpr (OPR_postDecr
, expr)
;
532 }
533 return expr;
534 }
535
536 Expr* Parser::unaryExpression()
537 {
538 Token t;
539
540 switch (t = hd ()) {
541 case T_Delete:
542 next();
543 return ALLOC(UnaryExpr, (OPR_delete, postfixExpression()))::new (allocator->alloc(sizeof(UnaryExpr))) UnaryExpr (OPR_delete
, postfixExpression())
;
544
545 case T_PlusPlus:
546 case T_MinusMinus:
547 next();
548 return ALLOC(UnaryExpr, (tokenToUnaryOperator(t), postfixExpression()))::new (allocator->alloc(sizeof(UnaryExpr))) UnaryExpr (tokenToUnaryOperator
(t), postfixExpression())
;
549
550 case T_Void:
551 case T_TypeOf:
552 case T_Plus:
553 case T_Minus:
554 case T_BitwiseNot:
555 case T_Not:
556 next();
557 return ALLOC(UnaryExpr, (tokenToUnaryOperator(t), unaryExpression()))::new (allocator->alloc(sizeof(UnaryExpr))) UnaryExpr (tokenToUnaryOperator
(t), unaryExpression())
;
558
559 default:
560 return postfixExpression();
561 }
562 }
563
564 Expr* Parser::multiplicativeExpression()
565 {
566 Expr* expr = unaryExpression();
567 Token t;
568
569 while (isMultiplicative(t = hd()) || t == T_BreakSlash) {
570 if (t == T_BreakSlash) {
571 divideOperator();
572 if (!isMultiplicative(t = hd()))
573 break;
574 }
575 next();
576 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, unaryExpression()))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (tokenToBinaryOperator
(t), expr, unaryExpression())
;
577 }
578 return expr;
579 }
580
581 Expr* Parser::additiveExpression()
582 {
583 Expr* expr = multiplicativeExpression();
584 Token t;
585
586 while (isAdditive(t = hd())) {
587 next();
588 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, multiplicativeExpression()))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (tokenToBinaryOperator
(t), expr, multiplicativeExpression())
;
589 }
590 return expr;
591 }
592
593 Expr* Parser::shiftExpression()
594 {
595 Expr* expr = additiveExpression();
596 Token t;
597
598 while (isShift(t = hd()) || t == T_BreakLeftAngle || t == T_BreakRightAngle) {
599 if (t == T_BreakLeftAngle) {
600 leftShiftOrRelationalOperator();
601 if (!isShift(t = hd()))
602 break;
603 }
604 else if (t == T_BreakRightAngle) {
605 rightShiftOrRelationalOperator();
606 if (!isShift(t = hd()))
607 break;
608 }
609 next();
610 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, additiveExpression()))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (tokenToBinaryOperator
(t), expr, additiveExpression())
;
611 }
612
613 return expr;
614 }
615
616 Expr* Parser::relationalExpression(int flags)
617 {
618 Expr* expr = shiftExpression();
619 Token t;
620 boolbool allowIn = !(flags & EFLAG_NoIn);
621
622 for (;;) {
623 if (!(isRelational(t = hd(), allowIn) || t == T_BreakLeftAngle || t == T_BreakRightAngle))
624 break;
625 if (t == T_BreakLeftAngle) {
626 leftShiftOrRelationalOperator();
627 if (!isRelational(t = hd(), allowIn))
628 break;
629 }
630 else if (t == T_BreakRightAngle) {
631 rightShiftOrRelationalOperator();
632 if (!isRelational(t = hd(), allowIn))
633 break;
634 }
635 next();
636 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, shiftExpression()))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (tokenToBinaryOperator
(t), expr, shiftExpression())
;
637 }
638
639 return expr;
640 }
641
642 Expr* Parser::equalityExpression(int flags)
643 {
644 Expr* expr = relationalExpression(flags);
645 Token t;
646
647 while (isEquality(t = hd())) {
648 next();
649 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, relationalExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (tokenToBinaryOperator
(t), expr, relationalExpression(flags))
;
650 }
651 return expr;
652 }
653
654 Expr* Parser::bitwiseAndExpression(int flags)
655 {
656 Expr* expr = equalityExpression(flags);
657 while (match(T_BitwiseAnd))
658 expr = ALLOC(BinaryExpr, (OPR_bitwiseAnd, expr, equalityExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_bitwiseAnd
, expr, equalityExpression(flags))
;
659 return expr;
660 }
661
662 Expr* Parser::bitwiseXorExpression(int flags)
663 {
664 Expr* expr = bitwiseAndExpression(flags);
665 while (match(T_BitwiseXor))
666 expr = ALLOC(BinaryExpr, (OPR_bitwiseXor, expr, bitwiseAndExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_bitwiseXor
, expr, bitwiseAndExpression(flags))
;
667 return expr;
668 }
669
670 Expr* Parser::bitwiseOrExpression(int flags)
671 {
672 Expr* expr = bitwiseXorExpression(flags);
673 while (match(T_BitwiseOr))
674 expr = ALLOC(BinaryExpr, (OPR_bitwiseOr, expr, bitwiseXorExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_bitwiseOr
, expr, bitwiseXorExpression(flags))
;
675 return expr;
676 }
677
678 Expr* Parser::logicalAndExpression(int flags)
679 {
680 Expr* expr = bitwiseOrExpression(flags);
681 while (match(T_LogicalAnd))
682 expr = ALLOC(BinaryExpr, (OPR_logicalAnd, expr, bitwiseOrExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_logicalAnd
, expr, bitwiseOrExpression(flags))
;
683 return expr;
684 }
685
686 Expr* Parser::logicalOrExpression(int flags)
687 {
688 Expr* expr = logicalAndExpression(flags);
689 while (match(T_LogicalOr))
690 expr = ALLOC(BinaryExpr, (OPR_logicalOr, expr, logicalAndExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_logicalOr
, expr, logicalAndExpression(flags))
;
691 return expr;
692 }
693
694 Expr* Parser::nonAssignmentExpression(int flags)
695 {
696 Expr* expr = logicalOrExpression(flags);
697 if (!match(T_Question))
698 return expr;
699
700 Expr* consequent = nonAssignmentExpression(flags);
701 eat (T_Colon);
702 Expr* alternate = nonAssignmentExpression(flags);
703 return ALLOC(ConditionalExpr, (expr, consequent, alternate))::new (allocator->alloc(sizeof(ConditionalExpr))) ConditionalExpr
(expr, consequent, alternate)
;
704 }
705
706 Expr* Parser::conditionalExpression(int flags)
707 {
708 Expr* expr = logicalOrExpression(flags);
709 if (!match(T_Question))
710 return expr;
711
712 Expr* consequent = assignmentExpression(flags);
713 eat (T_Colon);
714 Expr* alternate = assignmentExpression(flags);
715 return ALLOC(ConditionalExpr, (expr, consequent, alternate))::new (allocator->alloc(sizeof(ConditionalExpr))) ConditionalExpr
(expr, consequent, alternate)
;
716 }
717
718 Expr* Parser::assignmentExpression(int flags)
719 {
720 Expr* lhs = conditionalExpression(flags);
721 Token t;
722
723 if (!((t = hd()) == T_Assign || isOpAssign(t) || t == T_BreakLeftAngle || t == T_BreakRightAngle))
724 return lhs;
725
726 if (t == T_BreakLeftAngle) {
727 leftShiftOrRelationalOperator();
728 if (!isOpAssign(t = hd()))
729 return lhs;
730 }
731 else if (t == T_BreakRightAngle) {
732 rightShiftOrRelationalOperator();
733 if (!isOpAssign(t = hd()))
734 return lhs;
735 }
736
737 eat(t);
738 Expr* rhs = assignmentExpression (flags);
739 return ALLOC(AssignExpr, (tokenToBinaryOperator(t), lhs, rhs))::new (allocator->alloc(sizeof(AssignExpr))) AssignExpr (tokenToBinaryOperator
(t), lhs, rhs)
;
740 }
741
742 Expr* Parser::commaExpression(int flags)
743 {
744 Expr* expr = assignmentExpression(flags);
745 while (match(T_Comma))
746 expr = ALLOC(BinaryExpr, (OPR_comma, expr, assignmentExpression(flags)))::new (allocator->alloc(sizeof(BinaryExpr))) BinaryExpr (OPR_comma
, expr, assignmentExpression(flags))
;
747 return expr;
748 }
749
750 Expr* Parser::parenExpression()
751 {
752 eat (T_LeftParen);
753 Expr* expr = commaExpression(0);
754 eat (T_RightParen);
755
756 return expr;
757 }
758 }
759}
760
761#endif // VMCFG_EVAL