1L_a 编程语言 / 语言
1L_a 是一种二维编程语言,这意味着代码并不一定按线性顺序执行。因此,当程序启动时,一个指令指针(简称 IP)会从第一行的第一个字符开始生成,并向下移动。它将每一步前进并执行它遇到的命令,除非有东西改变了它的方向。
有两个指令:GO 和 STOP。GO 指令根据 IP 的方向执行不同的操作。(我们将在介绍数组后讨论这些指令。)解释器将记住程序的第一个字符,每次它遇到该字符时,GO 指令就会执行。其他所有内容都会执行 STOP。我更喜欢使用空格作为 GO 触发字符,因为这样可以轻松地通过观察程序来跟踪 IP 的移动。
1L_a 是基于数组的,这意味着您可以操作内置数组。(这里,数组是布尔类型的。)数组中的前三个元素,即 TL0、TL1 和 TL2,用于 I/O,我们将在稍后讨论。
有一个数据指针(不要与 IP 混淆),简称 DP,最初指向 TL2。所有操作都基于数据指针。您可以移动数据指针,或读取和切换它指向的位。
您可能注意到我说的是读取和切换,而不是读取和写入。这是因为 1L_a 没有直接设置一位的方法。要将一位设置为 0,您可以编写以下代码:
- 读取该位。
- 如果该位为 1,则切换它。
TL0 是数组中的第一个元素。如果它被切换,程序将从 STDIN 读取输入或将输出写入 STDOUT,这取决于 TL1 和 TL2 的值。这是在这门语言中执行 I/O 的唯一方法。
TL1 是 I/O 开关。当您切换 TL0 时,解释器将检查 TL1,如果 TL0 为 0,程序将读取一位输入,并将它的值存储在 TL2 中;如果 TL1 为 1,程序将输出一位。
TL2 用于注册要输出的位或新输入的位。它更靠近普通位,因此当您要输出一位时,您可以将它从普通位移动到 TL2,而无需经过其他特殊寄存器(在 1L_a 中,移动您的 DP 非常棘手),并且当您输入一位时,您可以读取该位在“回家”的路上。
如前所述,1L_a 中有两个指令:GO 和 STOP。以下是一个表格显示了它们执行的操作
指令 | IP 方向 | 操作 |
---|---|---|
GO | 向上 | DP 向右移动一位。 |
GO | 向左 | DP 向左移动一位,然后切换 DP 指向的位。(注意:切换的位在新的位置,而不是旧的位置。) |
GO | 向下 | 不执行任何操作。 |
GO | 向右 | 不执行任何操作 |
STOP | 任意 | 向后移动一个单元格(这里,“向后”是指与 IP 方向相反的方向),并读取指向的位。如果读取到 0,IP 将逆时针旋转,如果读取到 1,IP 将顺时针旋转。 |
与您可能想象的不同,在这样的语言中,“不执行任何操作”操作非常有用,因为它可以在不产生任何“副作用”(例如修改数组)的情况下转移 IP。
这种语言是基于位的,因此它以位而不是字符输出。但是,在许多实现中,这些位存储在一个“缓冲区”中,当缓冲区中已经有 8 位时,这些位将作为 ASCII 代码输出,并且它们将被清除。对于输入,也会发生类似的事情。当您输入一个字符时,程序会自动将其分解为 8 位,然后将其存储在一个“输入缓冲区”中。当程序想要读取一位时,它会读取缓冲区中的一位,并且该位将被删除。