[指令生成]语法制导的指令生成[5]

    最后还剩下一个, 声明语句的翻译. 因为符号表API已经很完善了, 所以声明语句的翻译不会太困难. 将一些小地方处理好了就行. 难对付的部分是设定初始值, 需要考虑到类型转换. OK, 代码说明一切.

struct List* insDeclarationNode(void* node)
{
    struct DeclarationNode* self = (struct DeclarationNode*)node;
    // 节点指令
    struct List* insList = (struct List*)newArrayList();
    AcceptType type = self->dectype;
    int i;

    // 如果有初值, 这些变量会派上用场
    struct IntParamInstruction* loadAddr;
    struct AbstractValueNode* initialVal;
    // 如果初值需要转型, 就用这个
    InstructionCode castCode = (INTEGER == type) ? REAL_2_INT : INT_2_REAL;
    InstructionCode assignCode = (INTEGER == type) ? INT_ASSIGN : REAL_ASSIGN;
    struct NoParamInstruction* initAssign;
    // 赋值结束需要弹出初始值, 这两个留作备用.
    int popSize = (INTEGER == type) ? INT_SIZE : REAL_SIZE;
    struct IntParamInstruction* popInitVal;
    for (i = 0; i < self->vars->length(self->vars); ++i) { // 一次可能声明多个变量
        // 调用符号表
        int addr = declare((struct VariableNode*)
                       (self->vars->peekAt(self->vars, i)), type);
        if (NULL != (initialVal = (struct AbstractValueNode*) // 如果有初始化
                            (self->initVals->peekAt(self->initVals, i)))) {
            struct List* insInitVal = initialVal->createInstruction(initialVal);
            // load 刚刚声明的变量
            loadAddr = (struct IntParamInstruction*)
                                   allocate(sizeof(struct IntParamInstruction));
            loadAddr->code = CONST_INT;
            loadAddr->param = addr;
            appendInsList(appendIns(insList, loadAddr), insInitVal);

            // 类型不匹配
            if (initialVal->typeOf(initialVal) != type) {
                struct NoParamInstruction* cast = (struct NoParamInstruction*)
                                    allocate(sizeof(struct NoParamInstruction));
                cast->code = castCode;
                appendIns(insList, cast);
            }
            initAssign = (struct NoParamInstruction*)
                                   allocate(sizeof(struct NoParamInstruction));
            initAssign->code = assignCode;
            popInitVal = (struct IntParamInstruction*)
                                   allocate(sizeof(struct IntParamInstruction));
            popInitVal->code = POP;
            popInitVal->param = popSize;
            appendIns(appendIns(insList, initAssign), popInitVal);
        }
    }
    return insList;
}

接下来, 就要进入... 测试环节了. 这么多指令生成代码, 不测试, 能放心吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值