はじめに
この文書では、Lua で書かれた Forth 系言語 F/L の標準辞書のワードについて説明します。F/L の標準辞書には以下に示す 4 つの巻があります。それぞれ順次説明していきます。
- object 辞書
- string 辞書
- list 辞書
- file 辞書
object 辞書
この辞書には、システムに関するワードや、即時実行特性を持つワードが格納されています。
HotStart
F/L インタプリタをホットスタートします。ユーザーが定義した辞書などはクリアされません。
/* および */
コメントを定義します。ネストすることも可能です。
"sq" := /* /* n -- n */ 2 乗した値をスタックに積みます */
dup * ;
( と )
リスト定義を開始します。ワード ) と連携することでリスト定義に使用します。作成されたリストはスタックに積まれます。
[ と ]
無名ワードブロックを定義します。[ 〜 ] は ( 〜 ) >noname と同じです。作成された無名ワードブロックはスタックに積まれます。
{ と }
対話環境用の無名ブロックを定義します。このワードを用いた無名ブロックはスタックに積むことはできません。
_[ および ]_
Forth における [ と ] と同じです。コンパイルモードで使用します。_[ で一時的にインタプリタモードに入り、]_ でまたコンパイルモードに戻ります。
compile
データスタックの TOS にある文字列をワードとして解釈し、現在定義中のワード等にコンパイルします。
>compile
データスタックの TOS にある値(文字列とは限らない)を、現在定義中のワード等にコンパイルします。
;
ワード定義を終了します。
immediate
Forth と同じです。直前に定義したワードに即時実行特性を与えます。
writable
直前に定義したワードに対し、上書可能特性を与えます。
@word
データスタックの TOS にある文字列と同名のワードをデータスタックに積みます。
execute
データスタックの TOS にあるワードを実行します。
例:
F/L> 2 3 "*" @word execute .
6 ok.
do
ローカル変数の環境を作ります
end
do で作成したローカル変数の環境を破棄します。
!var
(n s --- ) として、データスタックの TOS にある文字列をローカル変数とし、データスタックの 2 番目にある値を、そのローカル変数に代入します。
@var
(s -- n) として、データスタックの TOS にある文字列ををローカル変数とし、そのローカル変数に格納されている値をデータスタックにプッシュします。
例:
F/L> "mySwap" := do
"tos" !var "second" !var
"tos" @var "second" @var
end ;
ok.
F/L> 1 2 m
if, else, then
条件分岐に関する制御ワードです。使い方は Forth と同じです。詳しくは 「F/L でのプログラミング」を参照して下さい。
whle, loop および foreach, next
こちらはループに関するワードです。使い方は Forth と同じです。詳しくは 「F/L でのプログラミング」を参照して下さい。
from-to
データスタックの上から 2 番目から TOS までの値を +1 づつ変化させるイテレータを用意します。
使用例:
F/L> 1 10 { from-to foreach . next }
1 2 3 4 5 6 7 8 9 10 ok.
lines
データスタックの TOS にあるファイルハンドルから一行づつ読み込むイテレータを用意します。
load
データスタックの TOS にあるファイルを読み込み、そこに書かれている内容を実行します。
true
データスタックに真の値(true)をプッシュします。
false
データスタックに偽の値(falase)をプッシュします。
type
データスタックの TOS の型を表示します。
drop
データスタックの TOS を捨てます(Forth と同じです)。
dup
データスタックの TOS を複製します(Forth と同じです)。
F/L> "square" := dup * ;
ok.
F/L> 5 square .
25 ok.
swap
データスタックの TOS とその下の値(上から 2 番目の値)を入れ替えます(Forth と同じです)。
rot
データスタックの上から 3 つの要素を回転させます。( x1 x2 x3 -- x2 x3 x1 ) なる操作を行います(Forth と同じです)。
depth
データスタックに積まれている値の数をデータスタックにプッシュします(forth と同じです)。
>R
データスタックから値をポップし、その値をリターンスタックにプッシュします(Forth と同じです)。
R>
リターンスタックから値をポップし、その値をデータスタックにプッシュします(Forth と同じです)。
>E
データスタックから値をポップし、その値を環境スタックにプッシュします。
E>
環境スタックから値をポップし、その値をデータスタックにプッシュします。
E+>
環境スタックの TOS をデータスタックにプッシュします。>E dup >E と同様の動作をします。
+, -, *, /, %, //
各種四則演算用ワードです。データスタックの second と tos に対し実行されます。計算順序は演算子を op とすると、second op tos となります。
// はコメントではなく、Lua の演算子です。データスタックの second と tos に対し、Lua で second // tos を計算した値をデータスタックにプッシュします。
F/L> 3 5 - .
-2 ok.
F/L> 20 6 // .
3 ok.
F/L> 20 6 / .
3.3333333333333 ok.
>, <, >=, <=, =
比較演算用ワードです。データスタックの second と tos に対し実行されます。比較演算子を op で表すと、second op tos の結果をデータスタックにプッシュします。
F/L> 5 2 > .
true ok.
F/L> 5 3 = .
false ok.
F/L> 5 5 = .
true ok.
. (ドット)
データスタックの tos にある値を表示します。以下の boolean 辞書などにも同名のワードが存在しますが、tos の型に対する辞書に同名のワードがある場合、そちらが優先されます。
cr
改行を出力します。
boolean 辞書
and, or ,xor
データスタックの上から 2 つの bool 型に対し、それぞれ、論理積、論理和、排他的論理和を計算し、その値をデータスタックにプッシュします。対象となる値が bool 型でない場合はエラーとなります。
F/L> true true xor .
false ok.
not
データスタックの TOS をポップし、その値の否定をデータスタックにプッシュします。
.
データスタックの TOS をポップし、その値(ブール型)を表示します。
string 辞書
:=
「新たに定義するワード名の文字列 := ワード本体 ;」 という形で使用し、新たなワードを定義します。
assign
(B s -- ) ただし B は無名ワードブロックを表すものとします。
TOS で与えられた文字列を、スタックの 2 番目に積まれている無名ワードブロックの名前として割り当てます。以下の例では、PI という定数を定義します。
F/L> F/L> ( 3.14 ) >noname "PI" assign
ok.
F/L> PI .
3.14 ok.
eval
TOS にある文字列をプログラムとして実行します。
F/L> "2 3 * ." eval
6 ok.
>writable
TOS にある文字列と同名のワードに上書可能属性を与えます。
F/L> "PI" := 3 ;
ok.
F/L> 3.14 "PI" set!
F/L ERROR:can not overwrite. the word 'PI' is protected.
F/L> "PI" >writable
ok.
F/L> 3.14 "PI" set!
ok.
F/L> PI .
3.14 ok.
protect
>writable とは逆に、TOS にある文字列と同名のワードに上書禁止属性を与えます。
F/L> 3 "PI" set!
ok.
F/L> PI .
3 ok.
F/L> 3.14 "PI" set!
ok.
F/L> PI .
3.14 ok.
F/L> "PI" protect
ok.
F/L> 4 "PI" set!
F/L ERROR:can not overwrite. the word 'PI' is protected.
fopen
(s -- F) ただし F はファイルポインタを表すとします。
TOS で与えられる名前のファイルをオープンし、そのファイルポインタをスタックにプッシュします。関連ワード:read
list
デバッグ用のワードです。データとしてのリストを示しては いません ので注意して下さい。Basic で言うところのリストコマンドです。
TOS で与えられた文字列をワード名として、そのワードを逆コンパイルして表示します。逆コンパイルするので、ユーザー定義ワードにしか対応していません。
> "sq" := dup * ;
stdin:1: unexpected symbol near '"sq"'
> dofile "FL.lua"
--- F/L zero by Koji Iigura (build 2017.mm.dd)---
F/L> "sq" := dup * ;
ok.
F/L> 5 sq .
25 ok.
F/L> "sq" list
--- list of 'sq'---
1 dup
2 *
3 semis
ok.
list 辞書
length
データスタックよりリストをポップし、そのリストのトップレベルの長さ(要素数)をデータスタックにプッシュします。
F/L> ( 2 3 5 7 11 ) length .
5 ok.
F/L> ( 1 2 ( "apple" "orange" ) 3 ) length .
4 ok.
>noname
データスタックの TOS にあるリストを無名ワードブロックに変換します。変換された無名ワードブロックは、ワード execute で実行できます。
F/L> ( 2 3 * . "BY List" . ) >noname execute
6 BY List ok.
file 辞書
この辞書は、文字列に対するワード fopen で作成されたファイルハンドルに対するワードを格納する辞書です。
close
データスタックの TOS にあるファイルハンドルをクローズします。
read
データスタックの TOS にあるファイルハンドルから 1 行読み込み、データスタックにプッシュします。なお、このワードを実行するとファイルハンドルはポップされてしまいますので、実際には dup してから使用することになると思います(そうしないと close できない)。
おわり
以上で、現時点での F/L における標準辞書の説明は終わりです。厳密には、ここに書かれていないワードも存在します(内部用、もしくは、まだ使用方法が確定していないもの等)。標準辞書は defaultDict ディレクトリにあるファイルにより定義されていますので、興味の有る方はご覧になって下さい。