GaucheはR7RS Schemeのパーザをいくつかの点で拡張しています。 また、歴史的経緯から、デフォルトの字句構文の中に、R7RSの仕様と相反するものが いくつかあります。リーダのモードを設定することで、 R7RS互換にすることもできます。
#!で始まるトークンはリーダに特別な影響を与えます。
R7RSではそういった指示子がふたつ定義されています。
シンボルのリード時に大文字小文字を無視するかしないかを
切り替える、#!fold-caseと#!no-fold-caseです。
Gaucheで使える指示子の一覧については、下のHash-bangトークンを参照してください。
Gaucheは、R6RSの[]を()と同様に扱う構文規則を採用しています。
どちらの括弧も全く等価ですが、それぞれの開き括弧と閉じ括弧は対応していなければなりません。
括弧を混ぜることに眉をひそめる熟練のLisperもいますが、
括弧の種類を使い分けるのは、括弧の役割を視覚的に識別するのに役に立ちます。
一般的な慣習は、関数とマクロ呼び出し以外のグルーピングには[]を使う、
というものです。ただしそのようなグルーピングがネストする場合は、外側には()を
使います。例:
(cond [(test1 x) (y z)]
[(test2 x) (s t)]
[else (u v)])
(let ([x (foo a b)]
[y (bar c d)])
(baz x y))
この記法は、必ず従わなければいけないというものではありません。
R7RSではこの構文を採用せず、[]は言語拡張用に取ってあるので、
ポータブルなR7RSプログラムを書く場合は()だけを使うのが良いでしょう。
(リーダがstrict-r7モードの時は、[]が使われていたら
エラーが通知されます。詳しくはリーダー字句モード参照。)
エディタのSchemeモードの中には、)をタイプするとそれがどちらの
種類の括弧を閉じるかに応じて自動的に]か)を選んで挿入してくれる
ものがあります (EmacsのQuackなど)。この記法を使うときは
そういったモードを活用すると良いでしょう。
シンボル名はデフォルトで大文字小文字を区別します (大文字小文字の区別参照)。
数字や’+’, ’-’ で始まるシンボル名も、
トークンが有効な数値リテラルを構成しない限り許されます。
また、他の変な文字も ’|’ でシンボルを囲むことによってシンボル名に含めることが
できます (例:’|this is a symbol|’)。
シンボルも参照して下さい。
GaucheはR7RSのオプショナルな数値構文と、Gauche特有の拡張をサポートしています。
非正確な実数の整数部または小数部のいずれかが0の場合、それを省略することが
できます。例:30., .25, -.4。
数値リテラル中に ’#’ を含めることができます。これは使われ方によって
次の二つの異なる意味を持ちます。
#で終わっている場合、それは「重要でない
(有効数字外の)桁」を意味します(この構文はR5RSに含まれていました)。
Gaucheはそれらの桁を0で置き換えます。
#の連続は整数部から始まって小数点を
またいでも構いません。この表記がある数値リテラルは、小数点や指数部を
持たなくても、明示的な正確数プレフィクスがない限りは非正確数となります。
例: 12##.## ≡ 1200.00、
0.123##e5 ≡ 0.12300e5、
1##+2##i ≡ 100+200i。
#がありその後にひとつ以上の数字が続いている
場合、それは循環小数を表します。
#の後に続く桁が無限に繰り返されていると解釈されます。
例えば0.#3は0.33333333…の意味です。
おもしろいのは、正確数を指定した場合です。
#e0.1#142857は4/35になります (つまり、1/10 + 1/70)。
複素数表記は直交座標形 (例:1+0.3i) でも
極座標形 (例:3.0@1.57) でも認識されます。
極座標記法において、Gaucheではサフィックスpiをつけることにより
偏角をπの係数で表すことができます。Schemeの構文では偏角はラジアンですが、
πは浮動小数点数では近似値でしか扱えないので、偏角ゼロ以外で切りの良い数値を
表現することができません。
gosh> 2@3.141592653589793 -2.0+2.4492935982947064e-16i
piサフィックスを使うと切りの良い数値が書けます。
gosh> 2@1pi -2.0 gosh> 2@0.5pi 0.0+2.0i gosh> 2@-0.5pi 0.0-2.0i
複素数の直交座標表記として、GaucheはCommon Lisp形式
(例: #c(1.0 2.0)、1.0+2.0iと同じ)も認識します。
これはCommon Lispプログラムとデータ交換をする場合に便利です。
非正確な実数は、正の無限大、負の無限大、非数(NaN)を含み、
それらはそれぞれ+inf.0、-inf.0、および+nan.0と
表記されます。(-nan.0も非数(NaN)として読まれます)。
Gaucheはまた、SRFI-169 (数値中のアンダースコア)構文をサポートしています。
読みやすくするために、数値中に_を挿入することができます
(例: #b1100_1010_1111_1110)。
ただし、各アンダースコアは数字に囲まれていなければなりません。
1_2_3はokですが、_123、123_、12__3は
有効な数値リテラルではありません。
Gaucheはまた、Common Lisp風の基数を明示した数値リテラルも認識します。
例えば3進数の120は#3r120と書けます(10進数で15)。2進数から36進数まで
認識されます。10進数より上ではa-zA-Zのアルファベットを使えます。
いくつかのリテラル中では、文字をその文字コードの16進数表記で記入できます。 具体的には、文字、文字集合、文字列、シンボル、正規表現リテラルです。
R7RSは文字列および縦棒で囲まれたシンボル中では\xNNNN;、文字単独では
#\xNNNNというエスケープ構文を採用しました。16進数の桁数は可変で、
文字コードはUnicodeコードポイントです。
Gaucheは歴史的に2種類のエスケープを使ってきました。
\uと\xです。
uはUnicodeコードポイントに、xは内部エンコーディングによる
文字コードに使っていました。また、文字リテラル以外では
16進数の桁数は固定で、したがってR7RSのような終端文字(;)を必要としませんでした。
0.9.4からは、\xエスケープはそれが正しいR7RSの16進エスケープと解釈できる
限りはそう読まれます。R7RSの構文に合致しない場合は、以前のGaucheの構文とみなされます。
滅多にないことですが、R7RSとも以前のGauche構文ともみなすことができて、しかし解釈に違いが 生じるような場合というのが存在します。そのようなリテラルを含む昔のソースを 現在のGaucheで読むと、予想外の動作が起きるかもしれません。 その場合は、リーダのモードを以前との互換モードに変更できます。 詳細はリーダー字句モードを参照してください。
’#’ で始まる特殊構文がたくさん定義されています。
下の表を参照して下さい。
| • #構文: | ||
| • Hash-bangトークン: |
以下の表はシャープ構文のリストです。
#! | [R6RS][R7RS][SRFI-22] これは、スクリプトのインタプリタ指定行(shebang)の 開始を示すか、リーダのモードに影響を与える特別なトークンとして読まれます。 下の‘hash-bang token’の節を参照してください。 |
#" | 補間された文字列を先導します。文字列の補間参照。 |
##, #$, #%, #&, #' | 未使用。 |
#( | [R7RS] リテラルベクタ表記の開始です。 |
#) | 未使用。 |
#* | [SRFI-178] ビットベクタ(あるいは不完全な文字列)。ビットベクタ参照。 |
#+ | 未使用。 |
#, | [SRFI-10] リーダ構築子構文を開始します。 |
#-, #. | 未使用。 |
#/ | リテラルの正規表現を先導します。正規表現参照。 |
#0 … #9 | #n#, #n=: [SRFI-38] 共有サブストラクチャの定義と参照。#nR, #nr: 基数を明示した数値リテラル。#na, #ns8, #nu8, … #nc128: [SRFI-163] 配列リテラル。 配列のリテラル構文参照。 |
#: | インターンされていないシンボル。シンボル参照。 |
#; | [SRFI-62] S式コメント。続くS式をひとつ読んで捨てます。 |
#< | 読み取り不可能オブジェクトを先導します。 |
#=, #> | 未使用。 |
#? | デバッグマクロを先導します。デバッグ参照。 |
#@ | 未使用。 |
#a | 未使用。 |
#b | [R7RS] 2進数接頭辞。 |
#c | (1) [R7RS] 複素数ユニフォームベクタ (#c32(...), #c64(...),
#c128(...)。ユニフォームベクタ参照。(2) Common Lisp風の複素数表記。 #c(1.0 2.0)は1.0+2.0iです。
出力制御参照。 |
#d | [R7RS] 10進数接頭辞。 |
#e | [R7RS] 正確数接頭辞。 |
#f | [R7RS] 真理値の偽、あるいは
R7RS のユニフォームベクタを先導します。ユニフォームベクタ参照。
R7RSでは真理値の偽として#fと#falseが使えます。 |
#g, #h | 未使用。 |
#i | [R7RS] 非正確数接頭辞。 |
#j, #k, #l, #m, #n | 未使用。 |
#o | [R7RS] 8進数接頭辞。 |
#p, #q, #r | 未使用。 |
#s | [R7RS vector.@] R7RSのユニフォームベクタを先導します。ユニフォームベクタ参照。 |
#t | [R7RS] 真理値の真。R7RSでは真理値の真として#tと#trueが使えます。 |
#u | [R7RS vector.@] R7RS のユニフォームベクタを先導します。ユニフォームベクタ参照。
R7RSもバイトベクタに#u8のプリフィクスを使いますが、これは
u8ユニフォームベクタと互換です。 |
#v, #w | 未使用。 |
#x | [R7RS] 16進数接頭辞 |
#y, #z | 未使用。 |
#[ | リテラルの文字集合を先導します。文字集合参照 |
#\ | [R7RS] リテラルの文字を先導します。文字参照。 |
#], #^, #_ | 未使用。 |
#` | 文字列補間の古い構文です。新しいコードでは#"を使ってください。 |
#{ | 未使用。 |
#| | [SRFI-30] ブロックコメントを先導します。コメントは対応する ’|#’ で終ります。 |
#}, #~ | 未使用。 |
文字シーケンス#!は、どこでどのように現れるかによって2つの全く異なる
意味を持ちます。
ファイルが#!/もしくは#! (ハッシュ、バング、空白) から始
まっている場合、読み込みルーチンはそれをスクリプトのインタプリタ指定行
(shebang) とみなし、最初の行末までを無視します。
(実際は、ソースはファイルでなくても構いません。リーダはポートの先頭かどうかで
判断します。)
その場合以外では、#!identifierがひとつのトークンとして読ま
れ、特別な意味を持ちます。この種のトークンはデータとして読まれるのでは
なく、リーダに対して特別な指定を与えることもあります。
デフォルトでは、以下のトークンが認識されます。
#!fold-case#!no-fold-caseリーダが大文字小文字を区別するかどうかを切り替えます。
#!fold-caseに出会うとリーダは大文字小
文字を区別しないモードになり、#!no-fold-caseに出会うとその逆にな
ります。(大文字小文字の区別も参照してください。)
#!r6rsこのトークンはR6RSで導入され、プログラムがR6RSに準拠しているこ とを示します。GaucheはR6RSに準拠していませんが、今のところこのトー クンに出会っても警告を出すだけで読み込みは継続します。
#!r7rsリーダをR7RSに準拠したstrict-r7モードにします。
詳細はリーダー字句モードを参照してください。
#!gauche-legacyリーダをGauche 0.9.3およびそれ以前のものと互換なlegacyモードにします。
詳細はリーダー字句モードを参照してください。