@node Macros, Core library, Core syntax, Top
@chapter Macros
@c NODE マクロ

@c EN
Gauche supports both R5RS hygienic macros and
traditional macros.
@c JP
Gaucheでは、R5RSに定義される「健全な(hygienic)」マクロと
伝統的なマクロの両方が使えます。
@c COMMON

@c EN
Macro of Lisp-family language is very different feature from
ones of other languages, such as C preprocessor macros.
It allows you to extend the original language syntax.
You can use macros to change Gauche syntax
so that you can run a Scheme program written to other Scheme
implementations, and you can even design your own mini-language
to solve your problem easily.
@c JP
Lisp系言語のマクロは、他の言語に見られるマクロ(例えばCプリプロセッサマクロ)とは
大きく異なります。Lispのマクロは元の言語の構文を拡張する手段なのです。
例えば、Gaucheの構文を若干変えることで他のScheme実装用に書かれたSchemeプログラムを
走らせたり、あるいは自分の問題解決に適した「ミニ言語」をデザインすることさえできます。
@c COMMON

@menu
* Hygienic Macros::             
* Traditional Macros::          
* Macro expansion::             
* Macro utilities::             
@end menu

@node Hygienic Macros, Traditional Macros, Macros, Macros
@section Hygienic Macros
@c NODE 健全なマクロ

@c EN
R5RS hygienic macro is based on a special pattern language,
and guaranteed that no "variable capture" occurs.
"Variable capture" means that if you insert new variable
bindings in the expanded form, the new bindings
shadows the bindings in the form passed to the macro.
@c JP
R5RSの健全なマクロは特別なパターン言語に基づいていて、
また「変数捕捉」が起こらないことが保証されています。
「変数捕捉」とは、マクロが新しい変数束縛を導入した時に、その束縛が
マクロに渡されたフォーム中の変数名と衝突して、その変数名の本来の束縛を隠して
しまうことを言います。
@c COMMON

@defspec define-syntax name transformer-spec
[R5RS]
@end defspec

@defspec let-syntax ((name transformer-spec) @dots{}) body
@defspecx letrec-syntax ((name transformer-spec) @dots{}) body
[R5RS]
@end defspec

@defspec syntax-rules literals clause1 clause2 @dots{}
[R5RS]
@end defspec


@node Traditional Macros, Macro expansion, Hygienic Macros, Macros
@section Traditional Macros
@c NODE 伝統的なマクロ

@defspec define-macro name procedure
@defspecx define-macro (name . formals) body @dots{}
@c EN
Defines @var{name} to be a global macro whose transformer is @var{procedure}.
The second form is a shorthand notation of the following form:
@c JP
変換子が @var{procedure} である大域マクロ @var{name} を定義します。
2番目のフォームは、以下のフォームの簡易記法です。
@c COMMON
@example
(define-macro name (lambda formals body @dots{}))
@end example

@c EN
When a form @code{(name @var{arg} @dots{})} is seen by the compiler,
it calls @var{procedure} with @var{arg} @dots{}.  When @var{procedure}
returns, the compiler inserts the returned form in place of the original
form, and compile it again.
@c JP
コンパイラが @code{(name @var{arg} @dots{})} というフォームを見つけると、
@var{arg} @dots{} を引数として @var{procedure} を呼び出します。
@var{procedure} が戻ると、コンパイラは元のフォームの場所に返されたフォームを
挿入し、再度それをコンパイルします。
@c COMMON
@end defspec

@node Macro expansion, Macro utilities, Traditional Macros, Macros
@section Macro expansion
@c NODE マクロの展開

@defun macroexpand form
@defunx macroexpand-1 form
@c EN
If @var{form} is a list and its first element is a variable
globally bound to a macro, @code{macroexpand-1}
invokes its macro transformer and
returns the expanded form.  Otherwise, returns @var{form} as is.

@code{macroexpand} repeats @code{macroexpand-1} until the
@var{form} can't be expanded.

These procedures can be used to expand globally defined macros.
@c JP
@var{form} がリストで、その最初の要素が大域的にマクロに束縛された
変数であるならば、@code{macroexpand-1}はそのマクロ変換子を実行し、
展開されたフォームを返します。そうでなければ、@var{form} をそのまま
返します。

@code{macroexpand} は、@var{form} が展開できなくなるまで
@code{macroexpand-1} を繰り返します。

これらの手続きは、大域的に定義されたマクロを展開するために使うことが
できます。
@c COMMON
@end defun

@defspec %macroexpand form
@defspecx %macroexpand-1 form
@end defspec

@node Macro utilities,  , Macro expansion, Macros
@section Macro utilities
@c NODE マクロユーティリティ

@defmac syntax-error msg arg @dots{}
@defmacx syntax-errorf fmt arg @dots{}
@c EN
Signal an error.  They are same as
@code{error} and @code{errorf} (@xref{Signalling exceptions}),
except that the error is signalled at macro-expansion time
(i.e. compile time) rather than run time.

They are useful to tell the user the wrong usage of macro in
the comprehensive way, instead of the cryptic error from the macro
expander.   Because of the purpose, @var{arg} @dots{} are first
passed to @code{unwrap-syntax} described below, to strip off
the internal syntactic binding informations.
@c JP
これらは@code{error}と@code{errorf} (@ref{Signalling exceptions}参照) と
ほぼ同じですが、実行時ではなくマクロ展開時(すなわち、コンパイル時)に
エラーを通知するところが異なります。

これらの手続きは、マクロの誤った使い方を、
マクロ展開ルーチンの出す複雑なエラーではなく、
分かりやすい方法でユーザーに通知するのに使えます。
そのため、@var{arg} @dots{}はまず下に述べる@code{unwrap-syntax}に渡されて
内部の構文的束縛情報を取り除いた後でこれらの手続きに渡されます。
@c COMMON

@example
(define-syntax my-macro
  (syntax-rules ()
    ((_ a b)   (foo2 a b))
    ((_ a b c) (foo3 a b c))
    ((_ . ?)
     (syntax-error "malformed my-macro" (my-macro . ?)))))

(my-macro 1 2 3 4)
  @result{} @r{error: "malformed my-macro: (mymacro 1 2 3 4)"}
@end example

@end defmac

@defun unwrap-syntax form
@c EN
Removes internal syntactic information from @var{form}.
In order to implement a hygienic macro, macro expander replaces
symbols in the macro form for identifiers, which captures the
syntactic environment where they are defined.  Although it is
necessary information for the compiler, it is rather confusing
for users if it appears in the messages.  This function
replaces occurrences of identifiers in @var{form} to the original
symbols.
@c JP
@var{form}の内部的な構文情報を取り除きます。
健全なマクロの実装のために、マクロ拡張ルーチンはマクロ内のシンボルを
識別子(identifier)に置き換えます。識別子はそれが現れる構文的環境を
捕捉します。それはコンパイラに取っては必要な情報ですが、
エラーメッセージに現れるとユーザーを混乱させるもとにもなります。
そこで、この手続きでは@var{form}中の識別子をもとのシンボルに
置換しなおします。
@c COMMON
@end defun

@c Local variables:
@c mode: texinfo
@c coding: utf-8
@c end:
