| フォース | |
|---|---|
| パラダイム | 連結型(スタックベース)、手続き型、反射型 |
| デザイン : | チャールズ・H・ムーア |
| 初 登場 | 1970年 (1970年) |
| タイピングの規律 | 型なし |
| ファイル名拡張子 | .fs、.fth、.4th、.f、.forth |
| Webサイト | forth-standard.org |
| 主な実装例 | |
| SwiftForth(Forth, Inc.)、Gforth(GNUプロジェクト)、VFX Forth(MicroProcessor Engineering) | |
| 影響を受けた | |
| ビットコインスクリプト、ファクター、ジョイ、RPL、レボル、ストイック | |
Forth は、Charles H. "Chuck" Mooreによって設計され、1970 年に他のプログラマーによって初めて使用されたスタック指向プログラミング言語および対話型統合開発環境です。頭字語ではありませんが、初期の頃はFORTHとすべて大文字で表記されることがよくありました。Mooreが作成したものではない FORTH-79 および FORTH-83 実装が事実上の標準となり、1994 年に ANS Forth として言語の公式技術標準が発行されました。ANS Forth の前後には、Forth の派生版が数多く存在しました。フリーでオープンソースのソフトウェアであるGforth実装は、商用サポートのあるシステムと同様に、現在も活発にメンテナンスされています。
Forthは通常、コンパイラと統合コマンドシェルを組み合わせたもので、ユーザーはワードと呼ばれるサブルーチンを介して対話します。[ a ]
ワードは、プログラム全体を再コンパイルしたり再起動したりすることなく、定義、テスト、再定義、デバッグできます。変数、演算子、制御フローなど、すべての構文要素はワードとして定義されます。スタックを使用してワード間でパラメータを渡すため、逆ポーランド記法スタイルになります。
Forthの歴史の大部分において、標準的な手法はスレッドコードにコンパイルすることであり、これはバイトコードよりも高速に解釈できる。Forthの初期の利点の1つはサイズだった。コンパイラ、エディタ、ユーザープログラムを含む開発環境全体が、8ビットシステムや同様の制限のあるシステムのメモリに収まった。現在ではスペースの制約を受けず、他の言語コンパイラと同様に最適化されたマシンコードを生成する最新の実装が存在する。
基本的な Forth システムの作成が比較的容易であることから、多くの個人用および独自のバリアントが生まれており、例えば、Electronic Artsの1986 年のベストセラービデオゲームStarflight を実装するために使用されたカスタム Forth などがあります。[ 3 ] Forth は、 Open Firmwareブートローダー、Philae宇宙船などの宇宙飛行アプリケーション[ 4 ]、[ 5 ] [ 6 ] 、およびハードウェアとの相互作用を伴うその他の組み込みシステムで使用されています。
1980年代初頭から、ムーアはコンパイル済みのForthライクなコードを直接実行できる一連のマイクロプロセッサを開発し、cmForthやcolorForthなど、Forthの概念に基づいたより小規模な言語の実験を行った。これらの言語のほとんどは、チップ設計など、ムーア自身のプロジェクトを支援するために作成された。
Forthは天文学や宇宙アプリケーション[ 7 ]においてニッチな地位を築いており、組み込みシステムにおいても歴史があります。Apple 、IBM、Sun、OLPC XO-1で使用されているOpen FirmwareブートROMにはForth環境が含まれています。
Forthは新しいハードウェアの起動によく使われてきました。Forthは1978年に新しいIntel 8086チップに最初に常駐したソフトウェアであり、MacFORTHは1984年にMacintosh 128Kに最初に常駐した開発システムでした。[ 8 ]
1982 年頃、アタリ社は、デパートでアタリ 8 ビット コンピュータの機能を披露するために、Forth で書かれた精巧な自動実行デモを使用しました。 [ 9 ]エレクトロニック アーツは、 1980 年代に Forth で書かれた複数のビデオゲームを発売しました。これには、Worms? (1983)、[ 10 ] Adventure Construction Set (1984)、[ 11 ] Amnesia (1986)、[ 12 ] Starflight (1986)、[ 3 ]およびLords of Conquest (1986) が含まれます。ロボット コーディング ゲームChipWits (1984) はMacintosh 128K用に MacFORTH で開発され、[ 13 ] Commodore 64への移植は SuperForth 64 で書かれました。[ 14 ] Boulder Dash (1984)のプロトタイプは、6502 アセンブリ言語で書き直される前に Forth で実装されました。[ 15 ]
Ashton-TateのRapidFile(1986年)はフラットファイルデータベースプログラムであり、Paperback Software InternationalのVP-Planner [ 16 ] (1983年)はLotus 1-2-3と競合する表計算プログラムであり、Forthで書かれました。
キヤノンキャット(1987年)は、システムプログラミングにForthを使用しています。
ロックウェル社は、Forthカーネルを内蔵したシングルチップマイクロコンピュータ、R65F11とR65F12を製造した。
ASYSTは、PC上で計測と制御を行うためのForth拡張版でした。[ 17 ]
Forthは、1968年から継続的に開発されてきたチャールズ・H・ムーアの個人用プログラミングシステムから発展したものです。[ 8 ] [ 18 ] Forthが他のプログラマーに初めて紹介されたのは1970年代初頭で、米国国立電波天文台(NRAO)のエリザベス・ラザーがその先駆けでした。[ 8 ] NRAOでの仕事の後、チャールズ・ムーアとエリザベス・ラザーは1973年にFORTH, Inc.を設立し、次の10年間でForthシステムを改良し、他の数十のプラットフォームに移植しました。
ムーアはForthをコンパイル・リンク・Goの第3世代プログラミング言語、あるいは「第4世代」ハードウェア向けのソフトウェアの後継と見なしていた。彼はその名前がどのように付けられたかを回想している。[ 19 ]
モハスコ社(1960年代後半)では、 IBM 2250グラフィックディスプレイと接続されたIBM 1130を直接操作していました。1130は非常に重要なコンピュータで、初のカートリッジディスクに加え、カードリーダー、カードパンチ(ディスクのバックアップ用)、コンソールタイプライターを備えていました。1130によって、プログラマーは初めてコンピュータを完全にインタラクティブに制御できるようになったのです。
FORTHは、その1130上で初めて実体として登場しました。FORTHという名前は、FOURTHの5文字の略で、第4世代コンピュータ言語を意味します。当時、皆さんもご記憶にあるかもしれませんが、第3世代コンピュータの時代で、私はそれを飛び越えようとしていました。しかし、FORTHは1130上で動作したため(1130は5文字の識別子しか許可していなかった)、名前が短縮されました。
FORTH, Inc. の microFORTH は、1976 年よりIntel 8080、Motorola 6800、Zilog Z80、およびRCA 1802マイクロプロセッサ向けに開発されました。microFORTH は後に、1978 年の6502などの他のアーキテクチャ向けに Forth システムを生成するために趣味家によって使用されました。Forth Interest Group は 1978 年に設立されました。[ 20 ]同グループは、ほとんどのホームコンピュータ向けに独自の言語バージョンである FIG-Forth を宣伝および配布しました。
Forth は 1980 年代初頭に人気を博しました。[ 21 ]マイクロコンピュータの限られたメモリに適していたためです。言語の実装の容易さから、多くの実装が生まれました。[ 22 ] Jupiter ACEホームコンピュータは、ROM に常駐するオペレーティングシステムとして Forth を使用しています。Insoft GraFORTH は、Apple II 用のグラフィックス拡張機能を備えた Forth のバージョンです。[ 23 ]
一般的な慣行は、それぞれ 1979 年と 1983 年に事実上の標準である FORTH-79 [ 24 ]と FORTH-83 [ 25 ]に成文化されました。これらの標準は 1994 年にANSIによって統合され、一般的にANS Forthと呼ばれています。[ 26 ] [ 27 ]
2018年現在、FORTHのオリジナル1130バージョンのソースが復元され、復元またはエミュレートされた1130システムで動作するように更新されている。[ 28 ]
Forth は、ワードと呼ばれる小さくてシンプルな関数の使用を重視しています。より大きなタスクのためのワードは、それぞれが個別のサブタスクを実行する多くの小さなワードを呼び出します。大規模な Forth プログラムは、ワードの階層構造になっています。これらのワードは、スタック機構を介して暗黙的に通信する個別のモジュールであるため、独立してプロトタイプを作成、構築、テストできます。Forth コードの最上位レベルは、アプリケーションの英語の説明に似ている場合があります。Forth はメタアプリケーション言語、つまり問題指向言語を作成するために使用できる言語と呼ばれています。[ 29 ]
Forth は、データスタックの暗黙的な使用と、Hewlett-Packardの電卓で一般的に使用されている逆ポーランド記法に依存しています。逆ポーランド記法では、演算子はオペランドの後に配置されますが、より一般的な中置記法では演算子はオペランドの間に配置されます。後置記法は、言語の解析と拡張を容易にします。Forth の柔軟性により、静的なBNF文法は不適切であり、Forth にはモノリシックなコンパイラがありません。コンパイラを拡張するには、文法を変更したり、基盤となる実装を変更したりするのではなく、新しいワードを作成するだけで済みます。
RPNを用いると、算術式(25 × 10) + 50の値は次のように計算できます。
25 10 * 50 + CR . 300 OK
まず、数字の25と10を積み重ねます。

この単語は*、山積みの数字の一番上の2つの数字を取り出し、それらを掛け合わせ、その積を山積みに戻します。

次に、数字の50が積み重ねられたカードの上に置かれる。

このワードは+スタックから上位 2 つの数値を取り出し、それらを加算し、合計をスタックに戻します。CR(キャリッジリターン) は出力を新しい行で開始します。最後に、.結果を出力します。すべてが正常に完了したため、Forth システムは を出力しますOK。[ 30 ]
Forthの構造的な特徴もスタックベースです。例えば:
: FLOOR5 ( n -- n' ) DUP 6 < IF DROP 5 ELSE 1 - THEN ;コロンは新しい定義の開始を示し、この場合は新しい単語(ここでも、単語はサブルーチンを表す用語です)である を示しますFLOOR5。括弧内のテキストはコメントで、この単語はスタック上の数値を期待し、スタック上の数値が変更される可能性があることを知らせています。
サブルーチンは、次のコマンドを使用します。DUPスタック上の数値を複製します。6スタックの一番上に 6 をプッシュします。<スタック上の上位 2 つの数値 (6 とDUPed 入力) を比較し、それらを真偽値に置き換えます。IF真偽値を受け取り、その直後のコマンドを実行するか、 にスキップするかを選択しますELSE。DROPスタック上の値を破棄します。5スタックの一番上に 5 をプッシュします。THEN条件を終了します。
この単語は、条件演算子「?:」を使用してC言語FLOOR5で記述されたこの関数と同等です。
int floor5 ( int v ) { return ( v < 6 ) ? 5 : ( v - 1 ); }この関数は、より簡潔に次のように記述できます。
: FLOOR5 ( n -- n' ) 1- 5 MAX ;これは次のように実行できます。
1階5CR。5OK 8階5CR。7OKまず、数値(1または8)がスタックにプッシュされ、FLOOR5が呼び出され、数値が再びポップされて結果がプッシュされます。CR出力は新しい行に移動します(これも読みやすさのためだけにここにあります)。最後に、が呼び出され.、結果がポップされて出力されます。
Forth の文法には公式の仕様はありません。代わりに、単純なアルゴリズムによって定義されます。インタプリタはユーザー入力デバイスから入力行を読み取り、スペースを区切り文字として使用して単語を解析します。一部のシステムでは、追加の空白文字も認識します。インタプリタが単語を見つけると、辞書でその単語を検索します。単語が見つかった場合、インタプリタはその単語に関連付けられたコードを実行し、入力ストリームの残りの部分の解析に戻ります。単語が見つからない場合、その単語は数値であると想定され、数値に変換してスタックにプッシュする試みが行われます。成功した場合、インタプリタは入力ストリームの解析を続行します。それ以外の場合、検索と数値変換の両方が失敗した場合、インタプリタは単語の後に、単語が認識されなかったことを示すエラーメッセージを出力し、入力ストリームをフラッシュして、新しいユーザー入力を待ちます。[ 31 ]
新しい単語の定義は、単語:(コロン)で始まり、単語;(セミコロン)で終わります。たとえば、
: X DUP 1+ . . ;は単語をコンパイルしX、辞書内で名前を検索できるようにします。10 Xコンソールで と入力して実行すると、 が出力されます11 10。[ 32 ]
ほとんどの Forth システムには、プロセッサの機能を使用してワードを記述するためのアセンブラが含まれています。Forth アセンブラは、命令のパラメータが命令の前に来る逆ポーランド構文を使用することがよくあります。典型的な逆ポーランド構文のアセンブラは、オペランドをスタック上に準備し、最後のステップとしてニーモニックが命令全体をメモリにコピーします。Forth アセンブラは本質的にマクロ アセンブラであるため、Forth システムでの役割に応じてレジスタのエイリアスを簡単に定義できます。たとえば、データ スタック ポインタとして使用されるレジスタには「dsp」とします。[ 33 ]
ほとんどのForthシステムは、 Microsoft Windows、Linux、Unixなどのホストオペレーティングシステム上で動作し、ソースファイルとデータファイルにはホストオペレーティングシステムのファイルシステムを使用します。ANS Forth規格では、入出力に使用されるワードが規定されています。最新のForthシステムは、組み込みシステムであっても、ソースファイルには通常のテキストファイルを使用します。常駐コンパイラを備えた組み込みシステムは、シリアル回線経由でソースファイルを取得します。
従来のForthシステムでは、オペレーティングシステムもファイルシステムも使用されません。ソースコードはファイルに格納されるのではなく、物理ディスクアドレスに書き込まれたディスクブロックに格納されます。この用語BLOCKは、1Kサイズのディスク領域ブロックの番号を、Forthシステムによって自動的に管理されるデータを含むバッファのアドレスに変換するために使用されます。ブロックの使用は1990年代半ば以降、稀になりました。ホスト型システムでは、いずれの場合もこれらのブロックも通常のファイルに割り当てられます。
マルチタスク、最も一般的には協調ラウンドロビンスケジューリングが通常利用可能です(ただし、マルチタスクワードとサポートはANS Forth標準ではカバーされていません)。このワードは、PAUSE現在のタスクの実行コンテキストを保存し、次のタスクを見つけて、その実行コンテキストを復元するために使用されます。各タスクは独自のスタック、一部の制御変数のプライベートコピー、およびスクラッチ領域を持っています。タスクのスワップは簡単かつ効率的です。その結果、Intel 8051、Atmel AVR、TI MSP430などの非常にシンプルなマイクロコントローラでもForthマルチタスクが利用可能です。[ 34 ]
その他の非標準機能には、ホストOSやウィンドウシステムへの呼び出しを行うメカニズムが含まれており、多くはオペレーティングシステムが提供するスケジューリングを利用する拡張機能を提供しています。通常、これらの機能は、タスクの作成、中断、破棄、優先度の変更に関する用語セットが、スタンドアロンのForthとは異なり、より豊富で多様なものとなっています。PAUSE
ソースコードがすべて揃ったフル機能のForthシステムは、 Forthプログラマーによってメタコンパイルまたはセルフホスティングと呼ばれる手法で自己コンパイルされます(ただし、この用語は通常定義されているメタコンパイルと完全に一致するわけではありません)。通常の方法は、コンパイルされたビットをメモリに配置する少数のワードを再定義することです。コンパイラのワードは、メモリ内のバッファ領域にリダイレクトできるフェッチとストアの特別な名前付きバージョンを使用します。バッファ領域は、コードバッファとは異なるアドレスから始まるメモリ領域をシミュレートまたはアクセスします。このようなコンパイラは、ターゲットコンピュータのメモリとホスト(コンパイル)コンピュータのメモリの両方にアクセスするためのワードを定義します。[ 35 ]
コード空間におけるフェッチおよびストア操作が再定義された後、コンパイラ、アセンブラなどは、フェッチおよびストアの新しい定義を使用して再コンパイルされます。これにより、コンパイラとインタプリタのすべてのコードが効果的に再利用されます。次に、Forthシステムのコードがコンパイルされますが、このバージョンはバッファに格納されます。メモリ内のバッファはディスクに書き込まれ、テストのために一時的にメモリにロードする方法が提供されます。新しいバージョンが正常に動作することが確認されたら、以前のバージョンに上書きされます。
さまざまな環境向けに、このようなコンパイラのさまざまなバリエーションが存在します。組み込みシステムの場合、コードはシリアルポートまたは単一のTTLビットを介して別のコンピュータに書き込まれることがあります。これはクロスコンパイルと呼ばれる手法で、元のコンパイルコンピュータにワード名や辞書のその他の実行されない部分は保持されます。このような Forth コンパイラの最小限の定義は、バイトをフェッチしてストアするワードと、Forth ワードを実行するように命令するワードです。リモート ポートを作成する際に最も時間のかかる部分は、フェッチ、ストア、実行を実装する初期プログラムの構築であることが多いですが、多くの最新のマイクロプロセッサには、この作業を不要にする統合デバッグ機能 ( Motorola CPU32など) が備わっています。[ 36 ]
Forth の基本データ構造は「辞書」であり、「単語」を実行可能なコードまたは名前付きデータ構造にマッピングします。辞書は、メモリ上にリンクされたリストのツリーとして配置され、リンクは最新の(最も最近定義された)単語から最も古い単語へと進み、通常は NULL ポインタである番兵値が見つかるまで続きます。コンテキストスイッチが発生すると、リスト検索は別のリーフから開始されます。リンクされたリストの検索は、ブランチがメインの幹にマージされ、最終的に番兵であるルートに戻るまで続きます。辞書は複数存在できます。メタコンパイルなどのまれなケースでは、辞書が分離され、スタンドアロンになる場合があります。その効果は名前空間のネストに似ており、コンテキストによってはキーワードをオーバーロードできます。
定義語は一般的にヘッドとボディで構成され、ヘッドは名前フィールド(NF)とリンクフィールド(LF)からなり、ボディはコードフィールド(CF)とパラメータフィールド(PF)からなります。
辞書エントリの先頭と本体は、連続していない可能性があるため、別々に扱われます。たとえば、Forth プログラムが新しいプラットフォーム用に再コンパイルされる場合、先頭はコンパイルコンピュータに残り、本体は新しいプラットフォームに送られます。一部の環境 (組み込みシステムなど) では、先頭が不必要にメモリを占有します。ただし、ターゲット自体が対話型 Forth をサポートすることが想定される場合、一部のクロスコンパイラはターゲットに先頭を配置することがあります。[ 37 ]
辞書エントリの正確な形式は規定されておらず、実装方法は様々である。
コンパイラ自体は単一のプログラムではありません。システムから見えるForthワードで構成されており、プログラマが使用できます。これにより、プログラマは特別な目的のためにコンパイラのワードを変更できます。従来のForthシステムにおけるコンパイルは単純明快で、コードの抽象的な表現を構築したり最適化したりする必要はありません。(一部の新しいForthコンパイラは、他の言語で一般的なように、より高度なコンパイル方法を使用しています。)
名前フィールドの「コンパイル時」フラグは、「コンパイル時」動作を持つ単語に設定されます。ほとんどの単純な単語は、コマンドラインに入力された場合でも、コードに埋め込まれた場合でも、同じコードを実行します。これらの単語をコンパイルする場合、コンパイラは単にコードまたはスレッドポインタを単語に配置するだけです。[ 32 ]
コンパイル時ワードの典型的な例は、やなどの制御構造です。Forth の制御構造のほぼすべてとコンパイラのほぼすべてがコンパイル時ワードとして実装されています。Ulrich Hoffmann の preForth で使用されている条件付き戻りワードなど、ごく少数の実装にしか見られないまれにしか使用されない制御フローワードを除いて、Forth の制御フローワードはすべてコンパイル中に実行され、プリミティブワードのさまざまな組み合わせとその分岐アドレスをコンパイルします。[ 1 ] [ 2 ]IFWHILE?EXIT
例えば、IFとWHILE、そしてそれらに一致する単語は、BRANCH(無条件分岐)と?BRANCH(スタックから値をポップし、それが偽であれば分岐)を設定します。カウントループ制御フロー単語も同様に機能しますが、カウンタと連携するプリミティブ単語の組み合わせを設定します。コンパイル中、データスタックは、制御構造のバランス調整、ネスト、および分岐アドレスのバックパッチングをサポートするために使用されます。スニペット:
... DUP 6 < IF DROP 5 ELSE 1 - THEN ...定義内では、多くの場合、次のようなシーケンスにコンパイルされます。
... DUP LIT 6 < ?BRANCH 5 DROP LIT 5 BRANCH 3 LIT 1 - ...以降の数字はBRANCH相対ジャンプアドレスを表します。LITは、データスタックに「リテラル」数値をプッシュするための基本的なワードです。(LIT関連する数値のいずれかが定数として個別に定義されている場合、 と埋め込みデータの代わりに定数へのポインタを使用することで、より高速で短いコードがコンパイルされます。定数の代わりに他のワードを使用した場合も同様の変更が発生します。)
単語:(コロン)は、名前をパラメータとして解析し、辞書エントリ(コロン定義)を作成してコンパイル状態に入ります。インタプリタは、ユーザー入力デバイスからスペースで区切られた単語の読み取りを続けます。単語が見つかった場合、インタプリタは解釈セマンティクスではなく、その単語に関連付けられたコンパイルセマンティクスを実行します。単語のデフォルトのコンパイルセマンティクスは、その解釈セマンティクスを現在の定義に追加することです。[ 32 ]
単語;(セミコロン) は現在の定義を終了し、解釈状態に戻ります。これは、コンパイル意味がデフォルトと異なる単語の例です。ANS Forth;では、(セミコロン)、ほとんどの制御フロー単語、およびその他のいくつかの単語の解釈意味は未定義です。 つまり、これらは定義内でのみ使用でき、対話型コマンドラインでは使用できません。[ 32 ]
[インタープリタの状態は、(左括弧)と](右括弧)の単語を使用して手動で変更できます。これらの単語は、それぞれ解釈状態とコンパイル状態に入ります。これらの単語LITERALは、コンパイル中に値を計算し、計算された値を現在のコロン定義に挿入するために単語とともに使用できます。には、LITERALデータスタックからオブジェクトを取得し、そのオブジェクトをデータスタックに配置するために現在のコロン定義にセマンティクスを追加するコンパイルセマンティクスがあります。
ANS Forthでは、インタプリタの現在の状態はフラグSTATEから読み取ることができ、コンパイル状態の場合はtrue、それ以外の場合はfalseの値をとります。これにより、インタプリタの現在の状態に応じて動作が変化する、いわゆる状態依存型のワードを実装することが可能になります。
この単語は、IMMEDIATE直近のコロン定義を即時単語としてマークし、そのコンパイル意味論を解釈意味論に効果的に置き換えます。[ 38 ]即時単語は通常、コンパイル中に実行され、コンパイルされませんが、プログラマはどちらの状態でもこれを上書きできます。;は即時単語の例です。ANS Forth では、この単語は名前POSTPONEをパラメータとして受け取り、その単語が即時としてマークされていても、名前付き単語のコンパイル意味論を現在の定義に追加します。Forth-83では、それぞれ非即時単語と即時単語のコンパイルを強制するために、COMPILE別々の単語とが定義されました。[COMPILE]
Forthの一部の実装では、すべての定義に即時フラグ用の領域を確保する代わりに、コンパイルモード時に最初にチェックされる即時辞書を使用します。
ANS Forthでは、名前のないワードは:NONAME、次のワード;(セミコロン)までをコンパイルし、データスタック上に実行トークンを残すワードで定義できます。実行トークンは、 C言語の関数ポインタと同様に、コンパイルされたセマンティクスへの不透明なハンドルを提供します。
実行トークンは変数に格納できます。このワードはEXECUTEデータスタックから実行トークンを取得し、関連付けられたセマンティクスを実行します。(compile-comma) ワードはCOMPILE,データスタックから実行トークンを取得し、関連付けられたセマンティクスを現在の定義に追加します。
ワード'(ティック)は、ワードの名前をパラメータとして受け取り、データスタック上のそのワードに関連付けられた実行トークンを返します。解釈状態では、' RANDOM-WORD EXECUTEと同等ですRANDOM-WORD。[ 39 ]
コロン:、 、POSTPONE、は、データスタックではなくユーザー入力デバイスから引数を取得する解析語'の例です。別の例として、 括弧 は、次の右括弧までの単語を読み取って無視し、コロン定義にコメントを挿入するために使用されます。同様に、 バックスラッシュ は、現在の行の末尾まで続くコメントに使用されます。括弧 とバックスラッシュを正しく解析するには、後続のコメントテキストから空白で区切る必要があります。(\(\
ほとんどの Forth システムでは、コード定義の本体は機械語、または何らかの形式のスレッドコードで構成されます。非公式な FIG 標準 (Forth Interest Group) に準拠したオリジナルの Forth は、TIL (Threaded Interpretive Language) です。これは間接スレッドコードとも呼ばれますが、近年では直接スレッドやサブルーチンスレッドの Forth も普及しています。SwiftForth、VFX Forth、iForth などの最新の高速 Forth は、Forth をネイティブの機械語にコンパイルします。
単語が変数またはその他のデータオブジェクトである場合、CF は、その単語を作成した定義単語に関連付けられたランタイム コードを指します。定義単語は、特性「定義動作」(辞書エントリの作成、場合によってはデータ領域の割り当てと初期化)を持ち、この定義単語によって構築された単語クラスのインスタンスの動作も指定します。例:
VARIABLEVARIABLEスタック上のそのアドレスを返します。CONSTANTCONSTANT)。インスタンスの動作は値を返します。CREATEForthには、プログラマがアプリケーション固有の定義語を定義し、独自の定義動作とインスタンス動作の両方を指定できる機能も備わっています。例としては、循環バッファ、I/Oポート上の名前付きビット、自動インデックス付き配列などがあります。
これらの単語や類似の単語で定義されるデータオブジェクトは、スコープがグローバルです。他の言語のローカル変数によって提供される機能は、Forth ではデータスタックによって提供されます (ただし、Forth にも実際のローカル変数があります)。Forth のプログラミングスタイルでは、他の言語と比較して名前付きデータオブジェクトの使用が非常に少なく、通常、そのようなデータオブジェクトは、複数の単語またはタスク (マルチタスク実装の場合) で使用されるデータを格納するために使用されます。[ 40 ]
Forthはデータ型の使用の一貫性を強制しません。適切な演算子を使用して値を取得および格納したり、データに対してその他の操作を実行したりするのはプログラマの責任です。
:こんにちは( -- ) CR 。こんにちは、世界!" ;こんにちは< cr > こんにちは、世界!
(キャリッジリターン)という単語CRは、続く出力をCR 新しい行に表示します。解析語(ドットクォート)は、二重引用符で区切られた文字列を読み込み、現在の定義にコードを追加して、実行時に解析された文字列が表示されるようにします。単語と文字列."を区切るスペース文字は、文字列の一部としては含まれません。これは、パーサーがそれをForthの単語として認識するために必要です。."Hello, World!."
標準的なForthシステムもインタプリタであり、Forthコンソールに次のコード断片を入力することで同じ出力を得ることができます。
CR . (ハロー、ワールド!).((ドット-パレン) は、括弧で区切られた文字列を解析して表示する即時ワードです。ワードと同様に、とを."区切るスペース文字は文字列の一部ではありません。.(Hello, World!
単語はCR、印刷するテキストの前に来ます。慣例として、Forth インタープリタは新しい行から出力を開始しません。また、慣例として、インタープリタはプロンプトの後、前の行の末尾で入力を待ちます。他のプログラミング言語にあるような、ok暗黙の「バッファをフラッシュ」する動作は Forth にはありません。CR
EMIT-Q実行時に単一の文字を出力する単語の定義は次のとおりですQ。
: EMIT-Q 81 (文字「Q」のASCII値) EMIT ;この定義は、文字(81)のASCIIQ値を直接使用するために記述されています。括弧内のテキストはコメントであり、コンパイラによって無視されます。このワードはEMITデータスタックから値を取得し、対応する文字を表示します。
以下の再定義では、(左括弧)、(右括弧)、EMIT-Qおよびを使用して、一時的にインタプリタ状態に切り替え、文字のASCII値を計算し、コンパイル状態に戻り、計算された値を現在のコロン定義に追加します。[]CHARLITERALQ
: EMIT-Q [ CHAR Q ] LITERAL EMIT ;解析ワードはCHAR、スペースで区切られたワードをパラメータとして受け取り、その最初の文字の値をデータスタックに配置します。このワードは、[CHAR]の即値バージョンですCHAR。を使用すると[CHAR]、の例の定義はEMIT-Q次のように書き換えることができます。
: EMIT-Q [CHAR] Q EMIT ; \ 1文字「Q」を出力しますこの定義では、\説明コメントにバックスラッシュ(/)を使用しています。
と はどちらCHARもANS Forth[CHAR]で定義されています。 と を使用すると、は次のように定義できます。IMMEDIATEPOSTPONE[CHAR]
: [CHAR] CHAR POSTPONE LITERAL ; IMMEDIATE1987年、ロン・リベストはRSAデータセキュリティ社のためにRC4暗号システムを開発した。その概要は以下のとおりである。
256 バイトの配列があり、すべて異なります。配列が使用されるたびに、2 バイトを交換することで変更されます。交換は、最初はそれぞれ 0 であるカウンタiとjによって制御されます。新しいi を取得するには、1 を追加します。新しいjを取得するには、新しいiの配列バイトを追加します。iとjの配列バイトを交換します。コードは、 iとjの配列バイトの合計の配列バイトです。これは、暗号化する平文の 1 バイト、または復号する暗号文の 1 バイトと XOR されます。配列は、最初に 0 から 255 に設定することで初期化されます。次に、iとj を使用して配列を順に処理し、 iの配列バイトとキー バイトを追加して新しいjを取得し、 iとjの配列バイトを交換します。最後に、iとjを 0 に設定します。すべての加算は 256 を法として行われます。
以下のStandard Forthバージョンでは、コアワードとコア拡張ワードのみを使用します。
0値ii 0値jj 0値KeyAddr 0値KeyLen create SArray 256 allot \state 256 バイトの配列: KeyArray KeyLen mod KeyAddr ;: get_byte + c@ ; : set_byte + c! ; : as_byte 255 and ; : reset_ij 0 TO ii 0 TO jj ; : i_update 1 + as_byte TO ii ; : j_update ii SArray get_byte + as_byte TO jj ; : swap_s_ij jj SArray get_byte ii SArray get_byte jj SArray set_byte ii SArray set_byte ;: rc4_init ( KeyAddr KeyLen -- ) 256 min TO KeyLen TO KeyAddr 256 0 DO i i SArray set_byte LOOP reset_ij BEGIN ii KeyArray get_byte jj + j_update swap_s_ij ii 255 < WHILE ii i_update REPEAT reset_ij ; : rc4_byte ii i_update jj j_update swap_s_ij ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor ;これはコードをテストする一つの方法です。
hex create AKey 61 c, 8 A c, 63 c, D2 c, FB c, : test cr 0 DO rc4_byte . LOOP cr ; AKey 5 rc4_init 2 C F9 4 C EE DC 5 test \ 出力は次のようになるはずです: F1 38 29 C9 DE特定のプログラミング言語をサポートするように設計されたプロセッサは、言語「エンジン」と呼ばれます。[ 41 ]
Forthエンジンは、Forthで書かれたプログラムの開発と実行をサポートするために特別に設計されたハードウェアプラットフォームです。(同様に、LispマシンはLispで書かれたプログラムの開発と実行をサポートするために特別に設計され、Pascal MicroEngineはPascalで書かれたプログラムの開発と実行をサポートするために特別に設計されました。)
最初に市販されたシングルチップのForthエンジンはRockwell R65F11でした[ 41 ]。このチップにはROMにForthカーネル、拡張6502、SRAM、および以前は周辺チップが必要だったさまざまなインターフェース回路が含まれています。[ 41 ] [ 42 ] [ 43 ] [ 44 ] [ 45 ]
他の多くの商用CPU(Harris RTX-2000、Novix NC4016、F21、MARC4、KimKloneなど)や多くの自作CPU(My4TH、J1、H2、Mark 1 FORTH Computerなど)は、Forthを実行するために特別に設計されています。通常、これらのCPUは「Forth NEXT」などの一般的なForthプリミティブを単一の命令として実装しています。
Forthは実装が容易で、標準的なリファレンス実装が存在しないため、数多くのバージョンが存在します。これらのForthシステムの多くは、標準的なデスクトップコンピュータシステム(POSIX、Microsoft Windows、macOS)をサポートするだけでなく、様々な組み込みシステムも対象としています。以下に、1994年のANS Forth規格に準拠するシステムの一部を示します。
次の3種類があります。システム変数には、Forthシステム全体で使用される値が含まれます。ユーザー変数には、定義はシステム内のすべてのタスクで使用できますが、各タスク固有の値が含まれます。通常の変数は、システム全体でアクセス可能か、単一のタスク内でのみアクセス可能かによって、定義が
プライベートタスク内にあるかが決まります。
OPERATOR