frtm の上で cons や car/cdr 等のリスト処理を行うワードを作成し,局 所変数を持った新しい言語系を作られています.今のところはディレクトリが 表示されます.また,独自拡張された frtm のアーカイブも置かれています. 幾つかの機能は本家の frtm の方にも取り入れさせて頂く予定です.
FoRTh Modoki ver 1.4.3 Mar. 4, 2001. Copyright (C) 1999-2001 浪花 智英 (Tomohide Naniwa) naniwa@rbt.his.u-fukui.ac.jp 0. コンパイル □ UNIX でのコンパイル 必要があれば Makefile を変更してください.後は make だけで frtm ができ ます. I. はじめに このプログラムは FORTH を模擬したソフトですが,完全に FORTH を再現した ものではありません.コンパイラは持ちませんが,ユーザー定義ワードでは定 数やワードを定義時に解釈します. 式の解釈は逆ポーランド記法に従って行われます.if による条件分岐. do-while, for-loop などのループのための構造もあります.また,ワードを 組み合わせて新たなワードを作ることもできます. 現在のところ扱えるのは整数のみです.数字の入力は 10 進数,16 進数(頭に 0x を付ける),8 進数(頭に 0 を付ける)で行えます. frtm.h の中で各種スタックのサイズ等を定義しています.それぞれ, #define STMAX 500 ; 数値計算用スタック #define DICMAX 100 ; ユーザー定義ワードの最大数 #define CSMAX 1000 ; ユーザー定義ワードの本体の記憶領域 #define RSMAX 500 ; ユーザー定義ワード実行用スタック #define SSMAX 400 ; ループなどの入れ子用スタック #define MAX_NAME 8 ; ユーザー定義ワード名の最大文字数 #define LINE 100 ; 1行の最大文字数 となっています.適宜変更してください. II. 基本機能 □ 定義済ワード . 10 進表示 .h 16 進表示 .o 8 進表示 cr 改行 sp 空白 + 和 - 差 * 積 / 商 % 余り = 同値 < より小さい <= 以下 > より大きい >= 以上 ! 真偽反転 1+ 1 加算 1- 1 減算 0= 0 と同値 abs 絶対値 max 最大 min 最小 dup 複製 swap 交換 drop 除去 over スタックの2番目の複製 rot スタックの上位3つを回転し,3番目をトップへ rotr スタックの上位3つを回転し,トップを3番目へ ndup スタックの n 番目を複製 nrot スタックを回転し,n 番目をトップへ nrotr スタックを回転し,トップを n 番目へ ndrop スタックの上位 n 個を除去 copy スタックの上位 n 個を複製 SP 呼び出した時点のスタックの深さをスタックのトップに追加 minus 符合変換 spaces 複数個の空白 esc エスケープコード(0x1B)の出力 help 関数名一覧 quit 終了 □ 文字列に対する処理 ◇ 表示 echo (Hello_World) echo cr スタックには '0dlr' 'oW_o' 'lleH' と整数型にパックした文字列が入る.echo は文字列中に 0 が現れるまで順に 表示する.上記の例の最初の文字並びの 0 は数字の 0 で,文字の '0' では ない. 文字列中で \ (バックスラッシュ)によるコントロール・コードのエスケープ が可能である.利用可能な文字定数は '\n'(改行),'\t'(水平タブ), '\b'(バッ クスペース)と '\ddd' (ddd は8進数) である.ただし,8進数の文字定数で は最上位の数が 0 であることを仮定している.尚,これ以外の文字はそのま ま文字列中に追加される. ◇ 文字列の分解・結合 pack/unpack (Hello_World) unpack スタック上に置かれたパックされた文字列を1文字ずつに分解する.スタック には 0 'd' 'l' 'r' 'o' 'W' '_' 'o' 'l' 'l' 'e' 'H' と分解された整数が入る. pack unpack で1文字ずつに分解されたスタック上の整数を,再び echo で表示で きる文字列にパックする. III. プログラム構造 □ 条件分岐if endif if else endif 仕様 が 0 以外なら を実行. が 0 なら を実行. 制限 else ブロックは複数書ける. 例題 0 if 1 else 2 endif . cr □ do ループ do while 仕様 が 0 であれば終了.0 以外なら do に戻って繰り返し. 例題 1 do dup . cr 1 + dup 5 < while drop 1 do dup . sp 1 do dup . sp 1 + dup 5 < while cr drop 1 + dup 4 < while drop □ for ループ for loop for +loop 仕様 終了後 n2 + 1(またはn3) を実行し,n1 より小さければ for に戻っ て繰り返し. I リターンスタック上の n2 をスタックに追加する. 制限 n1, n2 は非負の数とする. 例題 5 0 for I . cr loop 10 0 for I . sp 5 1 for I . sp loop cr 2 +loop □ ワードの定義 : name ; 仕様 name を持つワードを作成する. 制限 do や for のループの中ではワードの登録はできない. ユーザー辞書は新しく定義されたものから順に検索するため,再帰が可能になっ ている.また,ワードを再定義しても古いワードの定義はそのまま残る. □ 例題 ・平均 : ave + 2 / ; 10 28 ave . cr ・階乗 [fact(1) = 1, fact(n) = n*fact(n-1)] : facti 1 swap 1+ 1 for I * loop ; : fact dup 1 = if else dup 1- fact * endif ; 10 facti . cr 10 fact . cr ・フィボナッチ数列 [fib(0) = 0, fib(1) = 1, fib(n) = fib(n-1) + fib(n-2)] : fib dup 0= if else dup 1 = if else dup 1- fib swap 2 - fib + endif endif ; 7 fib . cr : fibi dup 0= if else 0 1 rot 1 for swap over + loop swap drop endif ; 30 fibi . cr 20 0 for I fibi . sp loop cr ・ハノイの塔 : move1 (Move disk ) echo . swap ( from ) echo . ( to ) echo . cr ; : hanoi dup 1 = if move1 else 3 ndup 3 ndup + 6 - minus 4 ndup swap 3 ndup 1- hanoi 3 ndup 3 ndup 3 ndup move1 1- rotr swap over + 6 - minus swap rot hanoi endif ; 1 2 2 hanoi 1 2 4 hanoi ・N Queens : N 2 * 3 + ; : disp dup N ndup 0 for dup N ndup 0 for over I = if (Q ) echo else (. ) echo endif loop cr drop drop loop drop ; : check over 0 for 3 ndup 6 ndup = if drop 0 else 3 ndup 6 ndup - abs 3 ndup 6 ndup - = if drop 0 else 1 = endif endif 5 nrot 5 nrot drop drop loop rotr drop drop ; : nq dup N ndup 0 for I over 1+ dup N 1- copy 1 check if dup N ndup over 1+ = if dup N copy disp cr else nq endif endif drop drop loop ; : queens dup 0 for I 0 nq drop drop loop drop ; 4 queens [puzzle というワードを使って上記のハノイの塔と N Queens パズルを解く ワードをユーザー辞書に追加することができます.] □ 辞書コマンド help システム定義ワード,ユーザー定義ワードの一覧を表示. forget という名前を持つワード以降にユーザーが定義したワードを全部消去する. fgall ユーザーが定義したワードを全て消去する. def という名前を持つワードの定義を,再評価可能な形式で表示する. load スタックから文字列を取りだし,その名前を持つファイルの内容を読み込み評 価する. □ ワードの探索 ワードはシステム辞書,ユーザー辞書の順に探索される.ユーザー辞書は新し く登録されたものから検索される. IV. 変数 □ 変数の定義 var name 仕様 name という変数を作成する.変数は辞書に登録される.見かけ上はユーザー定義 ワードの形態を取る.name を評価すると,ユーザー辞書のインデックスがスタッ クに保存される. 制限 変数の宣言は実行可能状態でのみ可能.ワードの定義中や,do や for のループの 中では変数の定義は出来ない. □ 値の呼出し @ 仕様 スタックから辞書のインデックスを取りだし,その番地に含まれる数値をスタッ クに置く. □ 値の代入 $ 仕様 スタックから辞書のインデックスと数値を取りだし,その番地に登録する. □ 例題 var x x @ . cr 10 x $ x @ . cr : test x @ . cr ; test V. グラフィクス UNIX 上でコンパイルした場合は X11 環境で,EOTA でコンパイルした場合 は vga モードでのグラフィクスが利用できます. □ ワード gm グラフィクス・モードへ tm テキスト・モードへ x y moveto (x, y) へ移動 x y lineto 現在位置から (x, y) まで直線描画 x y rmoveto 現在位置から (x, y) だけ移動 x y rlineto 現在位置から (x, y) だけ直線描画 x y w h rect 矩形領域の描画 x y w h rectf 矩形領域の塗り潰し x y point 点の描画 x y w h ellips 楕円の描画 x y w h ellipsf 楕円の塗り潰し c setcolor 色設定(0: 黒 〜青緑水赤紫黄〜 15: 白) c setbgc 文字列の背景色の指定 n setfont フォントの指定 (0: a14, 1: 7x14bold) x y s drawstr (x, y) に文字列 s を表示(背景はそのまま) x y s drawistr (x, y) に文字列 s を表示(背景も塗り潰す) cls 画面消去 □ 例題 ・ 色を変えながら矩形領域を塗り潰す. : boxes 16 0 for I setcolor 10 20 I * + dup 100 100 rectf loop ; gm boxes tm ・再帰図形(Koch 曲線) : pre 5 copy drop ; : genx 3 ndup 6 ndup - * minus 100 / swap 4 ndup 7 ndup - * 100 / + 5 ndup + 5 nrotr 4 ndrop ; : geny swap 3 ndup 6 ndup - * 100 / swap 4 ndup 7 ndup - * 100 / + 4 ndup + 5 nrotr 4 ndrop ; : gen 6 copy genx 7 nrotr geny ; : keep 7 nrotr 7 nrotr pre ; : post 9 nrot 9 nrot 4 nrot 4 nrot 5 ndup 1- ; : line moveto lineto ; : koch dup 0= if drop line else pre 0 0 gen keep 33 0 gen post koch pre 33 0 gen keep 50 -28 gen post koch pre 50 -28 gen keep 66 0 gen post koch pre 66 0 gen keep 100 0 gen post koch 5 ndrop endif ; gm 50 250 600 250 4 koch tm : kochs 10 setcolor 89 440 551 440 4 koch 11 setcolor 551 440 320 40 4 koch 12 setcolor 320 40 89 440 4 koch ; gm kochs tm [graphics というワードを使って,boxes と Koch 曲線を描くワードをユー ザー辞書に追加することができます] VI. ソースコードについて. バージョン 1.3.0 以降の FoRTh Modoki (frtm) は GNU General Public License に従うものとします. コメント等がいただければはげみになります. --- (putprop '浪花 智英 'affiliation '(福井大学工学部知能システム工学科) 'e-mail '(naniwa@rbt.his.u-fukui.ac.jp) 'URL '(http://www.rbt.his.u-fukui.ac.jp/~naniwa/))