Stmt* Parser::forStatement() { Expr* init=NULL; Expr* lhs=NULL; uint32_t numbindings = 0; bool is_each = false; eat (T_For); if (hd() == T_Identifier && identValue() == compiler->SYM_each) { is_each = true; eat(T_Identifier); } uint32_t pos = position(); eat (T_LeftParen); if (hd() == T_Var) { uint32_t dummy = 0; init = varBindings(&dummy, defaultNamespace(), false, false, EFLAG_NoIn, &numbindings, &lhs); } else if (hd() == T_Semicolon) ; else lhs = init = commaExpression(EFLAG_NoIn); if (match(T_In)) { if (numbindings > 1) compiler->syntaxError(pos, SYNTAXERR_FOR_IN_ONEBINDING); Expr* objexpr = commaExpression(0); eat (T_RightParen); Stmt* body = statement(); AvmAssert( lhs != NULL ); return ALLOC(ForInStmt, (pos, lhs, init, objexpr, body, is_each)); } else { if (is_each) compiler->syntaxError(pos, SYNTAXERR_FOR_EACH_REQS_IN); eat(T_Semicolon); Expr* test = hd() == T_Semicolon ? NULL : commaExpression(0); eat(T_Semicolon); Expr* update = hd() == T_RightParen ? NULL : commaExpression(0); eat(T_RightParen); Stmt* body = statement (); return ALLOC(ForStmt, (pos, init, test, update, body)); } }
void Parser::xmlExpression(XmlContext* ctx, Escapement esc) { AvmAssert( T0 == T_XmlLeftBrace ); next(); // re-enter normal lexing Expr* expr = commaExpression(0); if (esc != ESC_none) expr = ALLOC(EscapeExpr, (expr, esc)); ctx->addExpr(expr); AvmAssert( T0 == T_RightBrace && T1 == T_LAST ); xmlPushback('}'); xmlAtom(); xmlAssert(ctx, T_XmlRightBrace); }
Stmt* Parser::returnStatement() { eat (T_Return); uint32_t pos = position(); if (topRib->tag != RIB_Function) compiler->syntaxError(pos, SYNTAXERR_RETURN_OUTSIDE_FN); Expr* expr = NULL; if (noNewline()) { if (topRib->signature->isVoid) compiler->syntaxError(pos, SYNTAXERR_VOIDFN_RETURNS_VALUE); expr = commaExpression(0); } return ALLOC(ReturnStmt, (pos, expr)); }
// 'default' has been consumed, hd() is the identifier 'xml' Stmt* Parser::defaultXmlNamespaceStatement() { uint32_t pos = position(); if(hd() != T_Identifier || identValue() != compiler->SYM_xml) goto failure; eat(T_Identifier); if(hd() != T_Namespace) goto failure; eat(T_Namespace); eat(T_Assign); setUsesDefaultXmlNamespace(); return ALLOC(DefaultXmlNamespaceStmt, (pos, commaExpression(0))); failure: compiler->syntaxError(pos, SYNTAXERR_EXPECT_DXNS); /*NOTREACHED*/ return NULL; }
Seq<CaseClause*>* Parser::caseElements() { SeqBuilder<CaseClause*> cases(allocator); bool hasDefault = false; CaseClause* last = NULL; for (;;) { switch (hd ()) { case T_RightBrace: return cases.get(); case T_Default: { if (hd2() != T_Colon) goto just_a_statement; // default xml namespace eat(T_Default); eat(T_Colon); if (hasDefault) compiler->syntaxError(position(), SYNTAXERR_DUPLICATE_DEFAULT); hasDefault = true; cases.addAtEnd(last = ALLOC(CaseClause, (0, NULL))); break; } case T_Case: { eat(T_Case); uint32_t pos = position(); Expr* expr = commaExpression(0); eat(T_Colon); cases.addAtEnd(last = ALLOC(CaseClause, (pos, expr))); } /*FALLTHROUGH*/ just_a_statement: default: { if (last == NULL) compiler->syntaxError(position(), SYNTAXERR_EXPECT_CASE_OR_DEFAULT); AvmAssert(last->stmts == NULL); SeqBuilder<Stmt*> stmts(allocator); while (hd() != T_RightBrace && hd() != T_Case && hd() != T_Default) stmts.addAtEnd(statement()); last->stmts = stmts.get(); break; } } } }
Stmt* Parser::throwStatement() { eat (T_Throw); uint32_t pos = position(); return ALLOC(ThrowStmt, (pos, commaExpression(0))); }