/* ParseFor - parse the 'FOR' statement */ static void ParseFor(ParseContext *c) { ParseTreeNode *var, *step; int test, body, inst; Token tkn; PVAL pv; PushBlock(c); c->bptr->type = BLOCK_FOR; /* get the control variable */ FRequire(c, T_IDENTIFIER); var = GetSymbolRef(c, c->token); code_lvalue(c, var, &pv); FRequire(c, '='); /* parse the starting value expression */ ParseRValue(c); /* parse the TO expression and generate the loop termination test */ test = codeaddr(c); (*pv.fcn)(c, PV_STORE, &pv); (*pv.fcn)(c, PV_LOAD, &pv); FRequire(c, T_TO); ParseRValue(c); putcbyte(c, OP_LE); putcbyte(c, OP_BRT); body = putcword(c, 0); /* branch to the end if the termination test fails */ putcbyte(c, OP_BR); c->bptr->u.ForBlock.end = putcword(c, 0); /* update the for variable after an iteration of the loop */ c->bptr->u.ForBlock.nxt = codeaddr(c); (*pv.fcn)(c, PV_LOAD, &pv); /* get the STEP expression */ if ((tkn = GetToken(c)) == T_STEP) { step = ParseExpr(c); code_rvalue(c, step); tkn = GetToken(c); } /* no step so default to one */ else { putcbyte(c, OP_LIT); putcword(c, 1); } /* generate the increment code */ putcbyte(c, OP_ADD); inst = putcbyte(c, OP_BR); putcword(c, test - inst - 1 - sizeof(VMUVALUE)); /* branch to the loop body */ fixupbranch(c, body, codeaddr(c)); Require(c, tkn, T_EOL); }
DOM* JSONParser::Load(std::string path) { Resource *res=LoadResource(path.c_str()); res->Open(); First((char*)res->Bufferize()); DOM *dom=ParseRValue(); delete res; return dom; }
/* ParseDoUntil - parse the 'DO UNTIL' statement */ static void ParseDoUntil(ParseContext *c) { PushBlock(c); c->bptr->type = BLOCK_DO; c->bptr->u.DoBlock.nxt = codeaddr(c); ParseRValue(c); putcbyte(c, OP_BRT); c->bptr->u.DoBlock.end = putcword(c, 0); FRequire(c, T_EOL); }
/* ParseLet - parse the 'LET' statement */ static void ParseLet(ParseContext *c) { ParseTreeNode *lvalue; PVAL pv; lvalue = ParsePrimary(c); code_lvalue(c, lvalue, &pv); FRequire(c, '='); ParseRValue(c); (*pv.fcn)(c, PV_STORE, &pv); FRequire(c, T_EOL); }
/* ParseReturn - parse the 'RETURN' statement */ static void ParseReturn(ParseContext *c) { Token tkn; if ((tkn = GetToken(c)) == T_EOL) { putcbyte(c, OP_LIT); putcword(c, 0); } else { SaveToken(c, tkn); ParseRValue(c); FRequire(c, T_EOL); } putcbyte(c, OP_RETURN); }
/* ParseLoopUntil - parse the 'LOOP UNTIL' statement */ static void ParseLoopUntil(ParseContext *c) { int inst; switch (CurrentBlockType(c)) { case BLOCK_DO: ParseRValue(c); inst = putcbyte(c, OP_BRF); putcword(c, c->bptr->u.DoBlock.nxt - inst - 1 - sizeof(VMUVALUE)); fixupbranch(c, c->bptr->u.DoBlock.end, codeaddr(c)); PopBlock(c); break; default: ParseError(c, "LOOP without a matching DO"); break; } FRequire(c, T_EOL); }
/* ParseIf - parse the 'IF' statement */ static void ParseIf(ParseContext *c) { Token tkn; ParseRValue(c); FRequire(c, T_THEN); PushBlock(c); c->bptr->type = BLOCK_IF; putcbyte(c, OP_BRF); c->bptr->u.IfBlock.nxt = putcword(c, 0); c->bptr->u.IfBlock.end = 0; if ((tkn = GetToken(c)) != T_EOL) { ParseStatement(c, tkn); fixupbranch(c, c->bptr->u.IfBlock.nxt, codeaddr(c)); PopBlock(c); } else Require(c, tkn, T_EOL); }
/* ParseElseIf - parse the 'ELSE IF' statement */ static void ParseElseIf(ParseContext *c) { switch (CurrentBlockType(c)) { case BLOCK_IF: putcbyte(c, OP_BR); c->bptr->u.IfBlock.end = putcword(c, c->bptr->u.IfBlock.end); fixupbranch(c, c->bptr->u.IfBlock.nxt, codeaddr(c)); c->bptr->u.IfBlock.nxt = 0; ParseRValue(c); FRequire(c, T_THEN); putcbyte(c, OP_BRF); c->bptr->u.IfBlock.nxt = putcword(c, 0); FRequire(c, T_EOL); break; default: ParseError(c, "ELSE IF without a matching IF"); break; } }
/* ParseImpliedLetOrFunctionCall - parse an implied let statement or a function call */ static void ParseImpliedLetOrFunctionCall(ParseContext *c) { ParseTreeNode *expr; Token tkn; PVAL pv; expr = ParsePrimary(c); switch (tkn = GetToken(c)) { case '=': code_lvalue(c, expr, &pv); ParseRValue(c); (*pv.fcn)(c, PV_STORE, &pv); break; default: SaveToken(c, tkn); code_rvalue(c, expr); putcbyte(c, OP_DROP); break; } FRequire(c, T_EOL); }
DOM* JSONParser::ParseRValue() { if(Char()=='{') { Next(); bool firstObject=true; DOM *dom=new DOM(); while(Char()!='}' && Char()!=0) { if(!firstObject) { if(Char()==',') { Next(); } else { LOGW("JSONParser::ParserRValue() syntax error at line %d: expected ',' between keys",m_lastLine); delete dom; return DOM::GetSentinel(); } } firstObject=false; string lValue = ParseLValue(); if(Char()!=':') { LOGW("JSONParser::ParseRValue() syntax error at line %d: expected ':' after key",m_lastLine); delete dom; return DOM::GetSentinel(); } Next(); dom->m_childs[lValue]=ParseRValue(); if(Char()!=',' && Char()!='}') { LOGW("JSONParser::ParseRValue() syntax error at line %d: expected ',' between keys or '}' after an object",m_lastLine); delete dom; return DOM::GetSentinel(); } } if(Char()==0) { LOGW("JSONParser::ParseRValue() syntax error at line %d: expected '}' after an object",m_lastLine); delete dom; return DOM::GetSentinel(); } Next(); return dom; } else if(Char()=='"') { Next(); string ans=""; while(Char()!='"' && Char()!=0) { ans+=Char(); Next(); } if(Char()==0) { LOGW("JSONParser::ParseRValue() syntax error at line %d: expected '\"' after value",m_lastLine); return DOM::GetSentinel(); } Next(); return new DOM(ans,true); } LOGW("JSONParser::ParseRValue() syntax error at line %d: expected '{' or '\"' before an object",m_lastLine); return DOM::GetSentinel(); }