コンパイラ作成の試み その2 言語の拡張(FOR文で四苦八苦)
(表示用のアイコンとして入れてあります) |
前回からずいぶんと時間が過ぎましたが、言語の拡張がなかなかうまくいかず、四苦八苦していますが、とりあえず現在の状況です。
拡張したのは以下の3つです。
1.コメント文が使えるようにした。
プログラム作成時にはコメントアウト機能は必須だと思いますので、/*と*/で囲んだ部分はコメントとして読み飛ばされるようにしました。
2.PRINT文(PRINTLNも)の書式を変更した。
C言語に慣れているせいか PRINT文の書式には違和感がありましたので、プリントする式部分を括弧で囲むように書式を変更しました。
変更前:PRINT I, ": ", DATA[I];
変更後:PRINT (I, ": ", DATA[I]);
3.FOR文を追加した。(...未完成)
制御文としては、IF文、WHILE文、DO..WHILE文があるのですが、やはりFOR文があると便利ということで追加してみようと試みました。
1と2は何とか実現できたのですが、3のFOR文の追加については四苦八苦した挙句、一応それらしく動作するものができたのですが、動作が思ったようにはなりません。。。
例えば FOR (I=0; I<10; I=I+1) PRINT(I,","); の場合
結果は 1,2,3,4,5,6,7,8,9,10 となってしまうのです。
その理由ですが、FOR文を頭から見ていくため、まず I=0 の初期設定で I の値を設定し、次に I<10 の終了条件の真偽判定をして、真の場合は続いて I=I+1 の増分を実行してから PRINT文を実行した後にFOR文の先頭に戻るという手順を繰り返すために、繰り返しの1回目から制御変数の増分を実行してしまうためです。
この言語は全てをスタックに積む形式で行っているために、途中経過をどこかに保存しておくということができず、プログラムをシーケンシャルに実行していくために、このような結果になってしまっています。
(WHILE文やDO..WHILE文ではシーケンシャルに実行していって正しい結果が得られるような書式になっています。)
スタック言語ではFOR文のような、解析した順序とは異なる順序で実行しなければならない文は不可能なのでしょうか。それとも何か実現できるような手法があるのでしょうか。
(そういえば、中田先生のPL/0にもFOR文はありませんね、、、)
私の知識・経験不足のためにこれ以上は無理なようですので、言語の拡張はここまでにして、次は、中間言語に変換しているところを直接6809の命令語に変換するように変更して、6809機で動作するコードを生成するコンパイラに仕上げていこうと思います。
0 件のコメント:
コメントを投稿