跳过 ATLAST 中的输入流
Skip over input stream in ATLAST forth
我正在尝试在 ATLAST 中实现一种“条件 :
”,原因是我有一个文件需要多次 FLOAD
ed 来处理多个步骤我的程序流程(我本质上是在滥用第四个作为汇编程序,第 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 )
在其他一些地方很常见,用于从输入流中读取单个字符( 在 之外 ::
声明,因为它是 IMMEDIATE
) 在 ATLAST 中不存在,我能找到的唯一相关词是:
'
: 应该从输入流中读取一个词,然后压入它的编译地址
[']
:像'
但是从当前行(::
声明的内部)读取一个词
(LIT)
/(STRLIT)
:应该根据文档从输入流中读取文字,我只能让它们出现段错误,我认为它们仅供编译器内部使用(例如,如果编译器遇到数字文字,它将编译 (LIT)
字以使其将该数字压入堆栈)
也没有 WORD
或 PARSE
和其他一些一样。
如您所见,'
由于某种奇怪的原因实际上正在努力从输入流中获取一些东西,看起来 [']
未能捕获 ;
然后出错是因为它突然遇到不属于它的 ;
。
我怀疑它实际上 运行 ' [']
,即使它 应该 在输入流上工作,而不是直接行,我是显然在编译模式那里。
我做了一个 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
;
但由于非标准词,它可能无法正常工作。另一个问题是非冒号定义超出了范围。
或许,更好的解决方案是通过外部手段进行预处理。
ATLAST 似乎是一个原始的 Forth,它不允许您对源进行更复杂的处理。但一切都没有丢失!
例如,根据 ISO 标准的 Forth 实现将通过以下一项或多项轻松处理该问题:REQUIRE [IF] [THEN] [DEFINED] SRC >IN NAME WORD FIND
因为你有一个 Forth,你可以从另一个 Forth 窃取这些词并编译代码。
另一个可能有直接帮助的解决方案是在加载文件时以解释模式执行 EXIT。
你必须找出是否可以创建一个标志是否放弃输入源。那么定义可能会有所帮助
: ?abandon IF S" EXIT" EVALUATE THEN ;
S" FIVE" FOUND ?abandon
注意?abandon必须在解释模式下执行
我正在尝试在 ATLAST 中实现一种“条件 :
”,原因是我有一个文件需要多次 FLOAD
ed 来处理多个步骤我的程序流程(我本质上是在滥用第四个作为汇编程序,第 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 )
在其他一些地方很常见,用于从输入流中读取单个字符( 在 之外 ::
声明,因为它是 IMMEDIATE
) 在 ATLAST 中不存在,我能找到的唯一相关词是:
'
: 应该从输入流中读取一个词,然后压入它的编译地址[']
:像'
但是从当前行(::
声明的内部)读取一个词(LIT)
/(STRLIT)
:应该根据文档从输入流中读取文字,我只能让它们出现段错误,我认为它们仅供编译器内部使用(例如,如果编译器遇到数字文字,它将编译(LIT)
字以使其将该数字压入堆栈)
也没有 WORD
或 PARSE
和其他一些一样。
如您所见,'
由于某种奇怪的原因实际上正在努力从输入流中获取一些东西,看起来 [']
未能捕获 ;
然后出错是因为它突然遇到不属于它的 ;
。
我怀疑它实际上 运行 ' [']
,即使它 应该 在输入流上工作,而不是直接行,我是显然在编译模式那里。
我做了一个 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
;
但由于非标准词,它可能无法正常工作。另一个问题是非冒号定义超出了范围。
或许,更好的解决方案是通过外部手段进行预处理。
ATLAST 似乎是一个原始的 Forth,它不允许您对源进行更复杂的处理。但一切都没有丢失! 例如,根据 ISO 标准的 Forth 实现将通过以下一项或多项轻松处理该问题:REQUIRE [IF] [THEN] [DEFINED] SRC >IN NAME WORD FIND 因为你有一个 Forth,你可以从另一个 Forth 窃取这些词并编译代码。
另一个可能有直接帮助的解决方案是在加载文件时以解释模式执行 EXIT。 你必须找出是否可以创建一个标志是否放弃输入源。那么定义可能会有所帮助
: ?abandon IF S" EXIT" EVALUATE THEN ;
S" FIVE" FOUND ?abandon
注意?abandon必须在解释模式下执行