我正在使用 Clojure 实现FALSE解释器,我对子例程需要多少参数感到困惑,例如
[1+]
接受一个参数。另一方面:
["hello"]
采用零参数
怎么讲?
在浏览了语言规范之后,这就是我解决问题的方法。
拿代码3[1+]!2
。我也|
用作堆栈上的分隔符。
首先是解析成命令。这个简单的程序将产生以下 3 个命令:
1. push 3
2. push [1+]
3. call
4. push 2
实现这一点的最简单方法(至少是我能想到的最简单的 atm 方法)是为堆栈设置一个数组/列表/堆栈结构,为命令设置一个数组/列表/队列结构。我将尝试说明执行以下命令将如何导致所述两个数组发生变化。
Cmd Stack
[push(3)|push([1+])|call|push(2)] []
[push([1+])|call|push(2)] [3]
[call|push(2)] [3|[1+]]
[push(1)|+|push(2)] [3]
[+|push(2)] [3|1]
[push(2)] [4]
[] [4|2]
这里call
的作用是(期望程序有效):
1. Pop the topmost stack-entry. (silently assume it to be a subrutine)
2. Parse the subrutine into a command array.
3. Iject said command array at the head of the executing command-array.
4. Continue execution until the command-array is empty.
有趣的是,您不能将 subrutines 视为 OOP 语言或类似语言中的正常函数。例如想象一下这个程序[1 2 3 4]!
。subrutine 会在消耗 0 时“返回”4 个值。