示例#1
0
 // '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_Identifier || identValue() != compiler->SYM_namespace)
         goto failure;
     eat(T_Identifier);
     eat(T_Assign);
     setUsesDefaultXmlNamespace();
     return ALLOC(DefaultXmlNamespaceStmt, (pos, commaExpression(0)));
 failure:
     compiler->syntaxError(pos, SYNTAXERR_EXPECT_DXNS);
     /*NOTREACHED*/
     return NULL;
 }
示例#2
0
 // <import> ::= "import" <ident> { "." <ident> }* { "." "*" }
 Stmt* Parser::importStatement()
 {
     uint32_t pos = position();
     SeqBuilder<Str*> name(allocator);
     eat(T_Import);
     if (hd() == T_Identifier)
         name.addAtEnd(identValue());
     eat(T_Identifier);
     while (match(T_Dot)) {
         if (hd() == T_Multiply) {
             name.addAtEnd(NULL);
             break;
         }
         if (hd() == T_Identifier)
             name.addAtEnd(identValue());
         eat(T_Identifier);
     }
     return ALLOC(ImportStmt, (pos, name.get()));
 }
示例#3
0
 Stmt* Parser::useStatement()
 {
     uint32_t pos = position();
     eat(T_Use);
     if (!(hd() == T_Identifier && identValue() == compiler->SYM_namespace))
         compiler->syntaxError(pos, SYNTAXERR_ILLEGAL_USE);
     eat(T_Identifier);
     Str* ns = identifier();
     return ALLOC(UseNamespaceStmt, (pos, ns));
 }
示例#4
0
        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));
            }
        }
示例#5
0
 // <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, ());
 }
示例#6
0
 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;
     }
 }