<1> 記法: トークンと区切り文字 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

# 1. 記法: トークンと区切り文字

## 1.1. 区切り文字 (Token Separators)

### コメント (Comment)

#### ・行コメント

> Pascal の文法を理解してくると、行コメントは Pascal という言語には異質な存在と思えるようになってきます (多分)。

C 言語もそうですが、Pascal は基本的にどこで改行しても構いません。改行コードは区切り文字の一種なので、文字列中に改行コードを含めたりはできませんが、改行なしでダラダラと一行プログラムを書く事ができます。既存のコードから改行コードが失われてもコンパイル可能です。

...が、この行コメント (`//`) を使用した場合、改行コードが失われるとコンパイルできなくなってしまいます。このためか、C 言語においても C99 になってやっと行コメントが追加されています。この行コメントは元を辿れば **BCPL** 由来です。

なお、可読文字だけで (制御文字を落としても) コンパイルできるようにしようと思うと、タブ文字 (0x09) も使ってはいけない事になります。

#### ・範囲外コメント (見出し領域)
**Pascal 6000-3.4 (Revised Report)** では、72 文字を超えて書かれたコードはコメント扱いになっていました。コンパイラ指令 `{$U-}` を指定すると、拡張されて 120 文字までが有効なコードとなります。COBOL の**見出し領域**のような拡張となっています。

#### ・XML ドキュメントコメント

Delphi 2007 以降、トリプルスラッシュ (`///`) で始まるコメントは **XML ドキュメントコメント**として扱われます。

**See also:**

 - [Delphi と XML ドキュメントコメント (Qiita)](https://qiita.com/ht_deko/items/2d26726e6e86972e8e5c)

## 1.2. 特殊シンボルと予約語

#### 特殊シンボル (Special-symbols)

#### 予約語 (Word-symbol / Reserved-word)

#### ・予約語 (Modula-2 の場合)

**Modula-2** では予約語をすべて大文字で記述する必要があります。嫌な人にはとても嫌な制約だと思いますが、プレーンテキストでも視認性がいいというメリットもあります。入力 (写経) しやすいかと言われると...

```text:Queens.mod
MODULE Queens;
  FROM InOut IMPORT WriteInt, WriteLn;
VAR
  i: INTEGER;
  q: BOOLEAN;
  a: ARRAY [ 1.. 8] OF BOOLEAN;  
  b: ARRAY [ 2..16] OF BOOLEAN;  
  c: ARRAY [-7.. 7] OF BOOLEAN;  
  x: ARRAY [ 1.. 8] OF INTEGER;  

PROCEDURE Try(i: INTEGER; VAR q: BOOLEAN);  
VAR
  j: INTEGER;
BEGIN
  j := 0;
  REPEAT
    j := j+1; q := FALSE;
    IF a[j] AND b[i+j] AND c[i-j] THEN
      x[i] := j;
      a[j] := FALSE; b[i+j] := FALSE; c[i-j] := FALSE;
      IF i<8 THEN
        Try(i+1, q);
        IF NOT q THEN
          a[j] := TRUE; b[i+j] := TRUE; c[i-j] := TRUE;
        END
        ELSE
          q := TRUE;
      END
    END
  UNTIL q OR (j=8)
END Try;  

BEGIN
  FOR i:= 1 TO  8 DO a[i] := TRUE END;
  FOR i:= 2 TO 16 DO b[i] := TRUE END;
  FOR i:=-7 TO  7 DO c[i] := TRUE END;
  Try(1, q);
  FOR i:= 1 TO 8 DO WriteInt(x[i], 4) END;
  WriteLn
END Queens.
```

**Modula-2** の予約語一覧は次の通りです (PIM4)。

```
AND             FOR             QUALIFIED
ARRAY           FROM            RECORD
BEGIN           IF              REPEAT
BY              IMPLEMENTATION  RETURN
CASE            IMPORT          SET
CONST           IN              THEN
DEFINITION      LOOP            TO
DIV             MOD             TYPE
DO              MODULE          UNTIL
ELSE            NOT             VAR
ELSIF           OF              WHILE
END             OR              WITH
EXIT            POINTER         
EXPORT          PROCEDURE 
```

## 1.3. 識別子 (Identifiers)

#### ・識別子の長さに制限がある処理系について

> Delphi の場合、識別子の長さに制限はありませんが、有効なのは最初の 255 文字だけです。標準 Pascal は実装依存ですが、最初の 8 文字しか有効でないものもあるようです。

**Revised Report** では識別子の最初の 8 文字だけが有効とされています。**Apple ][** や **///** の Pascal の識別子は 8 文字まで、**MPW Pascal** が 63 文字まででした。

**See also:**

 - [標準 Pascal の規格票と解説書を読んでみる (Qiita)](https://qiita.com/ht_deko/items/091661d6fa3d72700a56)
 - [<2> Clascal のオブジェクト指向拡張 (Pascal へのオブジェクト指向拡張の歴史と Delphi) (Qiita)](https://qiita.com/ht_deko/items/770f2db98c9cf3e8ef7b)
 - [<3> Macintosh 用 Pascal のオブジェクト指向拡張 (Pascal へのオブジェクト指向拡張の歴史と Delphi) (Qiita)](https://qiita.com/ht_deko/items/cd245180363e1911afa7)


## 1.4. 数値 (Numbers)

#### ・n 進数 (拡張 Pascal の場合)

**拡張 Pascal** では `基数#数値` という書式で任意の基数 (2～36) による値を表現できます。

```
13#42 { the answer to the ultimate question of life,
        the universe, and everything }
```

これは **Ada** 由来のようです (Ada では 2 ≦ 基数 ≦ 16)。

#### ・8 / 16 進数 (Modula-2 の場合)
**Modula-2** では 16進値の後に `H` というポストフィクスを付けて 16進値を表現する事ができます。8進値のポストフィクスは `B` です。

```Pascal
BEEFH { 48879 }
7777B { 4095 }
```

#### ・2 進数 (mikroPascal の場合)

mikroElektronika 社の『[mikroPascal](https://www.mikroe.com/mikropascal-pic)』もまた、2 進数を `%` で表記します。

```pascal
11      // decimal literal
$11     // hex literal, equals decimal 17
0x11    // hex literal, equals decimal 17
%11     // binary literal, equals decimal 3
```

 - [mikroPascal PRO for PIC Language Reference (mikroElektronika)](https://download.mikroe.com/documents/compilers/mikropascal/pic/help/mikropascal_language_reference.htm)


## 1.5. 文字列 (Character-strings)

### (1.5.1.) 制御文字列

**Modula-2** では 8進値のポストフィクスとして `C` を付けると文字として扱われます。

```Pascal
101C { ASCII: 'A' }
```

### (1.5.2.) キャレット記法 (Caret notation)

ASCII コードとの対応表です。

|16進値|文字|キャレット記法|
|:---:|:---:|:---:|
|0x00|NUL|^@|
|0x01|SOH|^A|
|0x02|STX|^B|
|0x03|ETX|^C|
|0x04|EOT|^D|
|0x05|ENQ|^E|
|0x06|ACK|^F|
|0x07|BEL|^G|
|0x08|BS|^H|
|0x09|HT|^I|
|0x0A|LF/NL|^J|
|0x0B|VT|^K|
|0x0C|FF/NP|^L|
|0x0D|CR|^M|
|0x0E|SO|^N|
|0x0F|SI|^O|
|0x10|DLE|^P|
|0x11|DC1|^Q|
|0x12|DC2|^R|
|0x13|DC3|^S|
|0x14|DC4|^T|
|0x15|NAK|^U|
|0x16|SYN|^V|
|0x17|ETB|^W|
|0x18|CAN|^X|
|0x19|EM|^Y|
|0x1A|SUB/EOF|^Z|
|0x1B|ESC|^[|
|0x1C|FS|^\\ |
|0x1D|GS|^]|
|0x1E|RS|^^|
|0x1F|US|^_|
|0x20|SP|^`|
|0x3B|;|^{|
|0x3C|<|^||
|0x3D|=|^}|
|0x3E|>|^~|
|0x60|`|^(SP)|
|0x61|a|^!|
|0x62|b|^"|
|0x63|c|^#|
|0x64|d|^$|
|0x65|e|^%|
|0x66|f|^&|
|0x67|g|^'|
|0x68|h|^(|
|0x69|i|^)|
|0x6A|j|^*|
|0x6B|k|^+|
|0x6C|l|^,|
|0x6D|m|^-|
|0x6E|n|^.|
|0x6F|o|^/|
|0x70|p|^0|
|0x71|q|^1|
|0x72|r|^2|
|0x73|s|^3|
|0x74|t|^4|
|0x75|u|^5|
|0x76|v|^6|
|0x77|w|^7|
|0x78|x|^8|
|0x79|y|^9|
|0x7A|z|^:|
|0x7B|{|^;|
|0x7C| \| |^\< |
|0x7D|}|^=|
|0x7E|~|^\> |
|0x7F|DEL|^?|

## 1.6. ラベル (Labels)

## 1.7. 指令 (Directives)

### (1.7.1.) ヒント指令 (Hint directives)

### (1.7.2.) コンパイラ指令 (Compiler directives)

#### ・オリジナル Pascal のコンパイラ指令

コンパイラ指令は

 - [The programming language Pascal (1970)](https://www.research-collection.ethz.ch/handle/20.500.11850/68712)
 - 『J&W (第 2 版以前)』の **Pascal 6000** の説明 (`第 14 章 Pascal 600-3.4 システムの使用法`) 

に記述がありますが互いに互換性はありません。

#### ・PASCAL-P4 /P5 のコンパイラ指令

**PASCAL-P4 / P5** にもコンパイラ指令があります。

| オプション | 意味 | デフォルト |
|:---:|:---|:---:|
| T | 各ルーチンがコンパイルされた後に、内部テーブルを印刷する/しない。| T- |
| L | コンパイル時にソースプログラムをリストアップする/しない。| L+ |
| D | 配列の境界、部分範囲型などをチェックするためのコードを追加する/しない。 | D+ |
| C | 中間形式ファイルへ出力する/しない。 | C+ |

オプションはカンマ区切りで複数指定できます。デフォルトの設定を書き出すと `{$T-,L+,D+,C+}` または `(*$T,L+,D+-,C+*)` という具合になります。

```pascal:optiontest.pas
(*$t-,l+,d+,c+*)
program optiontest(output);
var
  i: integer;
begin
  for i:=1 to 10 do
    writeln('Hello, world.');
end.
```

`L` オプションは `{$L-}` と `{$L+}` のようにしてコードブロックを挟みこむことにより、コンパイル時に一部のコードだけをリストアップしたり、一部のコードだけを非表示にする事ができます。

:::note warn
PASCAL-P4 ではオプションは小文字で記述する必要があります。
また、オプションは (*\$ *) で括る必要があります。
オリジナルの PASCAL-P4 ではオプション C の意味が逆なため、デフォルトは (*\$t-,l+,d+,c-*) となっています。
:::

:::note warn
PASCAL-P5 では {\$C-} が正しく動作しません。
:::

**See also:**

 - [『PASCAL』 - Wirth 先生の邦訳本を読んでみる (Qiita)](https://qiita.com/ht_deko/items/3086b7cff08928eca7a9#pascal-pascal)
 - [Chapter 1: Input and Lexical Analysis - Pascal Implementation (Steven Pemberton)](https://homepages.cwi.nl/~steven/pascal/book/1lexical.html#options)

### (1.7.3.) 呼び出し規約に関連する指令

16bit 環境で使われていた呼び出し規約に関わる指令は次の通りです。

```
export far near
```

| 指令 | 説明 |
|:---|:---|
| **export**  | export する DLL のルーチンに付与する必要があります  |
| **far**  | 8086 の far CALL / RET に相当します |
| **near**  | 8086 の near CALL / RET に相当します |

## (1.8.) 属性 (Attributes)

### (1.8.1.) コンパイラ属性 (Compiler Attributes)

#### (1.8.1.1.) [Ref] コンパイラ属性

#### (1.8.1.2.) [Unsafe] コンパイラ属性
 
#### (1.8.1.3.) [Volatile] コンパイラ属性

#### (1.8.1.4.) [Weak] コンパイラ属性

# 索引
[:ramen:](https://qiita.com/ht_deko/items/ce1f56017fb4fcf0302a) [ [← 0. はじめに〔裏〕](https://qiita.com/ht_deko/items/017489388d859692ddbb) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 2. データの概念: 単純型〔裏〕](https://qiita.com/ht_deko/items/e36898d7aa4bb3300f78) ]