define-macro (マクロ)
パッケージ: CURL.LANGUAGE.COMPILER

マクロを作成します。マクロは、Curl プレフィックス式を後でコンパイルする他のフォームに変換するデバイスです。

構文

マクロ定義の構文は、プロシージャの定義に似ています。ただし、通常のパラメータ リストの代わりに syntax-switch 内でパターン テンプレートを使用し、戻り値は指定しない点がプロシージャ定義と異なります。

{define-macro [attributes] {macro-name pattern-template}
    code-body
}
attributes: 有効な属性は、アクセス指定子の publiclibrary、および package です。いずれも指定されていない場合、package が指定されます。ただし、マクロが定義されたパッケージ内でそのマクロを使用することはできないため、実際に使用するためには、ユーザー定義のマクロを publicまたは libraryとして指定することが必要です。
macro-name: 有効な Curl 識別子。
pattern-template: 使用可能な単純なパターンと複雑なパターンの全リストについては、syntax-switch を参照してください。
code-body: code-body は、コード ブロックを構成する一連の式を含み、1 つまたは複数の return 式によって値を返します。

コード ブロックから返される値は、通常は expand-template 式の結果として生成されます。
macro-env:
define-macro は暗黙的な引数 macro-env:MacroEnv を取ります。このオブジェクトでメソッドを呼び出すことにより、マクロは呼び出されたコンテキストについてコンパイラをクエリすることができます。
このオブジェクトのより強力なバージョンが必要な場合は、define-syntax も参照してください。

説明

define-macro はコンパイラによって syntax-switch を含む macro-expander プロシージャに変換されます。syntax-switch は暗黙的に must-match? = true 指定を持つので、パターン テンプレートがマッチしないと SyntaxError がスローされます。

マクロはまた、パターン マッチングを回避して、?raw:verbatim などの単純な verbatim パターン テンプレートを指定することにより、独自の未加工処理を実行することができます。引数として有効なコードのみを読み取るマクロの場合は、代わりに ?raw:tokens を使用して効率性を高めることができますが、両方の方法とも使用可能です。

戻り値のデータ型を明示的に CurlSource とは宣言しませんが、code-bodyCurlSource オブジェクトを返さなければなりません。戻り値のデータ型の宣言を試行するとエラーが発生します。expand-template を使用するので、マクロの作成者は CurlSource クラスについて学習する必要はまったくありません。

パターン テンプレートで使用する構文パターンの詳細なリストについては、syntax-switch を参照してください。

define-macro より強力なバージョンに関しては、define-syntax を参照してください。

注意事項

コンパイル順 (compilation-order) で発生する複雑な問題に対処するため、マクロは起動される場所とは別のパッケージ内で定義することが必要です。この制限により、マクロ エクスパンダと呼び出される任意のヘルパー関数が、マクロ エクスパンダ実行の前に確実にコンパイルされます。

次に単純なマクロの例を示します。

    {define-macro public {print-sum ?arg1:expression, ?arg2:expression}
        {return {expand-template {output ?arg1 + ?arg2}}}
    }


2 番目の単純なマクロの例です。
{define-macro public {swap ?a:identifier, ?b:identifier}
    {return
        {expand-template
            {do
                let tmp:{compile-time-type-of ?a} = ?a
                set ?a = ?b
                set ?b = tmp
            }
        }
    }
}