コンセプトRedプリプロセッサはRedのダイアレクトであり、Red言語の最も上に存在する特別なレイヤーにおいてRedのソースコードを変換することを可能にします。呼ばれるインラインプリプロセッサ用のキーワードに基づいて行われます。directiveは次のタイミングで処理されます。関数が呼ばれた時プリプロセッサはLOADフェーズの後に実行されます。そのため、ソースコードを文字列的に扱うのではなく、Redの各種の値として処理します。ディレクティブは以下のカテゴリーに分けられます。式の結果に応じたコードを挿入します。プリプロセッサの振る舞いを制御します。関数を使ったより複雑なコード変換を行います。型の値で表現されます。ディレクティブが処理されると、そのディレクティブが返す戻り値でコードが置き換わります。いくつかのディレクティブは値を返さないですが、その場合は単に削除されます。ソースコードの変換はこのように行われます。これはディレクティブと似ていますが、ローレベルで文字列的な取り扱いにより適用されます。オブジェクトが使用可能です。これはコンパイル時の設定へのアクセスを可能にし、条件に従ってコードを挿入したい場合によく用いられます。オブジェクトは参照可能です。オブジェクトにはコードを実行しているRedのバイナリのコンパイルオプションが設定されています。実行コンテキストディレクティブの中で使用される式は全て、現在のコンテキストにのみ反映され、グローバルコンテキストにリークして予期しない副作用を起こすことはありません。ディレクティブが使用されるたびに拡張されます。Tips:以下のコードにより、隠蔽されたコンテキストの内容を表示することができます。self]実行時に使用される場合、隠蔽コンテキストへのアクセスは以下のように行います。現在のところ、コンパイル時に呼び出されるディレクティブ中の式はRebol2のインタプリタで評価されています。ツールチェインのコードを実行する場合と同じです。これは一時的なもので、できるだけ早くRedのエバリュエータに変更される予定です。それまでの間は、Redのランタイム(また、将来のコンパイル時の)における動作の互換性のため、使用する式やマクロがRedでも実行できるようにしておいてください。呼ばれることが多いです)をサポートしています。マクロを使うことで、より複雑な変換が行え、効率的なメタプログラミングを可能にします。実行コストをコンパイル時に発生させ、実行時のコストを回避できます。Redはマクロが実装される以前から実行時の強力なメタプログラミング性能を持っていましたが、Redのソースコードがコンパイラ上でもインタプリタ上でも同様に動作するため、マクロは実行時にも解決されるようになっています。NOTE:ソースの読み取り時のマクロは存在しません。文字列としてソースを取り扱う方法はすでにParseダイアレクトが存在するため、そのような機能のサポートは現在のところは冗長だと捉えられています。プリプロセッサは2つのタイプのマクロをサポートしています。名前付きマクロこのタイプのマクロはハイレベルで動作し、引数や戻り値の取り扱いまでプリプロセッサ側で処理してくれるため、ユーザーが意識する必要はありません。典型的なフォーマットは以下のようなものです。wordが現れるたびに、以下のステップに従ってこのマクロが呼び出されます。関数内で最後に評価された値で、マクロ呼び出しと引数部分を置き換え置き換えられた値を元にプリプロセッサの動作を再開(再帰的なマクロの評価も可能です)NOTE:引数の型を指定することは現在のところサポートされていません。64この結果は以下のように変換されます。65536マクロの中から他のマクロを呼び出す例です。1この結果は以下のように変換されます。パターンマッチマクロこのタイプのマクロはwordと引数でマッチングされるのではなく、Parseダイアレクトのルールとキーワードで定義されたパターンによってマッチングを行います。名前付きマクロと同様、戻り値がマッチしたパターンを置換するために使われます。属性を使用することで起動されます。この場合、暗黙的な処理はありませんが、ユーザーが全てをコントロールすることができます。自動的な置換は行われず、必要な変換を適用するのもコードの評価を再開する位置を決めるのも定義したマクロ関数次第です。典型的なパターンマッチマクロは以下のような形式です。以下のものを使用することができます。lit-word!型の値:指定したwordでマッチングされます。word!の値:Parseダイレクトで使用されるキーワードです。「skip」などです。block!型の値:Parseダイアレクトのルール。分割されたソースコードに対する参照です。戻り値は再開位置への参照である必要があります。指定することができます。これにより、そのマクロはローレベルのマニュアルモードで実行されます。2この結果は以下のように変換されます。3マニュアルモードを使用すると、同じ内容のマクロは以下のように書けます。1この結果は以下のように変換されます。条件式がtrueだった場合、コードブロックの内容を挿入します。ブロックは再度プリプロセッサに渡されます。Windows"]Windowsで実行した場合、以下のように変換されます。Windows"Windowsでない場合、以下の結果になります。ディレクティブを使うと自由にwordを定義でき、式の中で使用することができます。mode"]この結果は以下のように変換されます。条件式によって挿入するコードブロックを選択します。挿入されたブロックは再度プリプロセッサに渡されます。["Windows"]["Unix"]Windowsで実行した場合、以下のように変換されます。"Windows"Windowsでない場合、以下の結果になります。値に応じて、複数の選択肢の中から挿入するコードを選択します。挿入されたブロックは再度プリプロセッサに渡されます。["macOS"]]Windowsで実行した場合、以下のように変換されます。値に応じて、複数の選択肢の中から挿入するコードを選択します。挿入されたブロックは再度プリプロセッサに渡されます。["Hard"]]この結果は以下のように変換されます。(file!)説明コンパイル時に評価された場合、引数のファイルの中身を読み込んで現在の位置に挿入します。ファイルは現在のスクリプトからの絶対パスまたは相対パスを使うことができます。置換され、ファイルの挿入は行われません。暗黙的な実行コンテキスト上で、bodyブロックを評価します。評価した結果でディレクティブと引数が置換されます。"negative"]この結果は以下のように変換されます。マクロ関数のボディブロック説明マクロ関数を作成します。名前付きマクロでは、specブロックでは任意の数の引数を宣言できます。bodyブロックはマクロ呼び出しと引数を置換するための戻り値を返す必要があります。空のブロックを返した場合、マクロ呼び出しと引数は単に削除されます。引数を宣言する必要があり、それらがマッチしたパターンへの開始位置の参照と終了位置の参照になります。デフォルトでは、マクロの本体はマッチしたパターンを置換する値を返す必要があります。空のブロックを返した場合、マッチしたパターンは削除されます。属性を設定することで実行されます。マニュアルモードのマクロは置換する値ではなく、再開位置を返す必要があります。