ソースコードの文法

この章ではパステルステッチのソースコード (source code) の文法を規定する。

コードブロック

パステルステッチのソースコードは 0 個以上のコードブロック (code block) から成る。コードブロックは ^code 構文抽出器キーワードで始まり、^endcode 構文抽出器キーワードで終わる。コードブロックの外はコメントであり、^code 構文抽出器キーワードを除く任意の文字列を書くことができる。^code 構文抽出器キーワードから次の改行まではコードブロックキャプション (code block caption) である。コードブロックキャプションもコメントであり、改行を除く任意の文字列を記述できる。コードブロックの内部には 0 個以上のブロックまたは文を記述する。

以下に例を示す。この例では Simple program がコードブロックキャプションである。コメントを除いた実際のプログラムは print: ^[Hello world!] ^! の 1 行である。

^code Simple program
print: ^[Hello world!] ^!
^endcode

ブロック

ブロック (block) はブロック開始語 (block beginning word) で始まる。ただしブロック開始語の前後に空白があってもよい。ブロック開始語はいずれも構文抽出器キーワードであり、以下の 7 種類がある。

ブロックを開始してから最初の改行までがブロック開始文 (block beginning statement) である。ブロック開始文は引数 (argument) を持つ場合と持たない場合がある。引数を持たないブロック開始文は、ブロック開始語と改行 (line break) から成る。引数を持つブロック開始文は、単独引数形式 (single argument form) と複数引数形式 (multi-argument form) がある。単独引数形式のブロック開始文は、ブロック開始語、式 (expression)、改行から成る。複数引数形式のブロック開始文は、ブロック開始語、引数列 (arguments)、改行から成る。これらの要素の前後に空白があってもよい。

ブロック開始文に続いて 0 個以上のブロックまたは文が続く。ブロックはブロック終了文 (block ending statement) で終わる。ブロック終了文は構文抽出器キーワード ^end と改行から成る。ブロック終了語の前後に空白があってもよい。

以下の例では procedure ブロックと mulde ブロックを使用している。procedure ブロックは単独引数形式の引数を持っている。mulde ブロックは引数を持っていない。

^code Block
^procedure proc
 print: ^[procedure] ^!
^end
^mulde
 print: ^[mulde] ^!
 proc
^end
^endcode

以下の例では mulde, mulde, procedure の順にブロックを入れ子にしている。

^code Block nesting
^mulde
 print: ^[external] ^!
^mulde
  print: ^[mulde] ^!
  ^procedure internal
   print: ^[internal] ^!
  ^end
^end
^end
^endcode

^endcode 構文抽出器キーワードはコードブロックを閉じる。このとき、閉じていないブロックがあると、それらのブロックはすべて閉じられる。例えば、上の例は以下のように書き直すことができる。

^code Block and endcode
^mulde
 print: ^[external] ^!
^mulde
  print: ^[mulde] ^!
  ^procedure internal
   print: ^[internal] ^!
^endcode

文 (statement) は統合演算形式と改行から成る。統合演算形式の前後に空白を入れてもよい。

統合演算形式と改行から成る文を統合演算文 (unified operation statement) という。この文書では、文はすべて統合演算文である。

互換性についての注意 過去の言語仕様では倒置文が規定されていた。言語仕様 2015 では倒置文が廃止された。

統合演算形式

統合演算形式 (unified operation form) は引数を持つ場合と持たない場合がある。引数を持たない場合、統合演算形式は 1 個の式である。その式は演算指定子 (operation specifier) と呼ばれる。統合演算形式が引数を持つとき、その引数は単独引数形式または複数引数形式である。いずれの場合にも、統合演算形式は、式、コロン、引数から構成される。これらの要素の前後に空白があってもよい。このとき最初の式は演算指定子である。

単独引数形式は 1 個の式である。複数引数形式は 1 個以上のラベル付き引数の列である。それぞれのラベル付き引数の前後に空白があってもよい。

ラベル付き引数 (labeled argument) は、名前 (name) と、分離可能な式 (separable expression) から成る。これらの要素の前後に空白があってもよい。

以下の例では、writeprint が演算指定子である。write で始まる統合演算形式の引数は複数引数形式で、引数は tovalue の 2 個である。print で始まる統合演算形式の引数は単独引数形式である。

^code Arguments
write: to (hello) value ^[Hello world!] ^!
write: to (world) value [hello]
print: [world]
^endcode

文字列 (string) と浮動小数点数 (floating point number) は式 (expression) である。式をパーレン (parenthesis) で囲んだものは式である。統合演算形式をブラケット (bracket) で囲んだものは式である。これを統合演算式 (unified operation expression) という。これらの式は分離可能な式である。

複合名 (compound name) と、式を演算子 (operator) で結合したものは式である。これらは分離可能な式ではない。

演算子

演算子 (operator) は以下のものがある。

算術演算子は ∗, /, ;, +, − の 5 種類である。 演算子の優先順位 (order of operators) は、 /;+ よりも強い。

互換性についての注意 過去の言語仕様とは / 演算子の優先順位が異なるため、プログラムの書き換えが必要になる場合がある。

^code Arithmetic binary operators
print: 10 ∗ 20
write: to (a) value (30 + 40 ∗ 50)
print: (100 + 200) / (300 + 400)
write: to (b) value ((500 ∗ 600) / 700 + 800)
^endcode

左辺のないマイナス記号は −1 倍を表す。また、右辺のないプラス記号は offsetargument 複合名が省略されているとみなす。以下に例を示す。

^code
write: to (a +) value ((−20) ∗ 10 + (−10 ∗ 20))
print: [a +]
^endcode

集合演算子は和集合、積集合、差集合の 3 種類がある。和集合はコンマで表される。積集合と差集合は構文抽出器キーワードを演算子として用いる。積集合は ^intersection であり、差集合は ^setminus である。演算子の優先順位は積集合と差集合が同列で、和集合はそれよりも弱い。以下に例を示す。

^code Binary operators for sets
write: to (set a) value (a ^intersection b ^setminus c, d ^setminus e)
write: to (set b) value (a, b, c, d, e)
^endcode

型変換演算子 (type conversion operator) は ^convert 構文抽出器キーワードで表される。

比較演算子は「等しい」、「小なり」、「小なりまたは等しい」、「部分集合」、「型比較」の 5 種類がある。「等しい」と「小なり」はそれぞれ記号 =< を用いる。続く 3 種類は構文抽出器キーワードで表される。それらは順に ^le, ^subset, ^type である。以下に例を示す。

^code Relational operators
^if 10 < 20 ^and 20 ^le 30
^if 100 = 100 ^and ^not 100 = 200
  ^if (a, b) ^subset (a, b, c)
   print: ^[relational operators] ^!
^endcode

論理演算子は論理和、論理積、論理否定の 3 種類がある。論理和と論理積の記号はそれぞれ ^or^and である。論理否定の記号は ^not^unless の 2 種類があり、動作は同じだが優先順位が異なる。優先順位は ^not, ^and, ^or, ^unless の順である。以下に例を示す。

^code Boolean operators
^if ^unless false ^and true ^or ^not true ^and true
 print: ^[boolean operators] ^!
^endcode

書き込み演算子 (writing operator) は ^write 構文抽出器キーワードで表される。

シーケンシャル演算子 (sequential operator) は &^return-and-then の 2 種類がある。いずれも左辺と右辺をこの順に計算する。& の戻り値は右辺と等しく、^return-and-then の戻り値は左辺と等しい。

演算子の総合的な結合順位は算術演算子、集合演算子、型変換演算子、比較演算子、論理演算子、書き込み演算子、シーケンシャル演算子の順である。

演算子の一覧を以下の表に示す。

表記意味優先順位
積算 1
/ 除算 1
; 有理数 1
+ 加算 2
減算 2
^intersection 積集合 3
^setminus 差集合 3
, 和集合 4
^convert 型変換 5
= 等しい 6
< 小なり 6
^le 小なりまたは等しい 6
^subset 部分集合 6
^type 型比較 6
^not 論理否定 7
^and 論理積 8
^or 論理和 9
^unless 論理否定 10
^write 書き込み演算子 11
& シーケンシャル演算子 12
^return-and-then シーケンシャル演算子 12

複合名

パステルステッチの複合名 (compound name) は以下の形式で記述できる。

オブジェクトコードでは、複合名は固有名 (personal name) と姓 (family name) の組である。ソースコードで、姓を記号で指定する形式または姓を省略する形式を使用した場合は、構文抽出器が姓を推定する。

姓を明示する形式は、固有名と姓をこの順に記述する。これらの要素の前後に空白があってもよい。固有名は名前である。姓は、^( 構文抽出機キーワード、名前、右パーレンの順に記述する。この文書では姓は上付き文字で表現される。

姓を記号で指定する形式では、固有名の前または後に、姓を表す記号 (family name symbol) を記述する。これらの要素の前後に空白があってもよい。姓を表す記号はナンバーサイン、ドル、アットマーク、アポストロフィーである。

姓を省略する形式では、単に固有名を記述する。

姓を記号で指定する形式、または、姓を省略する形式では、^name 構文抽出器ディレクティブ (syntactic abstractor directive) で姓を指定する。姓を記号で指定する形式に対する ^name 構文抽出器ディレクティブは、^name 構文抽出器キーワード、姓を表す記号、名前、改行で構成される。これらの要素の前後に空白があってもよい。姓を省略する形式に対する ^name 構文抽出器ディレクティブは、^name 構文抽出器キーワード、名前、改行で構成される。これらの要素の前後に空白があってもよい。

^name 構文抽出器ディレクティブの有効範囲は、それが記述された位置から、^endcode 構文抽出器キーワードまでである。有効な ^name 構文抽出器ディレクティブがない場合、姓を省略する形式で推定される姓は main である。また、有効な ^name 構文抽出器ディレクティブがない場合、姓を記号で指定する形式で推定される姓は、記号 #$ に対してそれぞれ argumentresolution argument である。有効な ^name 構文抽出器ディレクティブがない場合に、他の記号を使用したときの動作は、実装により異なる。^name 構文抽出器ディレクティブの例を以下に示す。

^code Family name symbols
^name family name 1
^name # family name 2
^name $ family name 3
^name @ family name 4
^name ' family name 5
^endcode

互換性についての注意 過去の言語仕様では、有効な ^name 構文抽出器ディレクティブがない場合、姓を記号で指定する形式で推定される姓は、記号 @' に対してそれぞれ continuation argumentargument symbol であることが規定されていた。この仕様に依存するコードは、実装によっては動作しない場合がある。

演算子に対応する複合名は、演算子をブレース (brace) で囲んだものである。演算子と固有名の対応を以下の表に示す。姓はいずれも main である。

演算子固有名
{∗}multiply
{/}divide
{;}rational number
{+}plus
{−}minus
{^intersection}intersection
{^setminus}set minus
{,}union
{^convert}convert
{=}equal
{<}less
{^le}less or equal
{^subset}subset
{^type}type
{^and}and
{^or}or
{^not}not
{^write}write
{&}and then
{^return-and-then}return and then

名前

名前 (name) はクラス 2 または 4 の文字の 1 字以上の並びである。ただし、オブジェクトコードでは、名前はクラス 4 の文字のみで構成される。構文抽出器はクラス 2 の文字を名前から除去する。

文字列

文字列 (string) は 1 個以上のアトミック文字列 (atomic string) の列である。アトミック文字列の前後に空白があってもよい。

アトミック文字列には以下の形式がある。

複数文字形式は、構文抽出器キーワード ^[ と右ブラケットの間に、クラス 2, 3, 4, 5 の文字 (ただし右ブラケットを除く) の 1 字以上の並びを挟んだものである。

単独図形文字形式は、アンダースコアーと、クラス 3 または 4 の文字から成る。

制御文字形式は、構文抽出器キーワード ^& または ^! である。それぞれ水平タブと改行を意味する。

これらの例を以下に示す。

^code Strings
print: _[_^___^_]_p_ _(_-___-_)_b ^!
print: ^[a] ^& ^[b] ^& ^[c] ^!
print: ^[aa] ^& ^[bb] ^& ^[cc] ^!
^endcode

浮動小数点数

浮動小数点数 (floating point number) は、左パーレン、構文抽出器キーワード ^float、空白、クラス 3 または 4 の文字 (ただし右パーレンを除く) の 1 字以上の並び、右パーレンの順に記述する。以下に例を示す。

^code Floating point numbers
print: (^float 3.14) + (^float 1.5e+2)
^endcode

構文抽出器キーワード

構文抽出器キーワード (syntactic abstractor keyword) は構文抽出器によって解釈されるキーワードである。構文抽出器キーワードは ASCII のキャレット記号 (caret) で始まり、いずれかの構文抽出器キーワードと一致するまで続く。

この文書では構文抽出器キーワードを色の異なる太い文字で表記する。実際の構文抽出器では文字の色と装飾は影響しない。また、姓を表す構文抽出器キーワードは、この文書では上付き文字で表記する。実際にはキャレット記号とパーレンを用いて ^(family name) のように記述する必要がある。

空白

空白 (blank) は、スペース、水平タブ、無効化された改行 (ineffective line break) の 0 個以上の並びである。無効化された改行は、改行、スペースまたは水平タブの 0 字以上の並び、大なりから構成される。パステルステッチでは、大なりの記号は比較演算子ではなく、改行を無効化する記号である。以下の例では、write: to (a quick brown fox) という行と value (jumped over the lazy dog) という行の間の改行が無効化されている。

^code Blanks
write: to (jumped over the lazy dog) value (10)
write: to (a quick brown fox)
> value (jumped over the lazy dog)
print: [[a quick brown fox]], ^!
^endcode

文字クラス

パステルステッチでは文字を以下のように分類する。以下の表に ASCII での文字コード、パステルステッチでの文字クラス (character class)、この文章での名称を示す。

文字コード (16 進法)グリフ文字クラスこの文書での名称
00-080
091水平タブ
0A1改行
0B-1F0
202スペース
21!3
22"3
23#3ナンバーサイン
24$3ドル
25%4パーセント
26&3アンパサンド
27'3アポストロフィ
28(3左パーレン
29)3右パーレン
2A*3アスタリスク
2B+3プラス
2C,3コンマ
2D-3マイナス
2E.3
2F/3スラッシュ
30-390-94算用数字
3A:3コロン
3B;3セミコロン
3C<3小なり
3D=3イコール
3E>3大なり
3F?3
40@3アットマーク
41-5AA-Z4アルファベット大文字
5B[3左ブラケット
5C\3
5D]3右ブラケット
5E^3キャレット
5F_3アンダースコアー
60`3
61-7Aa-z4アルファベット小文字
7B{3左ブレース
7C|3
7D}3右ブレース
7E~3
7F0
その他5

文字クラス 0 はパステルステッチのソースコードとオブジェクトコードに含めることができない制御文字である。

文字クラス 1 はソースコードに含めることができる制御文字である。また、文字クラス 1 の文字を文字列に含めることができるが、ソースコードでは構文抽出器キーワード、オブジェクトコードでは実態参照で表現される。

文字クラス 2 はスペースである。スペースは文字列に含めることができる。また、ソースコードでは名前にスペースを含めることができるが、オブジェクトコードではこのスペースは除かれる。

文字クラス 3 は図形文字である。ソースコードでは、アンダースコアーに続いてクラス 3 の文字を記述することにより、単独図形文字形式のアトミック文字列を記述できる。クラス 3 の文字は文字列に含めることができる。

クラス 4 の文字は名前に使用することができる。クラス 4 の文字は文字列に含めることができる。クラス 4 は算用数字、アルファベット大文字、アルファベット小文字、パーセントから成る。

ASCII 互換でない文字はクラス 5 である。文字エンコーディングが UTF-8 である場合、最上位ビットが 1 であるバイトはクラス 5 である。クラス 5 の文字は文字列に含めることができる。