// <import> ::= "import" <ident> { "." <ident> }* { "." "*" } Stmt* Parser::importStatement() { SeqBuilder<Str*> name(allocator); StringBuilder id(compiler); const bool hackaround = true; // treat import x.y.z as import x.y.* eat(T_Import); if (hd() == T_Identifier) { name.addAtEnd(identValue()); id.append(identValue()); } eat(T_Identifier); bool qualified = true; while (match(T_Dot)) { if (hd() == T_Multiply) { match(T_Multiply); qualified = false; break; } if (hackaround) { if (hd() == T_Identifier && hd2() == T_Dot) { id.append("."); name.addAtEnd(identValue()); id.append(identValue()); } eat(T_Identifier); } else { id.append("."); if (hd() == T_Identifier) { name.addAtEnd(identValue()); id.append(identValue()); } eat(T_Identifier); } } Seq<Str*>* n = name.get(); if (qualified) { compiler->internalWarning(position(), "Unimplemented: Qualified import not supported yet, using an unqualified import instead"); addOpenNamespace(ALLOC(CommonNamespace, (id.str()))); addQualifiedImport(n); } else { addOpenNamespace(ALLOC(CommonNamespace, (id.str()))); addUnqualifiedImport(n); } return ALLOC(EmptyStmt, ()); }
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; } } } }
bool Parser::namespaceQualifier(int flags, Qualifier* qual) { switch (hd()) { case T_Native: if (!(flags & (SFLAG_Class|SFLAG_Package|SFLAG_Toplevel)) || qual->is_native || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "native"); eat(T_Native); qual->is_native = true; return true; case T_Private: if (!(flags & SFLAG_Class) || qual->tag != QUAL_none || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "private"); eat(T_Private); qual->tag = QUAL_private; return true; case T_Protected: if (!(flags & SFLAG_Class) || qual->tag != QUAL_none || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "protected"); eat(T_Protected); qual->tag = QUAL_protected; return true; case T_Public: if (!(flags & (SFLAG_Class|SFLAG_Package)) || qual->tag != QUAL_none || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "public"); eat(T_Protected); qual->tag = QUAL_public; return true; case T_Internal: if (!(flags & (SFLAG_Class|SFLAG_Package)) || qual->tag != QUAL_none || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "internal"); eat(T_Internal); qual->tag = QUAL_internal; return true; case T_Identifier: if (identValue() == compiler->SYM_namespace) return false; if ((flags & SFLAG_Class) && identValue() == compiler->SYM_static) { if (qual->is_static || qual->is_prototype) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "static"); next(); qual->is_static = true; return true; } if ((flags & SFLAG_Class) && identValue() == compiler->SYM_prototype) { if (qual->is_static || qual->is_prototype || qual->is_native || qual->tag != QUAL_none) compiler->syntaxError(position(), SYNTAXERR_KWD_NOT_ALLOWED, "prototype"); next(); qual->is_prototype = true; return true; } if (qual->tag != QUAL_none) return false; if (qual->is_native) goto consume; switch (hd2()) { case T_Function: case T_Var: case T_Const: case T_Class: case T_Interface: goto consume; default: return false; } consume: qual->tag = QUAL_name; qual->name = identValue(); eat(T_Identifier); return true; default: compiler->internalError(position(), "Unexpected namespace qualifier"); /*NOTREACHED*/ return false; } }