Delphi における Pascal の処理系定義

# はじめに
**標準 Pascal** では処理系毎の自由度のために、規格で決まっていない (決められていない) 動作があり、これを**処理系定義**と呼びます。規格で決まっておらず、処理系毎にも定まっていない動作は**処理系依存**と呼びます。

**Pascal** に準拠した言語では、処理系定義をマニュアル等に記載する必要があるのですが、**Delphi** には記載がないため、これを調べてみようという趣旨の記事となります。


# 処理系定義

**標準 Pascal** における処理系定義は次の 13 項目です。

| 番号 | 定義 | 章 |
|:---:|:---|:---|
| 1| 文字列用文字の値|                                           6.1.7    |
| 2| 実数型の値|                                                 6.4.2.2  |
| 3| 文字値の順序数|                                             6.4.2.2  |
| 4| ファイル操作手続きの外界に対する効果|                       6.6.5.2  |
| 5| 定数名 maxint の値|                                         6.7.2.2  |
| 6| 実数演算の近似の精度|                                       6.7.2.2  |
| 7| Write() のフィールド長パラメータ TotalWidth の基準値|                     6.9.3.1  |
| 8| 実数の Write() における ExpDigits の値|                     6.9.3.4.1|
| 9| 実数の Write() における指数表現文字の大文字・小文字の別|    6.9.3.4.1|
|10| 論理値の Write() における大文字・小文字の別|                6.9.3.5  |
|11| 手続き Page() の効果|                                       6.9.5    |
|12| プログラム引数 (ファイル型) の外部実体への結び付け方|       6.10     |
|13| Input, Output に Reset(), Rewrite() を適用したときの効果|   6.10     |
                                                                            

章は ISO 8175 / JIS X 3008 のものです。

## 1. 文字列用文字の値

これは可読文字の事を指しています。Delphi では

 - シングルバイト文字 (ANSI)
 - マルチバイト文字 (ANSI)
 - ワイド文字 (Unicode)

(の可読文字) が使えます。

ソースファイルの文字コードがコード中の文字列用文字コードとして使われる訳ではありません。文字型/文字列型の種類によって使える文字セットは異なります。

**See also:**

 - [文字セット (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E6%96%87%E5%AD%97%E3%82%BB%E3%83%83%E3%83%88)
 - [HIGHCHARUNICODE 指令（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/HIGHCHARUNICODE_%E6%8C%87%E4%BB%A4%EF%BC%88Delphi%EF%BC%89)

## 2. 実数型の値

**Real** 型は `リテラルで表せる実数の部分集合` という位置付けになっていますが、Delphi での Real 型は `2.23e-308 .. 1.79e+308` の範囲の値です。

伝統的な Pascal と互換性のある実数型である **Real48** は `2.94e-39 .. 1.70e+38` の範囲の値です。

伝統的な Pascal で Real 型のデータが書かれたファイルは、

```pascal
var
  F: File of Real;
```

Delphi では Real48 を使わないと正しく読み込めない場合があります。

```pascal
var
  F: File of Real48;
```

**See also:**

 - [単純型（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E5%8D%98%E7%B4%94%E5%9E%8B%EF%BC%88Delphi%EF%BC%89#.E5.AE.9F.E6.95.B0.E5.9E.8B)
 - [Real (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Real)
 - [Real48 (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Real48)


## 3. 文字値の順序数

文字の順序値は `Ord()` 関数で調べることができます。

例えばソースコード中にリテラル文字 `'あ'` を記述した場合を考えてみましょう。次のコードは Unicode 版 Delphi で `3042` を表示します。これは `'あ'` の Unicode でのコードポイントが U+3042 であるからです。

```pascal
var
  c: Char;
  s: string;
begin
  s := 'あ';
  for c in s do
    Writeln(IntToHex(Ord(c)));
end.
```

上記コードを ANSI 版 Delphi (日本語環境の Windows) で実行するか、Unicode 版 Delphi で次のコードを実行すると `82`,`A0` が表示されます。これは `'あ'` の Shift_JIS でのコードが 82A0 であるからです。

```pascal
var
  c: AnsiChar;
  s: AnsiString;
begin
  s := 'あ';
  for c in s do
    Writeln(IntToHex(Ord(c)));
end.
```

**See also:**

 - [Ord() (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Ord)
 - [HIGHCHARUNICODE 指令（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/HIGHCHARUNICODE_%E6%8C%87%E4%BB%A4%EF%BC%88Delphi%EF%BC%89)

## 4. ファイル操作手続きの外界に対する効果
ファイル変数に結び付けられた外部実体に対して行われる実際の処理はドキュメントを参照してください。

|手続き|説明|
|:---|:---|
|[Read()](http://docwiki.embarcadero.com/Libraries/ja/System.Read)|ファイルからデータを読み込む。|
|[Readln()](http://docwiki.embarcadero.com/Libraries/ja/System.Readln)|ファイルからテキストを 1 行読み込む。|
|[Reset()](http://docwiki.embarcadero.com/Libraries/ja/System.Reset)|ファイル F を先頭に位置付け、<br>F が空でなければ F の最初の要素が<br>F^ に代入され、[Eof()](http://docwiki.embarcadero.com/Libraries/ja/System.Eof) は **False** を返す。|
|[Rewrite()](http://docwiki.embarcadero.com/Libraries/ja/System.Rewrite)|ファイル F を生成する。<br>F は空になり、[Eof()](http://docwiki.embarcadero.com/Libraries/ja/System.Eof) は **True** を返す。|
|[Write()](http://docwiki.embarcadero.com/Libraries/ja/System.Write)|ファイルにデータを書き込む。|
|[Writeln()](http://docwiki.embarcadero.com/Libraries/ja/System.Writeln)|ファイルにテキストを 1 行書き出す。|

※ Delphi では Get(), Page(), Put() は実装されていません。 


## 5. 定数名 maxint の値

Delphi 1 で `32767 ($7FFF)`、それ以外の Delphi で `2147483647 ($7FFFFFFF)` です。

**See also:**

 - [System (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System)

## 6. 実数演算の近似の精度

内部データ構造のドキュメントを参照してください。

**See also:**

 - [内部データ形式（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E5%86%85%E9%83%A8%E3%83%87%E3%83%BC%E3%82%BF%E5%BD%A2%E5%BC%8F%EF%BC%88Delphi%EF%BC%89#.E5.AE.9F.E6.95.B0.E5.9E.8B)

## 7. Write() のフィールド長パラメータ TotalWidth の基準値

**フィールド長パラメータ (Field Width Parameter)** とは Write() 及び Writeln() で指定する書き込みパラメータのうちの省略可能な 2 つのパラメータの事です。

```
OutExpr [: TotalWidth [: FracDigits ] ]
```

TotalWidth と FracDigits の事ですね。Delphi では次のように定義されています。

```
OutExpr [: MinWidth [: DecPlaces ] ]
```

次のようなコードがあったとすると、

```pascal
  Writeln(1234);
  Writeln(-1234);
```

実行結果はこのようになります。

```
1234
-1234
```

つまり、**TotalWidth (MinWidth) は 1** となります。

## 8. 実数の Write() における ExpDigits の値

Delphi における浮動小数点の表示フォーマットは次のようになっています。

`[   | - ] <digit> . <decimals> E [ + | - ] <exponent>`

```
Writeln(Pi);
```

 の結果が `" 3.14159265358979E+0000"` となりますので、**ExpDigits (exponent) は 4** となります。


:::note warn
ドキュメントには `2 桁の 10 進指数` とありますが、これは誤りだと思われます。
:::

**See also:**

 - [Write() (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Write)

## 9. 実数の Write() における指数表現文字の大文字・小文字の別

Delphi での指数表現文字は**大文字の E** です。

## 10. 論理値の Write() における大文字・小文字の別

次のコードを実行すると、

```pascal
  Writeln(True);
  Writeln(False);
```

このように表示されます。

```
TRUE
FALSE
```

Delphi では**大文字**となります。


## 11. 手続き Page() の効果

Delphi では手続き Page() は実装されていません。ASCII コードで考えると、次のようなコードになるでしょうか。

```pascal
procedure Page();
begin
  write(^L); // FF (0x0C)
end;
```

## 12. プログラム引数 (ファイル型) の外部実体への結び付け方

関連付けには **AssignFile()** を使います。関連付けの解除は **CloseFile()** です。

|手続き|説明|
|:---|:---|
|[AssignFile()](http://docwiki.embarcadero.com/Libraries/Rio/ja/System.AssignFile)|外部ファイルの名前をファイル変数と関連付ける。<br>**Turbo Pascal** では Assign()。|
|[CloseFile()](http://docwiki.embarcadero.com/Libraries/Rio/ja/System.CloseFile)|ファイル変数と外部ファイル名の関連付けを終了する。<br>**Turbo Pascal** では Close()。|

**See also:**

 - [<9> ファイル型 (標準 Pascal 範囲内での Delphi 入門) (Qiita)](https://qiita.com/ht_deko/items/986fa01c9e6cfc3fd673)

## 13. Input, Output に Reset(), Rewrite() を適用したときの効果

**特に何も起こらない**ようです。

**See also:**

 - [Input (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Input)
 - [Output (DocWiki)](http://docwiki.embarcadero.com/Libraries/ja/System.Output)


# おわりに
なんとなくスッキリしましたね。

**See also:**

 - [標準 Pascal の規格票と解説書を読んでみる (Qiita)](https://qiita.com/ht_deko/items/091661d6fa3d72700a56)
 - [用語集 (標準 Pascal 範囲内での Delphi 入門) (Qiita)](https://qiita.com/ht_deko/items/56e4910d7e00d9bcc5b2)