Bug 623379: runtests: Check for java binary before asc invokes (r=fklockii)
[tamarin-stm.git] / eval / eval-parse-expr.cpp
blob7837882303c279cb9a96b31050a83e4864193f72
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
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/
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.
16 * The Original Code is [Open Source Virtual Machine.].
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.
23 * Contributor(s):
24 * Adobe AS3 Team
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.
38 * ***** END LICENSE BLOCK ***** */
40 #include "avmplus.h"
42 #ifdef VMCFG_EVAL
44 #include "eval.h"
46 namespace avmplus
48 namespace RTC
50 NameComponent::~NameComponent() {}
52 QualifiedName* Parser::typeExpression()
54 if (match(T_Multiply))
55 return NULL;
56 QualifiedName* n = nameExpression(false);
57 if ((n->qualifier != 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;
65 QualifiedName* Parser::nameExpression(bool is_attr)
67 uint32_t pos = position();
68 Str* name = NULL;
69 NameComponent* n = NULL;
70 if (match(T_Multiply))
71 n = ALLOC(WildcardName, ());
72 else if (match(T_Public)) {
73 n = ALLOC(BuiltinNamespace, (T_Public));
75 else if (match(T_Protected)) {
76 n = ALLOC(BuiltinNamespace, (T_Protected));
78 else if (match(T_Private)) {
79 n = ALLOC(BuiltinNamespace, (T_Private));
81 else if (match(T_Internal)) {
82 n = ALLOC(BuiltinNamespace, (T_Internal));
84 else {
85 name = identifier();
86 n = ALLOC(SimpleName, (name));
88 if (match(T_DoubleColon)) {
89 if (match(T_Multiply))
90 return ALLOC(QualifiedName, (n, ALLOC(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));
96 return ALLOC(QualifiedName, (n, ALLOC(SimpleName, (identifier())), is_attr, pos));
98 else {
99 if (name == compiler->SYM_arguments)
100 setUsesArguments();
101 return ALLOC(QualifiedName, (NULL, n, is_attr, pos));
105 Expr* Parser::exprListToCommaExpr(Seq<Expr*>* es) {
106 Expr* expr = es->hd;
107 for ( es=es->tl ; es != NULL ; es = es->tl )
108 expr = ALLOC(BinaryExpr, (OPR_comma, expr, es->hd));
109 return expr;
112 Expr* Parser::objectInitializer ()
114 uint32_t pos = position();
115 eat (T_LeftBrace);
116 Seq<LiteralField*>* fields = fieldList();
117 eat (T_RightBrace);
119 return ALLOC(LiteralObject, (fields, pos));
122 Seq<LiteralField*>* Parser::fieldList ()
124 SeqBuilder<LiteralField*> fields(allocator);
125 if (hd () != T_RightBrace) {
126 do {
127 fields.addAtEnd(literalField());
128 } while (match(T_Comma));
130 return fields.get();
133 LiteralField* Parser::literalField()
135 Str* name = NULL;
136 switch (hd ()) {
137 case T_StringLiteral:
138 name = stringValue();
139 break;
141 case T_IntLiteral:
142 name = doubleToStr(intValue());
143 break;
145 case T_UIntLiteral:
146 name = doubleToStr(uintValue());
147 break;
149 case T_DoubleLiteral:
150 name = doubleToStr(doubleValue());
151 break;
153 case T_Identifier:
154 name = identValue();
155 break;
157 default:
158 compiler->syntaxError(position(), SYNTAXERR_ILLEGAL_FIELDNAME);
159 break;
161 next();
162 match(T_Colon);
163 Expr* expr = assignmentExpression(0);
164 return ALLOC(LiteralField, (name, expr));
167 Expr* Parser::arrayInitializer ()
169 uint32_t pos = position();
170 eat (T_LeftBracket);
171 Seq<Expr*>* elts = elementList();
172 eat (T_RightBracket);
173 return ALLOC(LiteralArray, (elts, pos));
176 Seq<Expr*>* Parser::elementList()
178 SeqBuilder<Expr*> elts(allocator);
179 Expr* elt = NULL;
181 for (;;) {
182 switch (hd()) {
183 case T_RightBracket:
184 goto end_loop;
186 case T_Comma: {
187 eat(T_Comma);
188 if (elt == NULL)
189 elt = NULL;
190 elts.addAtEnd(elt);
191 elt = NULL;
192 break;
195 default:
196 if (elt != NULL)
197 eat(T_Comma);
198 elt = assignmentExpression(0);
199 break;
202 end_loop:
203 if (elt != NULL)
204 elts.addAtEnd(elt);
206 return elts.get();
209 Expr* Parser::functionExpression()
211 Qualifier qual;
212 return ALLOC(LiteralFunction, (functionGuts(&qual, false, false, true)));
215 Expr* Parser::primaryExpression()
217 if (hd() == T_BreakSlash)
218 regexp();
220 uint32_t pos = position(); // Record the source location before consuming the token
221 switch (hd ()) {
222 case T_Null:
223 next();
224 return ALLOC(LiteralNull, (pos));
226 case T_True:
227 case T_False: {
228 bool flag = hd() == T_True;
229 next();
230 return ALLOC(LiteralBoolean, (flag, pos));
233 case T_IntLiteral: {
234 int32_t i = intValue();
235 next();
236 return ALLOC(LiteralInt, (i, pos));
239 case T_UIntLiteral: {
240 uint32_t u = uintValue();
241 next();
242 return ALLOC(LiteralUInt, (u, pos));
245 case T_DoubleLiteral: {
246 double d = doubleValue();
247 next();
248 return ALLOC(LiteralDouble, (d, pos));
251 case T_StringLiteral: {
252 Str* s = stringValue();
253 next();
254 return ALLOC(LiteralString, (s, pos));
257 case T_RegexpLiteral: {
258 Str* r = regexValue();
259 next();
260 return ALLOC(LiteralRegExp, (r, pos));
263 case T_This:
264 next();
265 return ALLOC(ThisExpr, ());
267 case T_Super:
268 return superExpression();
270 case T_LeftParen:
271 return parenExpression();
273 case T_LeftBracket:
274 return arrayInitializer ();
276 case T_LeftBrace:
277 return objectInitializer ();
279 case T_Function:
280 return functionExpression ();
282 case T_LessThan:
283 case T_BreakXml:
284 return xmlInitializer();
286 case T_AtSign:
287 return attributeIdentifier();
289 default:
290 break;
293 return nameExpression();
296 QualifiedName* Parser::attributeIdentifier()
298 eat(T_AtSign);
299 if (hd() == T_LeftBracket) {
300 eat(T_LeftBracket);
301 Expr* e = commaExpression(0);
302 eat(T_RightBracket);
303 return ALLOC(QualifiedName, (NULL, ALLOC(ComputedName, (e)), true, 0));
305 else
306 return nameExpression(true);
309 QualifiedName* Parser::propertyIdentifier()
311 switch (hd()) {
312 case T_Multiply:
313 case T_AtSign:
314 case T_Identifier:
315 return (QualifiedName*)primaryExpression();
316 default:
317 compiler->syntaxError(position(), SYNTAXERR_ILLEGAL_PROPNAME);
318 /*NOTREACHED*/
319 return NULL;
323 Expr* Parser::propertyOperator(Expr* obj)
325 uint32_t pos = position();
326 switch (hd ()) {
327 case T_Dot: {
328 eat(T_Dot);
329 if (hd() == T_LeftParen)
330 return ALLOC(FilterExpr, (obj, parenExpression(), pos));
331 if (hd() == T_AtSign)
332 return ALLOC(ObjectRef, (obj, attributeIdentifier(), pos));
333 return ALLOC(ObjectRef, (obj, nameExpression(), pos));
335 case T_DoubleDot: {
336 eat(T_DoubleDot);
337 return ALLOC(DescendantsExpr, (obj, propertyIdentifier(), pos));
339 case T_LeftBracket: {
340 eat(T_LeftBracket);
341 Expr* expr = commaExpression(0);
342 eat (T_RightBracket);
343 return ALLOC(ObjectRef, (obj, ALLOC(QualifiedName, (NULL, ALLOC(ComputedName, (expr)), false, pos)), pos));
345 case T_LeftDotAngle:
346 compiler->internalError(position(), "Unimplemented: Cannot parse vector syntax");
347 default:
348 compiler->internalError(position(), "Unexpected token in propertyOperator: %d", (int)hd());
349 /*NOTREACHED*/
350 return NULL;
354 Seq<Expr*>* Parser::argumentList ()
356 SeqBuilder<Expr*> exprs(allocator);
358 eat(T_LeftParen);
359 if (hd() != T_RightParen) {
360 do {
361 exprs.addAtEnd(assignmentExpression(0));
362 } while (match(T_Comma));
364 eat(T_RightParen);
365 return exprs.get();
368 Expr* Parser::memberExpression ()
370 switch (hd ()) {
371 case T_New: {
372 next();
373 if (hd() == T_LessThan) {
374 // vector initializer
375 compiler->internalError(position(), "Unimplemented: Cannot parse vector initializer");
377 Expr* object_expr = memberExpression ();
378 Seq<Expr*>* argument_exprs = argumentList();
379 return memberExpressionPrime (ALLOC(NewExpr, (object_expr, argument_exprs)));
382 default: {
383 Expr* expr = primaryExpression ();
384 return memberExpressionPrime (expr);
389 Expr* Parser::memberExpressionPrime (Expr* expr)
391 switch (hd ()) {
392 case T_LeftBracket:
393 case T_Dot:
394 case T_DoubleDot:
395 case T_LeftDotAngle:
396 return memberExpressionPrime (propertyOperator (expr));
397 default:
398 return expr;
402 Expr* Parser::superExpression ()
404 eat (T_Super);
405 uint32_t pos = position();
406 Seq<Expr*>* arguments = NULL;
407 bool argsPresent = false;
408 if (hd() == T_LeftParen) {
409 argsPresent = true;
410 arguments = argumentList();
412 if (argsPresent && (arguments == NULL || arguments->tl != NULL))
413 compiler->syntaxError(pos, SYNTAXERR_ONE_ARGUMENT_REQUIRED);
414 if (hd() != T_Dot && hd() != T_LeftBracket)
415 compiler->syntaxError(pos, SYNTAXERR_PROPERTY_OPERATOR_REQUIRED);
416 Expr* obj = argsPresent ? arguments->hd : ALLOC(ThisExpr, ());
417 return propertyOperator(ALLOC(SuperExpr, (obj)));
420 Expr* Parser::callExpression ()
422 uint32_t pos = position();
423 Expr* object_expr = memberExpression ();
424 Seq<Expr*>* argument_exprs = argumentList();
426 return callExpressionPrime (ALLOC(CallExpr, (object_expr, argument_exprs, pos)));
429 // shared among many
430 Expr* Parser::callExpressionPrime (Expr* call_expr)
432 switch (hd ()) {
433 case T_LeftParen:
435 uint32_t pos = position();
436 Seq<Expr*>* argument_exprs = argumentList();
437 return callExpressionPrime (ALLOC(CallExpr, (call_expr, argument_exprs, pos)));
439 case T_LeftBracket:
440 case T_Dot:
441 case T_LeftDotAngle:
442 return callExpressionPrime (propertyOperator (call_expr));
443 default:
444 return call_expr;
448 Expr* Parser::newExpression (int new_count)
450 Expr* call_expression;
452 bool is_new = match(T_New);
453 if (is_new) {
454 if (hd() == T_LessThan) {
455 // vector initializer
456 compiler->internalError(position(), "Unimplemented: Cannot parse vector initializer");
458 call_expression = newExpression (new_count+1);
460 else
461 call_expression = memberExpression();
463 if (hd() == T_LeftParen) { // No more new exprs so this paren must start a call expr
464 uint32_t pos = position();
465 Seq<Expr*>* argument_exprs = argumentList();
466 if (new_count > 0)
467 return ALLOC(NewExpr, (call_expression, argument_exprs));
468 return callExpressionPrime (ALLOC(CallExpr, (call_expression, argument_exprs, pos)));
471 if (new_count > 0)
472 return ALLOC(NewExpr, (call_expression, NULL));
474 if (is_new)
475 return memberExpressionPrime (call_expression);
477 return call_expression;
480 Expr* Parser::leftHandSideExpression ()
482 Expr* oper = (hd() == T_New) ? newExpression (0) : memberExpression ();
483 if (hd () == T_LeftParen) {
484 uint32_t pos = position();
485 Seq<Expr*>* args = argumentList();
486 return callExpressionPrime(ALLOC(CallExpr, (oper, args, pos)));
488 return oper;
491 Expr* Parser::postfixExpression ()
493 Expr* expr = leftHandSideExpression ();
494 if (noNewline()) {
495 if (match(T_PlusPlus))
496 return ALLOC(UnaryExpr, (OPR_postIncr, expr));
497 if (match(T_MinusMinus))
498 return ALLOC(UnaryExpr, (OPR_postDecr, expr));
500 return expr;
503 Expr* Parser::unaryExpression()
505 Token t;
507 switch (t = hd ()) {
508 case T_Delete:
509 next();
510 return ALLOC(UnaryExpr, (OPR_delete, postfixExpression()));
512 case T_PlusPlus:
513 case T_MinusMinus:
514 next();
515 return ALLOC(UnaryExpr, (tokenToUnaryOperator(t), postfixExpression()));
517 case T_Void:
518 case T_TypeOf:
519 case T_Plus:
520 case T_Minus:
521 case T_BitwiseNot:
522 case T_Not:
523 next();
524 return ALLOC(UnaryExpr, (tokenToUnaryOperator(t), unaryExpression()));
526 default:
527 return postfixExpression();
531 Expr* Parser::multiplicativeExpression()
533 Expr* expr = unaryExpression();
534 Token t;
536 while (isMultiplicative(t = hd()) || t == T_BreakSlash) {
537 if (t == T_BreakSlash) {
538 divideOperator();
539 if (!isMultiplicative(t = hd()))
540 break;
542 next();
543 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, unaryExpression()));
545 return expr;
548 Expr* Parser::additiveExpression()
550 Expr* expr = multiplicativeExpression();
551 Token t;
553 while (isAdditive(t = hd())) {
554 next();
555 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, multiplicativeExpression()));
557 return expr;
560 Expr* Parser::shiftExpression()
562 Expr* expr = additiveExpression();
563 Token t;
565 while (isShift(t = hd()) || t == T_BreakRightAngle) {
566 if (t == T_BreakRightAngle) {
567 rightShiftOrRelationalOperator();
568 if (!isShift(t = hd()))
569 break;
571 next();
572 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, additiveExpression()));
575 return expr;
578 Expr* Parser::relationalExpression(int flags)
580 Expr* expr = shiftExpression();
581 Token t;
582 bool allowIn = !(flags & EFLAG_NoIn);
584 for (;;) {
585 if (hd() == T_Identifier && identValue() == compiler->SYM_to && !compiler->es3_keywords)
586 T0 = T_To;
587 if (!(isRelational(t = hd(), allowIn) || t == T_BreakRightAngle))
588 break;
589 if (t == T_BreakRightAngle) {
590 rightShiftOrRelationalOperator();
591 if (!isRelational(t = hd(), allowIn))
592 break;
594 next();
595 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, shiftExpression()));
598 return expr;
601 Expr* Parser::equalityExpression(int flags)
603 Expr* expr = relationalExpression(flags);
604 Token t;
606 while (isEquality(t = hd())) {
607 next();
608 expr = ALLOC(BinaryExpr, (tokenToBinaryOperator(t), expr, relationalExpression(flags)));
610 return expr;
613 Expr* Parser::bitwiseAndExpression(int flags)
615 Expr* expr = equalityExpression(flags);
616 while (match(T_BitwiseAnd))
617 expr = ALLOC(BinaryExpr, (OPR_bitwiseAnd, expr, equalityExpression(flags)));
618 return expr;
621 Expr* Parser::bitwiseXorExpression(int flags)
623 Expr* expr = bitwiseAndExpression(flags);
624 while (match(T_BitwiseXor))
625 expr = ALLOC(BinaryExpr, (OPR_bitwiseXor, expr, bitwiseAndExpression(flags)));
626 return expr;
629 Expr* Parser::bitwiseOrExpression(int flags)
631 Expr* expr = bitwiseXorExpression(flags);
632 while (match(T_BitwiseOr))
633 expr = ALLOC(BinaryExpr, (OPR_bitwiseOr, expr, bitwiseXorExpression(flags)));
634 return expr;
637 Expr* Parser::logicalAndExpression(int flags)
639 Expr* expr = bitwiseOrExpression(flags);
640 while (match(T_LogicalAnd))
641 expr = ALLOC(BinaryExpr, (OPR_logicalAnd, expr, bitwiseOrExpression(flags)));
642 return expr;
645 Expr* Parser::logicalOrExpression(int flags)
647 Expr* expr = logicalAndExpression(flags);
648 while (match(T_LogicalOr))
649 expr = ALLOC(BinaryExpr, (OPR_logicalOr, expr, logicalAndExpression(flags)));
650 return expr;
653 Expr* Parser::nonAssignmentExpression(int flags)
655 Expr* expr = logicalOrExpression(flags);
656 if (!match(T_Question))
657 return expr;
659 Expr* consequent = nonAssignmentExpression(flags);
660 eat (T_Colon);
661 Expr* alternate = nonAssignmentExpression(flags);
662 return ALLOC(ConditionalExpr, (expr, consequent, alternate));
665 Expr* Parser::conditionalExpression(int flags)
667 Expr* expr = logicalOrExpression(flags);
668 if (!match(T_Question))
669 return expr;
671 Expr* consequent = assignmentExpression(flags);
672 eat (T_Colon);
673 Expr* alternate = assignmentExpression(flags);
674 return ALLOC(ConditionalExpr, (expr, consequent, alternate));
677 Expr* Parser::assignmentExpression(int flags)
679 Expr* lhs = conditionalExpression(flags);
680 Token t;
682 if (!((t = hd()) == T_Assign || isOpAssign(t) || t == T_BreakRightAngle))
683 return lhs;
685 if (t == T_BreakRightAngle) {
686 rightShiftOrRelationalOperator();
687 if (!isOpAssign(t = hd()))
688 return lhs;
691 eat(t);
692 Expr* rhs = assignmentExpression (flags);
693 return ALLOC(AssignExpr, (tokenToBinaryOperator(t), lhs, rhs));
696 Expr* Parser::commaExpression(int flags)
698 Expr* expr = assignmentExpression(flags);
699 while (match(T_Comma))
700 expr = ALLOC(BinaryExpr, (OPR_comma, expr, assignmentExpression(flags)));
701 return expr;
704 Expr* Parser::parenExpression()
706 eat (T_LeftParen);
707 Expr* expr = commaExpression(0);
708 eat (T_RightParen);
710 return expr;
715 #endif // VMCFG_EVAL