自分のプログラミング言語でコードを生成するために、私は訪問者パターンを使用しています。代入文を処理するためのより良い方法を探したいと思います。ビジターパターンとコンパイラコードの生成、割り当ての処理方法は?
私の仮想マシンをベースに登録し、各式ノードは、ちょうど私がバイナリ式ノードを訪問するときに、私は次のようなコードを実行するグローバルスタックにレジスタ番号をPUSH訪れている:私はすることができます。このコードで
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);
}
}
以下のような処理指示:レジスタのレジスタ1と変数Bに変数Aを仮定すると、A + B が生成2のコードは次のようになります
ADD 3 1 2
問題を割り当て、命令の異なるセットを必要とするで有することですスタック上のレジスタ番号は不十分です。たとえば、グローバル変数にアクセス(読み込み)するには、GLOAD命令を使用してグローバル変数に格納(書き込み)する必要があります.GSTORE命令を使用する必要があります。
私は現在、各ノードにboolean is_assignment値を格納することで問題を解決しています。そのため、どの命令を生成するかを再帰的に確認できますが、それは多くのロジックを訪問ノードに分散させる必要があります。 visit_binary_expr関数だけが、生成する最適な命令が何であるかを判断できる、よりエレガントな方法です。