Delphi で Pascal-S をコンパイルする (16bit 版 Delphi)

# はじめに

Pascal-S という Pascal インタプリタを最新の Delphi / ANSI 版 Delphi でコンパイルできるように改変する記事を書きました。

 - [Delphi で Pascal-S をコンパイルする (Qiita)](https://qiita.com/ht_deko/items/77052d1f3c3c1a927034)
 - [Delphi で Pascal-S をコンパイルする (ANSI 版 Delphi) (Qiita)](https://qiita.com/ht_deko/items/f4391f6f8b4b87a1fcf0)

本記事はその Pascal-S を 16bit 版 Delphi でコンパイルしてみようという趣旨です。Delphi の 16bit 版というのは一つしかありません。**初代 Delphi** の事です。

16bit 版 Delphi を動かす環境は 16bit Windows である **Windows 3.1** です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/5c8f1580-4b0e-40d8-3ad5-f1bd28cc8782.png)
この Windows 3.1 は Windows 7 の VirtualPC の上で動作させています。

Delphi 1 は XP (32bit) 等にもインストール可能です。XP なら Windows 10 以降の Hyper-V で動作させる事もできますし、Windows 7 の XP Mode も使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/5896379b-0535-bf8b-65ed-094e94d6927f.png)
動作確認するだけでしたら Windows 3.1 環境を用意する必要はありません。今回は 25 年前の環境を再現すべく、Windows 3.1 を使っています。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/3389e51d-76d3-df45-78e2-d48f13f741bd.png)](https://www.embarcadero.com/jp/delphi-stories/)

# 修正

以降で修正を行います。ベースとするのは ANSI 版 Delphi 用のコードです。大文字/小文字を区別しない Pascal-S を以前作りましたので、それを流用します。

 - [https://ht-deko.com/delphiforum/?vasthtmlaction=viewtopic&t=2191.0#postid-3871](https://ht-deko.com/delphiforum/?vasthtmlaction=viewtopic&t=2191.0#postid-3871)

アーカイブ \([PASCAL-S_20190826.zip](https://ht-deko.com/software/PASCAL-S_20190826.zip)\) は適当な場所に解凍し、VM の Windows 3.1 へ転送しておきます。

## コードの修正 (コンパイルエラーの除去)

Delphi で ANSI 版の方の `PASCALS.DPR` を開きます。まずはコンパイルエラーになる箇所をすべて潰します。

### 疑似コンソールアプリケーションの指定

Windows 3.1 には Win32 コンソールなんてものはありませんし、Delphi 1 では MS-DOS アプリケーションは作れません。当然、コンソールアプリケーションなんていうものは作れないため、`{$APPTYPE CONSOLE}` の記述を削除します。

コンソールアプリケーションは作れませんが、古い MacOS にあった SIOW アプリケーションのような**疑似コンソールアプリケーション**を作ることはできます。疑似コンソールアプリケーションを作るには `WinCRT` を **uses** に加えます。

```pascal
...

program Pascals(input { + [sam] } , output, srcfil { [sam] } ); (* 1.6.75 *)
(* N. Wirth, E.T.H CH-8092 Zurich *)

uses
  SysUtils, WinCRT;
...
```

**See also:**

 - [Delphi のコンソールアプリケーションで文字色変更と座標指定をしたい！ (Qiita)](https://qiita.com/ht_deko/items/e0a12036de0596c9cbae)
 - [<3> Macintosh 用 Pascal のオブジェクト指向拡張 (Pascal へのオブジェクト指向拡張の歴史と Delphi) (Qiita)](https://qiita.com/ht_deko/items/cd245180363e1911afa7)

### 行コメント
`// Loop1` や `// Loop2` のように行コメントを使っている所がありますので、これをブロックコメント (`{ }` または `(* *)`) で置き換えるかコメントを消します。**Delphi 1 では行コメントが使えません。**

### パラメータの変更
パラメータをオリジナルの PASCAL-P4 に近づけます。16bit アプリなので、そんなに多くのメモリは使えないからです。

```pascal
const
  nkw   =     27;                 (* no. of key words *)
  alng  =     10;                 (* no. of significant chars in identifiers *)
  llng  =    250 {120 [sam]};             (* input line length *)
  emax  =    308 {322 [sam]};             (* max exponent of real numbers *)
  emin  =   -308 {-292 [sam]};            (* min exponent *)
  kmax  =     15;                         (* max no. of significant digits *)
  tmax  =    200 {100 [sam]};             (* size of table *)
  bmax  =     40 {20 [sam]};              (* size of block-table *)
  amax  =     60 {30 [sam]};              (* size of array-table *)
  c2max =     40 {20 [sam]};              (* size of real constant table *)
  csmax =     60 {30 [sam]};              (* max no. of cases *)
  cmax  =   1700 {850 [sam]};             (* size of code *)
  lmax  =     14 {7 [sam]};               (* maximum level *)
  smax  =   1200 {600 [sam]};             (* size of string table *)
  ermax =     58;                         (* max error no. *)
  omax  =     63;                         (* highest order code *)
  xmax  = 131071;                         (* 2**17 - 1 *)
  nmax  = maxint {281474976710655 [sam]}; (* 2**48 - 1 *)
  lineleng =   250 {136 [sam] };            (* output line length *)
  linelimit =  400 {200 [sam]};
  stacksize = 1500 {1500 [sam]};
```

## モジュールヘッダのエラー
IDE を閉じてまたプロジェクトを開こうとしたり、プロジェクトに名前をつけて保存しようとすると `モジュールヘッダーが無いか間違っています。` と怒られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/3083bfa7-b9cf-6a35-ff15-bc779d19b069.png)
実害はないのですが、これを回避するにはプログラムヘッダーをシンプルになるよう書き換えます。

```pascal
program Pascals; (* 1.6.75 *)
```

## 実行

修正が終わったら、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/99546bca-f9b5-f1a5-7353-223663ed7d5f.png)
〔Ctrl〕+〔F9〕または [コンパイル | コンパイル] で一旦コンパイルします。コンパイルエラーが出るようなら修正が不完全です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/6a69fa5b-cf8f-2a17-0f6a-a63edc8c0674.png)
無事 PASCA-S がコンパイルできたら、`PASCALS.EXE` と同じ場所に `FIZZBUZZ.PAS` を用意します。

```pascal:FIZZBUZZ.PAS
program FizzBuzz(output);
var
  i: integer;
begin
  for i:=1 to 100 do
  begin
    if ((i mod 3) +  (i mod 5)) = 0 then
      writeln('Fizz Buzz')
    else if (i mod 3) = 0 then
      writeln('Fizz')
    else if (i mod 5) = 0 then
      writeln('Buzz')
    else
      writeln(i);
 end;     
end.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c02cf8ac-470e-4d31-b1f4-526c690c4ffa.png)
[実行 | 引数] で `FIZZBUZZ.PAS` を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/67c7084b-e07f-91e2-6066-7c7eb5584fe8.png)
〔F9〕または [実行 | 実行] すると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/a05c802a-7667-1c8b-6a5f-c62f531f2e9b.png)
FizzBuzz が疑似コンソールで実行されます。わかりにくいかもしれませんが、次のような処理を行っています。

 1. Delphi で PASCAL-S という Pascal インタプリタをコンパイルして実行ファイル PASCALS.EXE を生成
 2. PASCALS.EXE (Pascal インタプリタ) に FIZZBUZZ.PAS を読み込ませて実行

FIZZBUZZ.PAS を Delphi 1 でコンパイルして FIZZBUZZ.EXE を作り、それを実行している訳ではありません。Delphi 1 で直接 FizzBuzz を実行 (ファイルに) するには次のような 'FIZZBUZZ.DPR' をコンパイルします。

```pascal:FIZZBUZZ.DPR
program FizzBuzz;

uses
  WinCRT;

var
  i: integer;
begin
  for i:=1 to 100 do
  begin
    if ((i mod 3) +  (i mod 5)) = 0 then
      writeln('Fizz Buzz')
    else if (i mod 3) = 0 then
      writeln('Fizz')
    else if (i mod 5) = 0 then
      writeln('Buzz')
    else
      writeln(i);
 end;     
end.
```


# おわりに

生成されたバイナリ単体で動作させるには**ファイルマネージャ** (WINFILE.EXE) の [ファイル | 名前を指定して実行] から実行するのが簡単だと思います。疑似コンソールアプリケーションは MS-DOS プロンプトから実行する事はできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/55a4e7dd-fd81-2612-b711-68ca9217f8fd.png)
2020/02/14 で Delphi は 25 周年となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c7128ca2-7cbc-a7a9-7146-5a5cead1613f.png)

**追記: 2020/02/15**
Delphi 1.0 Client/Server (英語版) がアンティークソフトウェアとして無償公開されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/fa0b5cff-7f35-13a9-ca33-2bb6dd1f5086.png)

 - [Historic Delphi 1 Client/Server Install ISO (Embarcadero)](https://cc.embarcadero.com/item/30911)
 - [Delphi 1.0 Client/Server が無償公開されたので Windows 7 の XP Mode にインストールしてみる (Qiita)](https://qiita.com/ht_deko/items/e02a7b42ef65baa5d175)
 - [Delphi 1.0 Client/Server が無償公開されたので Windows 10 (64bit) / 11 にインストールしてみる (Qiita)](https://qiita.com/ht_deko/items/a65e0950b906d28ccb5f)