asCScriptNode *asCParser::ParseGlobalVar() { asCScriptNode *node = new asCScriptNode(snGlobalVar); // Parse data type node->AddChildLast(ParseType(true)); if( isSyntaxError ) return node; sToken t; for(;;) { // Parse identifier node->AddChildLast(ParseIdentifier()); if( isSyntaxError ) return node; // If next token is assignment, parse expression GetToken(&t); if( t.type == ttAssignment ) { GetToken(&t); RewindTo(&t); if( t.type == ttStartStatementBlock ) { node->AddChildLast(ParseInitList()); if( isSyntaxError ) return node; } else { node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; } } else if( t.type == ttOpenParanthesis ) { RewindTo(&t); node->AddChildLast(ParseArgList()); if( isSyntaxError ) return node; } else RewindTo(&t); // continue if list separator, else terminate with end statement GetToken(&t); if( t.type == ttListSeparator ) continue; else if( t.type == ttEndStatement ) { node->UpdateSourcePos(t.pos, t.length); return node; } else { Error(ExpectedTokens(",", ";").AddressOf(), &t); return node; } } return 0; }
FuncSymbol* Parser :: createFunction(const string &name, SymbolType *type, bool ConstFun){ FuncSymbol *func = new FuncSymbol(name, type); func->params = new SymTable(); symStack->push(func->params); func->isConst = ConstFun; ParseArgList(); symStack->pop(); return func; }
asCScriptNode *asCParser::ParseFunctionCall() { asCScriptNode *node = new asCScriptNode(snFunctionCall); node->AddChildLast(ParseType(false)); if( isSyntaxError ) return node; node->AddChildLast(ParseArgList()); return node; }
bool Parser::CheckArgs(FuncSymbol *func1){ symStack->push(new SymTable()); ParseArgList(); if(func1->params->size() != symStack->size()) return 0; for( int i = 0 ; i < func1->params->name.size();i++){ if(func1->params->sym_ptr[i]->getType() != symStack->top()->sym_ptr[i]->getType()) return 0; } symStack->pop(); return 1; }
Type * ParseType3() { Type * type = NULL, * variant_type = NULL; Type * elmt, * t; Var * var; BigInt * st; //# "type" restrict_type if (NextIs(TOKEN_TYPE2)) { variant_type = ParseType2(INSTR_VAR); type = TypeType(variant_type); //# "enum" ["struct"] } else if (NextIs(TOKEN_ENUM)) { type = TypeAlloc(TYPE_INT); type->range.flexible = true; type->is_enum = true; if (NextIs(TOKEN_STRUCT)) { ParseEnumStruct(type); } else { type = ParseConstList(type); } //# "proc" args } else if (NextIs(TOKEN_PROC)) { type = TypeAlloc(TYPE_PROC); ParseArgList(SUBMODE_ARG_IN, type); if (TOK) { ProcTypeFinalize(type); } //# "macro" args } else if (NextIs(TOKEN_MACRO)) { type = TypeAlloc(TYPE_MACRO); ParseArgList(SUBMODE_ARG_IN, type); // Struct } else if (NextIs(TOKEN_STRUCT)) { type = TypeAlloc(TYPE_STRUCT); ParseArgList(SUBMODE_EMPTY, type); // String } else if (NextIs(TOKEN_STRING_TYPE)) { type = TypeAlloc(TYPE_STRING); // Array } else if (NextIs(TOKEN_ARRAY)) { type = TypeAlloc(TYPE_ARRAY); t = NULL; if (TOK == TOKEN_OPEN_P) { EnterBlockWithStop(TOKEN_EQUAL); while (TOK != TOKEN_ERROR && !NextIs(TOKEN_BLOCK_END)) { elmt = ParseIntType(); if (type->index == NULL) { type->index = elmt; } else if (t != NULL) { t->right = TypeTuple(t->right, elmt); t = t->right; } else { t = TypeTuple(type->index, elmt); type->index = t; } NextIs(TOKEN_COMMA); }; } // If no dimension has been defined, use flexible array. // This is possible only for constants now. if (TOK) { if (type->index == NULL) { elmt = TypeAlloc(TYPE_INT); elmt->range.flexible = true; elmt->range.min = 0; type->index = elmt; } } // Element STEP may be defined if (TOK) { if (NextIs(TOKEN_STEP)) { ExpectExpression(NULL); if (TOK) { var = STACK[0]; st = VarIntConst(var); if (st != NULL) { type->step = IntN(st); } else { SyntaxError("Expected integer constant"); } } } } if (TOK) { if (NextIs(TOKEN_OF)) { type->element = ParseSubtype(); } else { type->element = TypeByte(); } } if (TOK) { if (type->step == 0) { type->step = TypeSize(type->element); } } } else if (NextIs(TOKEN_ADR2)) { elmt = NULL; if (NextIs(TOKEN_OF)) { elmt = ParseSubtype(); } type = TypeAdrOf(elmt); } return type; }