歴史家である私にとって、FPC で Scheme インタープリターを書くことは、すでに最初の段階にあり、深刻な作業であることがわかりました。:) 私は、C でそれを行う方法を示したPeter Michaux のブログをフォローしています (Pascal に役立つ可能性があるAdaへの翻訳もあります)。
Michaux の作品 (v 0.1) からの C の次の 2 つの関数を考えてみましょう。
object *alloc_object(void) {
object *obj;
obj = malloc(sizeof(object));
if (obj == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
return obj;
}
object *make_fixnum(long value) {
object *obj;
obj = alloc_object();
obj->type = FIXNUM;
obj->data.fixnum.value = value;
return obj;
}
私が理解している限り (C の基本的な読み取り知識)、コンストラクターmake_fixnum
は構造体 (fixnum 型のタグ付きデータ) へのポインターを返します。構築されたオブジェクトの場合、メモリを割り当てる必要があります(昨日のポイントについて@David Heffernanに感謝します)。
これは、これまでの FPC への私の翻訳であり、エラーなしでコンパイルされます。
program scheme;
type
TTag = (ScmFixnum);
PScmObject = ^TScmObject;
TScmObject = record
case ScmObjectTag: TTag of
ScmFixnum: (ScmObjectFixnum: integer);
end;
var Test: PScmObject = nil;
procedure AllocateObject(x: PScmObject);
begin
new(x);
end;
function MakeFixnum(x: integer): PScmObject;
var
fixnum: PScmObject = nil;
begin
AllocateObject(fixnum);
fixnum^.ScmObjectTag := ScmFixnum;
fixnum^.ScmObjectFixnum := x;
MakeFixnum := fixnum;
end;
begin
Test := MakeFixnum(1);
writeln(Test^.ScmObjectTag);
writeln(Test^.ScmObjectFixnum);
end.
でも...:
$ ./test
Runtime error 216 at $080480DD
$080480DD
$08048117
$08063873
ポインターの使用方法と参照方法に重大な欠陥があると思われます。
このポインタとメモリがどのように機能するかを理解するのを手伝ってくれた人に感謝します (FAQ や論文などへの参照も大歓迎です)。