Factor入門第5回。
今回は"parsing words"について調べます。

通常、Factorのwordは、パーズされ解釈され、即スタックに影響を与えます。数値リテラルならスタックに積まれるし、wordなら実行されます。多くの場合、スペースで区切られたひとつのwordは、スタックのみに依存して動作します。

スタック系言語の、わたしに認識できる歳代の利点は、このように「文法構造」がほぼないので、文法部分にあたまを使わずに読み書きできる、ということです。文法構造を理解する必要もない。

でも一部に、その場でスタックとのやりとりをしない動作をするものがあります。たとえば、quotationのはじまりを示す"["。

( scratchpad ) [

このように、Factorの対話画面(listenerといいます、って入門第5回で紹介するのは遅すぎですね)で"["を入力して、リターンを押しても何も起きません。( scratch )のプロンプトすら出ません。

( scratchpad ) [
2 4 *

2 4 * と入力すると、普通は2がつまれ4がつまれ、そしてそれに乗算が適用されて、スタックに8がつまれますが、やはり何も起きません。

( scratchpad ) [
2 4 *
]
--- Data stack:
[ 2 4 * ]
( scratchpad )

"]" で閉じるとはじめてプロンプトが戻り、そしてquotation "[ 2 4 * ]"がスタックにつまれます。明らかに普通のwordとは動作が違います。

word "["は、Factorではふつうのwordではなく、"parsing word"として定義されています。Factorのドキュメントの解説を参照してみましょう。

The Factor parser follows a simple recursive-descent design. The parser reads successive tokens from the input; if the token identifies a number or an ordinary word, it is added to an accumulator vector. Otherwise if the token identifies a parsing word, the parsing word is executed immediately.

ふつうのwordでも、先にわたしが書いた「即スタックに影響を与えます」というのに対応するのは"added to an accumulator vector"だそうで、accumulator vectorというものに初遭遇です。さらに、parsing wordの場合は「即実行されます」と書かれています。即実行なのか。実例が出ているので試してみます。

( scratchpad ) : hello "hello world." print ; parsing  #! まず実例
( scratchpad ) hello
hello world.
( scratchpad ) : hello2 "hello world." print ; #! parsingじゃない版
( scratchpad ) hello2 #!結果同じじゃん
hello world.
( scratchpad ) : hello3 "hello world." ; parsing #!スタックに文字列を残してみよう(parsing wordでは違反のはず)
( scratchpad ) hello3 #! なんじゃこりゃ
--- Data stack:
T{ decoder f ~input-port~ utf8 f }
104
101
108
108
111
32
119
111
114
108
100
46

parsing word, 気軽に始めたのですが、けっこう手強そうです。つづく。