generate.c
static void code_expr(GenerateContext *c, ParseTreeNode *expr, PVAL *pv)
{
    VMVALUE ival;
    switch (expr->nodeType) {
    case NodeTypeFunctionDefinition:
        code_function_definition(c, expr);
        break;
    case NodeTypeLetStatement:
        code_rvalue(c, expr->u.letStatement.rvalue);
        code_lvalue(c, expr->u.letStatement.lvalue, pv);
        (pv->fcn)(c, PV_STORE, pv);
        break;
    case NodeTypeIfStatement:
        code_if_statement(c, expr);
        break;
    case NodeTypeForStatement:
        code_for_statement(c, expr);
        break;
    case NodeTypeDoWhileStatement:
        code_do_while_statement(c, expr);
        break;
    case NodeTypeDoUntilStatement:
        code_do_until_statement(c, expr);
        break;
    case NodeTypeLoopStatement:
        code_loop_statement(c, expr);
        break;
    case NodeTypeLoopWhileStatement:
        code_loop_while_statement(c, expr);
        break;
    case NodeTypeLoopUntilStatement:
        code_loop_until_statement(c, expr);
        break;
    case NodeTypeReturnStatement:
        code_return_statement(c, expr);
        break;
    case NodeTypeAsmStatement:
        code_asm_statement(c, expr);
        break;
    case NodeTypeCallStatement:
        code_rvalue(c, expr->u.callStatement.expr);
        putcbyte(c, OP_DROP);
        break;
    case NodeTypeGlobalRef:
        pv->fcn = code_global;
        pv->u.sym = expr->u.symbolRef.symbol;
        break;
    case NodeTypeArgumentRef:
        pv->fcn = code_local;
        pv->u.val = expr->u.symbolRef.symbol->value;
        break;
    case NodeTypeLocalRef:
        pv->fcn = code_local;
        pv->u.val = -1 - expr->u.symbolRef.symbol->value;
        break;
    case NodeTypeStringLit:
        putcbyte(c, OP_LIT);
        putcword(c, AddStringRef(c, expr->u.stringLit.string));
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeIntegerLit:
        ival = expr->u.integerLit.value;
        if (ival >= -128 && ival <= 127) {
            putcbyte(c, OP_SLIT);
            putcbyte(c, ival);
        }
        else {
            putcbyte(c, OP_LIT);
            putcword(c, ival);
        }
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeUnaryOp:
        code_rvalue(c, expr->u.unaryOp.expr);
        putcbyte(c, expr->u.unaryOp.op);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeBinaryOp:
        code_rvalue(c, expr->u.binaryOp.left);
        code_rvalue(c, expr->u.binaryOp.right);
        putcbyte(c, expr->u.binaryOp.op);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeFunctionCall:
        code_call(c, expr);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeArrayRef:
        code_arrayref(c, expr, pv);
        break;
    case NodeTypeDisjunction:
        code_shortcircuit(c, OP_BRTSC, expr);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeConjunction:
        code_shortcircuit(c, OP_BRFSC, expr);
        pv->fcn = GEN_NULL;
        break;
    default:
        // error
        break;
    }
}
/* code_expr - generate code for an expression parse tree */
generate code for an expression parse tree
generate code for an expression parse tree
static void code_expr(GenerateContext *c, ParseTreeNode *expr, PVAL *pv)
{
    VMVALUE ival;
    switch (expr->nodeType) {
    case NodeTypeFunctionDefinition:
        code_function_definition(c, expr);
        break;
    case NodeTypeLetStatement:
        code_rvalue(c, expr->u.letStatement.rvalue);
        code_lvalue(c, expr->u.letStatement.lvalue, pv);
        (pv->fcn)(c, PV_STORE, pv);
        break;
    case NodeTypeIfStatement:
        code_if_statement(c, expr);
        break;
    case NodeTypeForStatement:
        code_for_statement(c, expr);
        break;
    case NodeTypeDoWhileStatement:
        code_do_while_statement(c, expr);
        break;
    case NodeTypeDoUntilStatement:
        code_do_until_statement(c, expr);
        break;
    case NodeTypeLoopStatement:
        code_loop_statement(c, expr);
        break;
    case NodeTypeLoopWhileStatement:
        code_loop_while_statement(c, expr);
        break;
    case NodeTypeLoopUntilStatement:
        code_loop_until_statement(c, expr);
        break;
    case NodeTypeReturnStatement:
        code_return_statement(c, expr);
        break;
    case NodeTypeAsmStatement:
        code_asm_statement(c, expr);
        break;
    case NodeTypeCallStatement:
        code_rvalue(c, expr->u.callStatement.expr);
        putcbyte(c, OP_DROP);
        break;
    case NodeTypeGlobalRef:
        pv->fcn = code_global;
        pv->u.sym = expr->u.symbolRef.symbol;
        break;
    case NodeTypeArgumentRef:
        pv->fcn = code_local;
        pv->u.val = expr->u.symbolRef.symbol->value;
        break;
    case NodeTypeLocalRef:
        pv->fcn = code_local;
        pv->u.val = -1 - expr->u.symbolRef.symbol->value;
        break;
    case NodeTypeStringLit:
        putcbyte(c, OP_LIT);
        putcword(c, AddStringRef(c, expr->u.stringLit.string));
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeIntegerLit:
        ival = expr->u.integerLit.value;
        if (ival >= -128 && ival <= 127) {
            putcbyte(c, OP_SLIT);
            putcbyte(c, ival);
        }
        else {
            putcbyte(c, OP_LIT);
            putcword(c, ival);
        }
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeUnaryOp:
        code_rvalue(c, expr->u.unaryOp.expr);
        putcbyte(c, expr->u.unaryOp.op);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeBinaryOp:
        code_rvalue(c, expr->u.binaryOp.left);
        code_rvalue(c, expr->u.binaryOp.right);
        putcbyte(c, expr->u.binaryOp.op);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeFunctionCall:
        code_call(c, expr);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeArrayRef:
        code_arrayref(c, expr, pv);
        break;
    case NodeTypeDisjunction:
        code_shortcircuit(c, OP_BRTSC, expr);
        pv->fcn = GEN_NULL;
        break;
    case NodeTypeConjunction:
        code_shortcircuit(c, OP_BRFSC, expr);
        pv->fcn = GEN_NULL;
        break;
    default:
        break;
    }
}
static void code_expr ( GenerateContext * c , ParseTreeNode * expr , PVAL * pv ) { VMVALUE ival ; switch ( expr -> nodeType ) { case NodeTypeFunctionDefinition : code_function_definition ( c , expr ) ; break ; case NodeTypeLetStatement : code_rvalue ( c , expr -> u . letStatement . rvalue ) ; code_lvalue ( c , expr -> u . letStatement . lvalue , pv ) ; ( pv -> fcn ) ( c , PV_STORE , pv ) ; break ; case NodeTypeIfStatement : code_if_statement ( c , expr ) ; break ; case NodeTypeForStatement : code_for_statement ( c , expr ) ; break ; case NodeTypeDoWhileStatement : code_do_while_statement ( c , expr ) ; break ; case NodeTypeDoUntilStatement : code_do_until_statement ( c , expr ) ; break ; case NodeTypeLoopStatement : code_loop_statement ( c , expr ) ; break ; case NodeTypeLoopWhileStatement : code_loop_while_statement ( c , expr ) ; break ; case NodeTypeLoopUntilStatement : code_loop_until_statement ( c , expr ) ; break ; case NodeTypeReturnStatement : code_return_statement ( c , expr ) ; break ; case NodeTypeAsmStatement : code_asm_statement ( c , expr ) ; break ; case NodeTypeCallStatement : code_rvalue ( c , expr -> u . callStatement . expr ) ; putcbyte ( c , OP_DROP ) ; break ; case NodeTypeGlobalRef : pv -> fcn = code_global ; pv -> u . sym = expr -> u . symbolRef . symbol ; break ; case NodeTypeArgumentRef : pv -> fcn = code_local ; pv -> u . val = expr -> u . symbolRef . symbol -> value ; break ; case NodeTypeLocalRef : pv -> fcn = code_local ; pv -> u . val = -1 - expr -> u . symbolRef . symbol -> value ; break ; case NodeTypeStringLit : putcbyte ( c , OP_LIT ) ; putcword ( c , AddStringRef ( c , expr -> u . stringLit . string ) ) ; pv -> fcn = GEN_NULL ; break ; case NodeTypeIntegerLit : ival = expr -> u . integerLit . value ; if ( ival >= -128 && ival <= 127 ) { putcbyte ( c , OP_SLIT ) ; putcbyte ( c , ival ) ; } else { putcbyte ( c , OP_LIT ) ; putcword ( c , ival ) ; } pv -> fcn = GEN_NULL ; break ; case NodeTypeUnaryOp : code_rvalue ( c , expr -> u . unaryOp . expr ) ; putcbyte ( c , expr -> u . unaryOp . op ) ; pv -> fcn = GEN_NULL ; break ; case NodeTypeBinaryOp : code_rvalue ( c , expr -> u . binaryOp . left ) ; code_rvalue ( c , expr -> u . binaryOp . right ) ; putcbyte ( c , expr -> u . binaryOp . op ) ; pv -> fcn = GEN_NULL ; break ; case NodeTypeFunctionCall : code_call ( c , expr ) ; pv -> fcn = GEN_NULL ; break ; case NodeTypeArrayRef : code_arrayref ( c , expr , pv ) ; break ; case NodeTypeDisjunction : code_shortcircuit ( c , OP_BRTSC , expr ) ; pv -> fcn = GEN_NULL ; break ; case NodeTypeConjunction : code_shortcircuit ( c , OP_BRFSC , expr ) ; pv -> fcn = GEN_NULL ; break ; default : break ; } }
code_expr - generate code for an expression parse tree
code_expr - generate code for an expression parse tree
// error
