asCScriptNode *asCParser::ParseImport() { asCScriptNode *node = new asCScriptNode(snImport); sToken t; GetToken(&t); if( t.type != ttImport ) { Error(ExpectedToken(asGetTokenDefinition(ttImport)).AddressOf(), &t); return node; } node->SetToken(&t); node->UpdateSourcePos(t.pos, t.length); node->AddChildLast(ParseFunctionDefinition()); if( isSyntaxError ) return node; GetToken(&t); if( t.type != ttIdentifier ) { Error(ExpectedToken(FROM_TOKEN).AddressOf(), &t); return node; } asCString str; str.Assign(&script->code[t.pos], t.length); if( str != FROM_TOKEN ) { Error(ExpectedToken(FROM_TOKEN).AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttStringConstant ) { Error(TXT_EXPECTED_STRING, &t); return node; } asCScriptNode *mod = new asCScriptNode(snConstant); node->AddChildLast(mod); mod->SetToken(&t); mod->UpdateSourcePos(t.pos, t.length); GetToken(&t); if( t.type != ttEndStatement ) { Error(ExpectedToken(asGetTokenDefinition(ttEndStatement)).AddressOf(), &t); return node; } node->UpdateSourcePos(t.pos, t.length); return node; }
int asCParser::ParseFunctionDefinition(asCScriptCode *script) { Reset(); this->script = script; scriptNode = ParseFunctionDefinition(); if( errorWhileParsing ) return -1; return 0; }
/* declare a variable or function */ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) { char *Identifier; struct ValueType *BasicType; struct ValueType *Typ; struct Value *NewVariable = NULL; int IsStatic = FALSE; int FirstVisit = FALSE; Picoc *pc = Parser->pc; TypeParseFront(Parser, &BasicType, &IsStatic); do { TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier); if ((Token != TokenVoidType && Token != TokenStructType && Token != TokenUnionType && Token != TokenEnumType) && Identifier == pc->StrEmpty) ProgramFail(Parser, "identifier expected"); if (Identifier != pc->StrEmpty) { /* handle function definitions */ if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) { ParseFunctionDefinition(Parser, Typ, Identifier); return FALSE; } else { if (Typ == &pc->VoidType && Identifier != pc->StrEmpty) ProgramFail(Parser, "can't define a void variable"); if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto) NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit); if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) { /* we're assigning an initial value */ LexGetToken(Parser, NULL, TRUE); ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit); } } } Token = LexGetToken(Parser, NULL, FALSE); if (Token == TokenComma) LexGetToken(Parser, NULL, TRUE); } while (Token == TokenComma); return TRUE; }
/* add a library */ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList) { struct ParseState Parser; int Count; char *Identifier; struct ValueType *ReturnType; struct Value *NewValue; void *Tokens; char *IntrinsicName = TableStrRegister(pc, "c library"); /* read all the library definitions */ for (Count = 0; FuncList[Count].Prototype != NULL; Count++) { Tokens = LexAnalyse(pc, IntrinsicName, FuncList[Count].Prototype, strlen((char *)FuncList[Count].Prototype), NULL); LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, TRUE, FALSE); TypeParse(&Parser, &ReturnType, &Identifier, NULL); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier); NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func; HeapFreeMem(pc, Tokens); } }
AST* ParseExpression(ParserState* parser) { switch(parser->currentToken.type) { case TOKEN_INTREAD: Match(parser, TOKEN_INTREAD); return CreateASTNode(SEM_INTREAD, VALUE_EMPTY); case TOKEN_READ: Match(parser, TOKEN_READ); return CreateASTNode(SEM_READ, VALUE_EMPTY); case TOKEN_ARRAY: return ParseArray(parser); case TOKEN_OBJECT: case TOKEN_NEW: return ParseObject(parser); case TOKEN_FUNCTION: return ParseFunctionDefinition(parser); default: return ParseArithmeticalExpression(parser); } assert(0); return NULL; }
AST* ParseOperator(ParserState* parser) { AST* ast; switch(parser->currentToken.type) { case TOKEN_BEGIN: return ParseBlock(parser); case TOKEN_ID: ast = parser->nextToken.type == TOKEN_LEFTBRACKET ? ParseFunctionCall(parser) : ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_LOCAL: ast = ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_WHILE: return ParseWhileCycle(parser); case TOKEN_IF: return ParseIfStatement(parser); case TOKEN_FUNCTION: return ParseFunctionDefinition(parser); case TOKEN_RETURN: ast = ParseReturn(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_PRINT: ast = ParsePrint(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_INCLUDE: return ParseInclude(parser); case TOKEN_LOAD: ast = ParseLoad(parser); Match(parser, TOKEN_SEMICOLON); return ast; /** TODO: Factor common parts out of switch */ } FailWithUnexpectedToken(parser, parser->currentToken.type, TOKEN_ID); return NULL; }