Beispiel #1
0
/* 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);
}
Beispiel #2
0
/* 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);
}
Beispiel #3
0
/* CallHandler - compile a call to a runtime print function */
static void CallHandler(ParseContext *c, char *name, ParseTreeNode *expr)
{
    Symbol *sym;
    
    /* find the built-in function */
    if (!(sym = FindSymbol(&c->globals, name)))
        ParseError(c, "undefined print function: %s", name);
        
    /* compile the function symbol reference */
    putcbyte(c, OP_LIT);
    putcword(c, sym->value);

    /* compile the argument */
    if (expr)
        code_rvalue(c, expr);
    
    /* call the function */
    putcbyte(c, OP_CALL);
    putcbyte(c, (expr ? 1 : 0));
    putcbyte(c, OP_DROP);
}
Beispiel #4
0
/* ParseRValue - parse and generate code for an r-value */
void ParseRValue(ParseContext *c)
{
    ParseTreeNode *expr;
    expr = ParseExpr(c);
    code_rvalue(c, expr);
}