そのままなら簡単です(長文)



[ このメッセージへの返事 ] [ 返事を書く ] [ home.html ]



投稿者: INNO @ INS201.sendai.dti.ne.jp on 97/10/29 00:46:41

In Reply to: BASICからC言語に変換するのは難しいです.

posted by 豊野 @ ee07.ee.nagano-nct.ac.jp on 97/10/28 13:09:10

まず単純に変換する場合。

変数:
BASICの変数は使用された時生成され、なお且つスコープがグローバル
(プログラム中で常にユニークであり、何処からでも参照・変更可能)
なので、実数は全てグローバルでdoubleにすれば良いという事になります。
問題なのは、$変数(文字列)です。
Cではこれをstaticに出来ないので、取り敢えずchar*で宣言しておき、
使用されているところでC言語ならmallocで必要分の容量を取得します。
その都度メモリ容量を確保しなければならないので、
最大長で予め宣言するという方法もあります。
(最大長ってありましたよね?たしか)

10 A=10:B=A+1
20 C$="A"
------------↓
double a;
double b;
void main()
{
L10: a=10;
L20: b=a+1;


命令:
予約語の制御命令(IF,FOR〜NEXT等)はgotoを含め全てC言語にあります。
ラベル宣言も使えますので、行番号を全てラベルに置き換えれば直ぐできます。
GOSUBで飛ぶ部分はスタックが無いと制御出来ないので、
関数化するかその場にRETURN命令が出てくるまで展開するしか無いでしょう。

100 GOSUB 500



200 GOSUB 520



500 A=B+C
510 PRINT A
520 A=A+1
530 RETURN
-----------------↓
double a,b,c;

void main()
{



l100: gosub500();



l200: gosub520();



}
void gosub500() //GOTOで飛んでくる場合は
{ //BASICでもエラーになるのでラベルを置かない
a=b+c;
printf("%d\n",a );
gosub520();
return;
}
void gosub520()
{
a++;
return;
}


標準関数:
主だったものはC言語にあります。
LPRINTとかSCREEN等の機種依存する部分は、
その動作環境に従った形にして下さい、DOS環境なら割り込みで全て出来ます。


さらにオプチマイズまで考えた場合。
冗長な部分(同じ命令の羅列)を抜き出せば良いのですが、
条件があります。
GOTOで途中に割り込む箇所が無いのを条件とし、
返り値/引数の無い関数に置き換えて、呼ぶ形に出来ます。
この辺のオプチマイゼーションは、
コンパイラにサイズ優先でコンパイルさせた場合の動作と同じです。

結果的にはBASICコンパイラと同じ事をする訳ですね。
処理としては、まずクロスリファレンスを作成します。
これで変数部は構築できますし、
行番号についても参照されている箇所を探し、関数化する場合はそれを定義し、
まず関数を創ってしまいます。
更にその中でGUSUBを使っている場合、再帰して変換かけるロジックにしましょう。

もしツールをお持ちなら、
BASICコンパイラにかけたものを逆コンパイルでC言語に落とせば、
ヒントになると思います。

頑張ってね