
最近のマイブーム9ccコンパイラ作成
前回単語変数対応したのですが、複数文字のローカル変数対応は宿題になっていました。
ヒントとしては、連想配列を使うと言う事で、連想配列の作成方法は方法が載っていました。
こんな感じか?というのを記事にします。
連想配列をどう使うかがポイントだと思うのですが、前回1文字の変数対応した時には26文字分の領域を確保していました。
今回は変数の数分領域を確保しておいて、後から使う事になると思います。
パーサーの変更
Tokenにパースする処理の部分で複数文字の変数判定が必要になります。
変数の型をTokenとして登録する時に変数名も登録します。
また、Nodeを作成する処理の際に、変数の数をカウントします。
その際に連想配列を使って、変数の数とスタックに積んだ時の数を設定しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if (get_token(pos)->ty == TK_IDENT) { Node *node = new_node(ND_IDENT, NULL, NULL); node->name = get_token(pos++)->input; // 変数の数を数えるためにMapに値を入れる // variablesに登録されていない変数はスタックに積む必要がある // valsに変数のIndexを入れる int *count_of_value = map_get(variables, node->name); if (count_of_value == NULL) { count_of_value = malloc ( sizeof ( int )); // 変数の出現順をIndexにする *count_of_value = variables->keys->len; map_put(variables, node->name, count_of_value); } return node; } |
コード生成部分の修正
プロローグで26文字固定で確保していた変数領域を必要な数にします。
変数が幾つあるかは連想配列の数を調べればわかります。
あとは変数をスタックに入れている処理の部分のoffsetの計算処理の部分を連想配列の数値をつかって計算するように修正すればうまく動作するようになりました。
テストコードで動作を確認すれば実装完了です。
0 件のコメント :
コメントを投稿