ソースコードを読み込む
現在のところ、プログラムを実行するには、プログラム配列progにコード化されたプログラムを直接書かないといけない。 「えーと、+のコードは-2っと」なんてやってられないので、外部ファイルから読み込むようにする。 行うことは、
指定されたファイルを解析し、内部コードに変換してプログラム配列progに入れていく
処理内容は、次のようになる。
- ファイルからトークンを得る(空白で区切られた文字列がトークン)
- トークンが"+"なら、対応するコードCODE_PLUSをprogに埋め込む
- トークンが"."なら、対応するコードCODE_PRINTをprogに埋め込む
- トークンが数字なら、対応するコードCODE_PUSHと、その数値をprogに埋め込む
- EOFまで繰り返す
まず、main()を引数からファイル名を得られるようにする。
int main(void)
を
int main(int argc, char *argv[])
に変更する。 ファイル名は、argv[1]に格納されている。
Forthのプログラムを解析する関数parse()を作る。 引数としてファイル名をとる。
void parse(char *fname)
parse()内でget_token()を呼び出すことで、トークンを得る。
void get_token(FILE * fp, char *token) { int c; int j = 0; token[0] = '\x0'; c = fgetc(fp); while (c != ' ' && c != '\n' && !feof(fp)) { token[j] = c; j++; c = fgetc(fp); } token[j] = '\x0'; }
ファイルから1文字ずつ取っていき、空白または改行が見つかると、そこまでの文字列をトークンとして返す。
得たトークンをもとに、parse()は対応するコードをプログラム配列progに埋め込んでいく。
get_token(fp, token); while (token[0] != '\x0' || !feof(fp)) { if (strcmp(token, "+") == 0) { prog[idx] = CODE_PLUS; idx++; } else if (strcmp(token, ".") == 0) { prog[idx] = CODE_PRINT; idx++; } else if (isnumber(token)) { prog[idx] = CODE_PUSH; prog[idx + 1] = atoi(token); idx += 2; } get_token(fp, token); } prog[idx] = CODE_END;
さて、実行してみる。ファイルtest1の中身は"4 5 + ."である。
$ ./a.out testfile/test1 9
完成した。 ソースコード
moiforth-0.2.tar.gz
moiforth-0.2.zip