Forth
BRANCHのあとの数のは相対的なジャンプアドレスを表している。LITは「リテラル」数値をデータスタックにプッシュするためのプリミティブなワードである。
ワード :(コロン)は名前を引数として構文解析し、辞書にヘッダを作り(記述法はコロン記号で始まりセミコロン記号で終わるので、コロン定義, colon definition)、コンパイル状態に突入する。コンパイラは後続のワードをコンパイルしていく。このときワードが後述する即時ワードである場合は実行し、そうでない場合は実行時に呼び出されるようにコンパイルする。
ワード;(セミコロン)は現在の定義を終了し、実行状態へと復帰する。
システムの状態はワード [(左大括弧)及び ](右大括弧)を用いて手動で変更させることができ、それぞれ実行状態とコンパイル状態に突入する。ANS  Forthでは、現在のインタプリタの状態はフラグ STATEから読み取ることができ、コンピレーションステート状態 true、そうでなければ false の値がこいる。をこのインタプリタの現在の状態による振る舞いコンパイル時ステートスマートワード (state-smart words) の実装を可能にする。
ワードIMMEDIATEは、直近のコロン定義を、即時ワードにする。即時ワードは通常はコンパイル後ではなくコンピレーションの間に実行されるが、どちらのステートにおいてもプログラマにオーバーライドされることができる。; は即時ワードの一例である。ANS Forth では、ワードがイミディエイトとしてマークされていても、ワード POSTPONE は名前を引つけられたワードのコンピを強制的にコンパイルする。
ANS Forth では、ワード :NONAME を用いて、次の;(セミコロン)までの後続のワードをコンパイルし、実行トークン (execution token) をデータスタック上に残す、無名のワードが定義できる。
ワード EXECUTE はデータスタックから実行トークンを取り出し、関連づけられたセマンティクスを実行することができる。またワード COMPILE,(COMPILE コンマ)は、データスタックから実行トークンを取り出し、コンパイルする。
ワード ' (tick) は、ワード名を引数としてとりデータスタック上のワードに関連づけられた実行トークンを返す。
ワード : (colon)、POSTPONE、' (tick)と :NONAME は、データスタックの代わりにユーザからの入力からそれらの引数をとる構文解析ワード (parsing words) の例である。別の例では、コロン定義において、次の右括弧を含む後続のワードを読み込んで無視し、コメントを配置するのに使われる ((左括弧)がある。同様に、ワード Backslash(バックスラッシュ)は現在の行の終端まで続くコメントのために使われる。
ほとんどの Forth システムにおいて、コード定義のボディはマシン語といくつかの形式のスレッデッドコードからなる。非公式の FIG 規格 (Forth Interest Group) に従っているオリジナルの Forth は、TIL (Threaded Interpretive Language) である。これは 間接スレッディング(indirect-threading)とも呼ばれ、直接スレッディング(direct-threading) と サブルーチン・スレッディング(subroutine-threading) も現在はよく使われるようになってきた。最初期のモダンな Forth はサブルーチン・スレッディングを使っており、マクロとしてシンプルなワードを挿入し、より小さく速いコードを生成するために のぞき穴的最適化 や他の最適化戦略を実行した。
ワードが変数や他のデータオブジェクトであるとき、CPはそれを作成した定義ワードに関連付けられたランタイムコードを指している。定義ワードは特徴的な"defining behavior"(ディクショナリエントリの作成に加え、もしかしたらアロケートとデータ領域の初期化をする)を持っており、この定義しているワードによって構築されたワードのクラスのインスタンスの振る舞いの定義もする。たとえは、
VARIABLE
初期化されていないものを命名する、one-cell memory location。VARIABLE のインスタンスの振る舞いはそのスタック上のアドレスを返す。
CONSTANT
値を命名する(CONSTANTの引数として指定する)。インスタンスの振る舞いは値を返す。
CREATE
位置を命名する。空間がこの場所に確保されるか、さもなくばこれは文字列か他の初期化された値を格納するためにそれがセットされることができる。インスタンスの振る舞いは、この空間の開始のアドレスを返す。
Forth は、カスタム定義の振る舞いとインスタンスの振る舞いを指定する、新しいアプリケーション特有の定義ワードをプログラマが定義できる機能もまた提供する。円形バッファ、I/Oポート上で命名されたビット、自動的にインデックス化された配列などの例がある。
これらに定義されたデータオブジェクトと同様のワードはスコープにおいてグローバルである。他の言語でローカル変数から提供された関数は、Forth ではデータスタックから提供される(しかし、Forth も真のローカル変数は持っている)。Forth のプログラミングスタイルは他の言語に比べ、ごく少数の名付けられたデータオブジェクトを使う。典型的にはこのようなデータオブジェクトは、たくさんのワードやタスク(マルチタスクの実装においては)によって使われるデータを格納するのに使われる。
Forth は型システムを持たない。したがって値の操作は全てプログラマの責任で行われる。
Forth で書かれたワードは実行可能な形式にコンパイルされる。古典的実装は、順に実行されるワードのアドレスのリストをコンパイルする。多くの現代的なシステムは実際のマシンコードを生成する(いくつかの外部ワードの呼び出しと、適当な場所に展開された他者のためのコードを含む)。最適化コンパイラをもつシステムもある。一般的な場合、Forth プログラムは実行可能形式としてロードされたとき実行されるコマンド (e.g., RUN) を含めた、Forthプログラムのコンパイル済みコードのメモリイメージとして保存されている。
開発中、プログラマは小さなコード片を開発したときに実行およびテストするためにインタプリタを使う。そのため、ほとんどの Forth プログラマは緩やかなトップダウン設計と、単体テストと統合の繰り返しによるボトムアップ開発を支持している。
トップダウン設計では、普通まずプログラムを「語彙」へのプログラムを分割し、それらを最終的に必要なプログラムを書くための、高レベルなツールセットとして利用する。よく設計された Forth プログラムは自然言語のように読むことができ、単一の目的を達成するために用いられるだけでなく、関連する問題を解くプログラムを書くのに利用することができる。
For an explanation of the tradition of programming "Hello World", see Hello world.
実装の一つとしては、
: HELLO  ( -- )  CR ." Hello, world!" ; HELLO <cr>
ワード CR (Carriage Return) は後続の出力を新しい行の上に表示するようにする。構文解析ワード  ." (dot-quote) はダブルクオートで区切られた文字列を読み、構文解析された文字列が実行時に表示されるように現在の定義にコードを追加する。文字列 Hello, world! からこの空白文字で区切っているワード ." は、文字列には含まれていない。これは構文解析器が ." を Forth ワードとして認識するために必要である。
標準的な Forth システムはインタプリタでもあり、同じ出力は次のコード片を Forth コンソールに入力することで得ることができる。
CR .( Hello, world!)
.( (dot-paren) は括弧で囲まれた文字列を構文解析し、これを表示するイミディエイトワードである。."と同様に、Hello, world! から空白文字で区切られた.( は文字列の一部ではない。
ワード CR は表示する文字列の前にくる。慣例的に、Forth インタプリタは新規行に出力を開始しない。また、慣例により、インタプリタは直前の行の終端、okプロンプトの後で入力を待つ。他のプログラミング言語で時々そうであるような、Forth の CR にはバッファをフラッシュする暗黙の動作はない。
ここに 実行されると単一の文字 Q を発行するワード EMIT-Q の定義がある。
: EMIT-Q   81 (the ASCII value for the character 'Q') EMIT ;
この定義は Q のASCII値 (81) を直接を使うことで書かれている。括弧の間の文字列はコメントで、コンパイラに無視される。ワード EMIT はデータスタックから値をとり、対応する文字を表示する。
次の EMIT-Q の再定義は、ワード[(左大括弧)、](右大括弧), CHAR、LITERAL  をインタプリタステートを一時的に切り替えるために使っており、文字 Q のAscii値を計算し、コンピレーションステートを返し、計算した値を現在のコロン定義に追加する。
: EMIT-Q   [ CHAR Q ]  LITERAL  EMIT ;
構文解析ワード CHAR は空白で区切られたワードをパラメータとしてとり、データスタック上のその最初の文字の値を置く。ワード [CHAR] は CHAR のイミディエイトバージョンである。[CHAR]を使って、EMIT-Q の定義例は次のように書くことができる。
: EMIT-Q   [CHAR] Q  EMIT ; Backslash Emit the single character 'Q'
この定義はコメントを書くために Backslash(バックスラッシュ)を使っている。
CHAR と [CHAR]の両方は ANS Forth では事前に定義される。IMMEDIATE と POSTPONE と使って、[CHAR] はこのように定義することができる。
: [CHAR]   CHAR  POSTPONE LITERAL ; IMMEDIATE
1987年、Ron Rivest は RC4 暗号システムを RSA Data Security, Inc. のために開発した。このコードは非常に単純で、説明を読めば大抵のプログラマは書くことができる。
それぞれすべて値の異なった 256 バイトの配列がある(訳注:これが暗号ストリームの状態であり、鍵で適当に初期化する)。
この配列が使われるときはいつも、2つのバイトが交換されることによって変更される。
この交換はカウンタ i および j によって制御され、どちらも最初は 0 である。
新しい i を取得するには 1 を加算する。
新しい j を取得するには、新しい i の位置にある配列のバイトを加算する。
i と j の位置にある配列の値を交換する。
このコード(訳注:後のXORに使う値)は i と j の位置にある配列のバイトの和の位置にある配列のバイトである。
平文を暗号化したり暗号文を復号するためには、このバイトを XOR される。
配列は最初の設定によって 0 から 255 にかけて初期化される(訳注:手順の途中に書いてあるが、これは最初に行う)。
それから i と j を使う、i の位置にある配列のバイトを j に加算による新しい j とキーのバイトの取得、i と j のバイトの交換と手順は進んでいく。
最後に、i と j は 0 にセットされる。
すべての加算は 256 を法とするモジュラ演算である。
さらなる情報は、http://ciphersaber.gurus.com を参照すること。
以下の標準の Forth バージョンはコアのワードのみを使っている。
0 VALUE ii
0 VALUE jj
CREATE S[] 256 CHARS ALLOT
: ARCFOUR  (c -- x)
ii 1+ DUP TO ii 255 AND ( -- i)
S[] +  DUP C@ ( -- 'S[i] S[i])
DUP jj +  255 AND DUP TO jj ( -- 'S[i] S[i] j)
S[] +  DUP C@ >R ( -- 'S[i] S[i] 'S[j])
OVER SWAP C!       ( -- 'S[i] S[i])
R@ ROT C! ( -- S[i])
R> + ( -- S[i]+S[j])
255 AND S[] + C@ ( -- c x)
XOR ;
: ARCFOUR-INIT (key len -- )
256 MIN LOCALS| len key |
256 0 DO  I  S[] I + C!  LOOP
0 TO jj
256 0  DO (key len -- )
key I len MOD + C@
S[] I  + C@  + jj + 255 AND TO jj
S[] I  + DUP C@  SWAP (c1 addr1)
S[] jj + DUP C@  (c1 addr1 addr2 c2) ROT C! C!
0 TO ii  0 TO jj ;
これはこのコードを検証する多くのテストのひとつである。
CREATE KEY: 64 CHARS ALLOT
: !KEY (c1 c2 ... cn n—store the specified key of length n)
DUP 63 U> ABORT" key too long (<64)"
DUP KEY: C! KEY: + KEY: 1+ SWAP ?DO  I C!  -1 +LOOP ;
HEX  61 8A 63 D2 FB  5 !KEY
KEY: COUNT ARCFOUR-INIT
DC ARCFOUR 2 .R SPACE
EE ARCFOUR 2 .R SPACE
4C ARCFOUR 2 .R SPACE
F9 ARCFOUR 2 .R SPACE
2C ARCFOUR 2 .R
CR .(Should be: F1 38 29 C9 DE)
Forth 仮想マシンは実装が単純で規格のリファレンス実装を持たないため、大量の言語実装が存在する。標準的な各種デスクトップコンピュータシステム (POSIX, Microsoft Windows, macOS) をサポートしていることに加え、これらの多くの Forth システムは各種の組み込みシステムもまた対象としている。1994年の ANS Forth 規格に準拠するさらに有名ないくつかのシステムが列挙する。
Gforth - GNUプロジェクトによる移植性の高い ANS Forth 実装
- Forth の開発者たちによって設立され、デスクトップ向け (SwiftForth) と組み込み向け (SwiftX) ANS Forth ソリューションを販売している
- 高度に最適化されたデスクトップ (VFX) と 組み込み ANS Forth コンパイラ
Open Firmware - ANS Forth に準拠したブートローダと ファームウェア の規格
Forthをベースに、オブジェクト指向に改良したMac OS向けの開発システムMops。オブジェクト指向とマルチスレッド対応のPalo Alto Shipping Co.製のMach1(まっはわん)がある。
Open Firmwareのシェル言語はForthベースである。SunのOpenBoot PROM(OBP)やCHRPベースのPower Macintoshの起動用ファームウェアはOpen Firmwareの実装である。
Forthを元にしたコマンド言語であるFiclはFreeBSDのブートローダの実装に使われている。
1985年ごろ、服飾メーカーとして知られるJUN(株式会社ジュン)が開発したコンピュータグラフィックシステム4D-Boxのオペレーション言語0DLはForthであった。
PostScriptは、作者によれば影響されたものではないとしているが、Forthと同じく後置記法でスタック指向であり、類似性が指摘されることがある。
TeleScript General Magic社が開発・提供していた次世代エージェント指向の通信用プログラム言語。Forthアーキテクチャで実装されていた。