首页 \ 问答 \ 访问者模式和编译器代码生成,如何处理赋值?(Visitor pattern and compiler code generation, how to process assignment?)

访问者模式和编译器代码生成,如何处理赋值?(Visitor pattern and compiler code generation, how to process assignment?)

对于我的编程语言中的代码生成,我使用访问者模式,我想找到一种更好的方法来处理赋值语句。

我的虚拟机是基于注册的,每个表达式节点只访问一个寄存器编号到全局堆栈中,所以当我访问二进制表达式节点时,我执行如下代码:

static void visit_binary_expr (gvisitor_t *self, gnode_binary_expr_t *node) {
    DECLARE_CODE();

    bool is_assignment = (node->op == TOK_OP_ASSIGN);
    if (is_assignment) {
        // assignment is right associative
        visit(node->right);
        visit(node->left);
    } else {
        // visiting binary operation from left to right
        visit(node->left);
        visit(node->right);
    }

    if (!is_assignment) {
        uint32_t r3 = ircode_register_pop(code);
        uint32_t r2 = ircode_register_pop(code);
        uint32_t r1 = ircode_register_push_temp(code);

        opcode_t op = token2opcode(node->op);
        ircode_add(code, op, r1, r2, r3);
    }
}

使用此代码,我可以处理如下指令:a + b假设寄存器1中的变量a和寄存器2中的变量b生成的代码将是:

ADD 3 1 2

问题是分配需要一组不同的指令,并且只有堆栈上的寄存器号是不够的。 例如,为了访问(读取)全局变量,我应该使用GLOAD指令,而在存储(写入)全局变量时,我应该使用GSTORE指令。

我目前正在通过将boolean is_assignment值存储到每个节点来解决这个问题,所以我可以递归地检查要生成哪条指令但是需要将大量逻辑分配到每个被访问节点中,我真的想找到一种更优雅的方式只有visit_binary_expr函数可以决定生成的最佳指令是什么。


For code generation in my programming language I am using the visitor pattern and I'd like to find a better way to handle assignment statements.

My virtual machine is registered based and each expression node visited just PUSH a register number into a global stack so when I visit the binary expression node I perform a code like:

static void visit_binary_expr (gvisitor_t *self, gnode_binary_expr_t *node) {
    DECLARE_CODE();

    bool is_assignment = (node->op == TOK_OP_ASSIGN);
    if (is_assignment) {
        // assignment is right associative
        visit(node->right);
        visit(node->left);
    } else {
        // visiting binary operation from left to right
        visit(node->left);
        visit(node->right);
    }

    if (!is_assignment) {
        uint32_t r3 = ircode_register_pop(code);
        uint32_t r2 = ircode_register_pop(code);
        uint32_t r1 = ircode_register_push_temp(code);

        opcode_t op = token2opcode(node->op);
        ircode_add(code, op, r1, r2, r3);
    }
}

With this code I can process instructions like: a + b Assuming variable a in register 1 and variable b in register 2 code generated will be:

ADD 3 1 2

The problem is that assignments require a different set of instructions and having only register numbers on the stack is not sufficient. For example in order to access (read) a global variable I should use a GLOAD instruction while to store (write) into a global variable I should use a GSTORE instruction.

I am currently solving the issue by storing a boolean is_assignment value into each node, so I can recursively check which instruction to generate but that requires a lot of logic distributed into every visited node and I really would like to find out a more elegant way where only the visit_binary_expr function can decide what is the best instruction to generate.


原文:https://stackoverflow.com/questions/36800908
更新时间:2023-12-07 10:12

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。