向前跳过 ATLAST 中的输入流

问题描述

我正在尝试在 ATLAST 中实现一种“有条件的 :”,原因是我有一个文件可以多次FLOAD处理我的多个步骤程序流程(我实际上是在滥用第四个作为汇编程序,步骤 1 对引用进行第一次解析等。在步骤 2 中,指令字实际上发出字节)。

所以当在那个文件中声明“宏”的词时,它在步骤 2 中出错,因为它们已经在步骤 1 中声明了,但我也不能只 FORGET 它们,因为那样会忘记所有来的之后,比如我刚刚在步骤 1 中收集的参考

所以本质上我需要一个只在第 1 步运行的“:”,我的想法是这样的:

VARIABLE STAGE

: ::
  STAGE @ 0 = IF
    [COMPILE] : ( be a word declaration )
  EXIT
  THEN
  BEGIN    ( eat the disabled declaration )
    '      ( get the address of the next word )
    ['] ;  ( get the address of semicolon )
    =      ( loop until they are equal )
  UNTIL
; IMMEDIATE

:: FIVE 5 ; ( declares as expected )

FIVE .      ( prints 5 )

1 STAGE !   ( up to here everything's fine )

:: FIVE 6 ; ( is supposed to do nothing,but errors out )

FIVE .      ( is supposed to print 5 again )

被追踪的错误信息(从1 STAGE !开始):

Trace: ! 
Trace: :: 
Trace: STAGE 
Trace: @ 
Trace: (LIT) 0 
Trace: = 
Trace: ?BRANCH 
Trace: ' 
Trace: (LIT) 94721509587192 
Trace: = 
Trace: ?BRANCH 
Trace: ' 
Word not specified when expected.

Trace: ; 
Compiler word outside deFinition.
Walkback:
   ;

KEY ( -- ch ) 与其他一些常见的用于从输入流中读取单个字符一样(outside :: 声明,因为它是 IMMEDIATE )不t 存在于 ATLAST 中,我能找到的唯一相关词是:

  • '应该从输入流中读取一个单词,然后推送它的编译地址
  • [']:类似于 ',但从当前行(:: 声明的内部)读取一个单词
  • (LIT)/(STRLIT)应该根据文档从输入流中读取文字,我只能让它们出现段错误,我认为它们是为了仅供编译器内部使用(例如,如果编译器遇到数字文字,它将编译 (LIT) 字以使其将该数字压入堆栈)

也没有像其他一些地方那样的 WORDPARSE

如您所见,由于某种奇怪的原因,' 实际上正在努力从输入流中获取某些东西,而且看起来 ['] 未能捕获 ;,然后出错因为它突然遇到了一个不属于它的 ;

我怀疑它实际上运行了 ' ['],即使它应该在输入流上工作,而不是直接行,而且我显然在那里处于编译模式。

我做了一个带有条件声明变量的 similar thing,在那里很容易只 [COMPILE] ' DROP 跳过一个单词(将 RES x 变成 ' x DROP),但在这里我很确定我实际上无法编译这些指令,因为我无法在声明之外发出循环。除非有人知道如何以某种方式编译类似的代码,以递归方式摆脱所有内容,直到 ;

解决方法

问题是 ' 找不到数字。一个可能的解决方案是为定义使用一个特殊的虚拟名称,而不是跳过它:

: :: 
  STAGE @ 0 = IF : EXIT THEN
  ' DROP \ this xt isn't needed
  " : _dummy" EVALUATE ( -- n ) DROP
;

或者每次都使用一个新名称:

: :: 
  STAGE @ 0 = IF : EXIT THEN
  ' >NAME @ \ ( s1 ) \ should be checked
  ": _dummy_" DUP >R S+
  R> EVALUATE ( -- n ) DROP
;

但由于非标准词,它可能不起作用。另一个问题是非冒号定义超出了范围。

也许更好的解决方案是通过外部方式进行预处理。