delphi - 使用FPC : Recursive data structures编写Scheme解释器

标签 delphi scheme pascal freepascal sicp

本质上,这是一个关于Pascal(FPC)中的递归数据结构的问题。由于我想实现一个像 SICP 第 4 章所示的计划解释器,这个问题也可能与计划者相关。 :)

S-表达式应表示为标记数据。到目前为止,我已经构建了一个变体记录,它代表数字和对。希望代码是可读且不言自明的:

program scheme;

type
   TTag = (ScmFixnum, ScmPair);
   PScmObject = ^TScmObject;
   TScmObject = record
      case ScmObjectTag: TTag of
         ScmFixnum: (ScmObjectFixnum: integer);
         ScmPair: (ScmObjectCar, ScmObjectCdr: PScmObject);
      end;

var
   Test1: TScmObject;
   Test2: TScmObject;
   Test3: TScmObject;

function MakeFixnum(x: integer): TScmObject;
var
   fixnum: TScmObject;
begin
   fixnum.ScmObjectTag := ScmFixnum;
   fixnum.ScmObjectFixnum := x;
   MakeFixnum := fixnum;
end;

function MakePair(car, cdr: PScmObject): TScmObject;
var
   pair: TScmObject;
begin
   pair.ScmObjectTag := ScmPair;
   pair.ScmObjectCar := car;
   pair.ScmObjectCdr := cdr;
   MakePair := pair;
end;

begin
   Test1 := MakeFixnum(7);
   writeln('Test1, Tag: ', Test1.ScmObjectTag,
           ', Content: ', Test1.ScmObjectFixnum);
   Test2 := MakeFixnum(9);
   writeln('Test2, Tag: ', Test2.ScmObjectTag,
           ', Content: ', Test2.ScmObjectFixnum);
   Test3 := MakePair(Test1, Test2);
end.

但是,编译代码会产生如下错误:

$ fpc scheme.pas
(...)
Compiling scheme.pas
scheme.pas(43,34) Error: Incompatible type for arg no. 2: Got "TScmObject", expected "PScmObject"
scheme.pas(45) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted

很明显,MakePair函数中存在错误。但我还不明白我到底做错了什么。任何帮助表示赞赏。 :)

最佳答案

MakePair 函数定义如下:

function MakePair(car, cdr: PScmObject): TScmObject;

请注意,它接收两个 PScmObject 类型的指针。然后你可以这样调用它:

MakePair(Test1, Test2);

但是 Test1Test2 的类型为 TScmObject。所以实际传递的参数是不兼容的,就像编译器所说的那样。

您需要传递指向这些记录的指针:

MakePair(@Test1, @Test2);
<小时/>

从长远来看,您需要注意这些记录的生命周期。您需要在堆上进行分配,并且如果没有垃圾收集,我怀疑您将进入一个试图跟踪谁拥有记录的痛苦世界。也许您可以考虑使用接口(interface)引用计数来管理生命周期。

关于delphi - 使用FPC : Recursive data structures编写Scheme解释器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14164783/

相关文章:

c - C 中的 union 和范围变量

c++ - 帕斯卡的模数

algorithm - 二进制插入排序算法重复输出

Delphi FloatToStr - 为什么显示不同?

delphi - 如何检测单击和双击 TreeView 中的节点?

delphi - 如何将 Delphi ADOTable 过滤器应用于日期数据类型

delphi - 获取用于打开关联应用程序的文件的文件名

algorithm - 方案中的算法或数据结构书籍

scheme - 使用 let-values 而不是 let 有什么好处?

recursion - scheme::contract violation: 递归过程