Delphi
Pascal
10

割と簡単に ’標準 Pascal' を試してみたい

はじめに

Delphi を使っていて、何が 標準 Pascal (Standard Pascal) に準拠していて何が準拠していないのかふと知りたくなることがあります。ISO/IEC 7185 の仕様を読めばいいのですが、実際にコードを実行して試したい事がよくあります。

そんな時は ideone で GPC を使ったり、同じく FPC で {$mode ISO} 指令を付けてみたりするのですが、これらは純粋な標準 Pascal ではないので、場合によっては検証にならなかったりします。

純粋な '標準 Pascal' を求めて

Windows 環境で最も簡単に実行できる標準 Pascal は Scott A. Moore 氏が書いた (改修した) Pascal-P5 だと思われます。

Mac や Linux の場合には自前でソースコードをビルドする必要があります。

今回の話題からは外れますが X68000 (Human68K) だと Pure Pascal が標準 Pascal ですね。
image.png

環境設定

PASCAL-P5 のアーカイブを解凍したら、bin フォルダにある pcom.exe と pint.exe を適当な場所にコピーします。これが PASCAL-P5 の本体です。

PASCAL-P5 は P-CODE コンパイラです。簡単に言えば PCOM がソースコードを中間コード (P-CODE) 形式にコンパイルし、それを PINT が実行します。PCOM がコンパイラで PINT がインタプリタという訳です。なので、理屈的には PINT さえ移植できればどこでもプログラムを実行できます。

え? Java っぽい? え? .NET っぽい? え? VB っぽい?そうですか...

さて、PCOM は prd という名前のファイルをソースコードとみなし、コンパイルして prr という中間形式ファイルを出力します。そして PINT は prr という名前のファイルを中間形式ファイルとみなして実行します...名前決め打ちなんですよ、面倒ですね。

これを簡単にするバッチファイルもアーカイブの bin フォルダにあるのですが、何故かバッチファイルに cp や mv が使われていて Cygwin がないと動作しません。

バッチファイル

面倒なので Cygwin が不要なようにバッチファイルを書きました。以下の 4 つのファイルを pcom.exe / pint.exe と同じ場所に保存してください。

setpath.bat

カレントディレクトリを環境変数 PATH に設定するバッチファイルです。

setpath.bat
@echo off
cls
set PATH=%CD%;%PATH%
echo %PATH%

compile.bat

ソースファイルをコンパイルするバッチファイルです。

compile.bat
@echo off
cls

if not "%1"=="" goto paramok
echo *** Error: Missing parameter
goto exit

:paramok
if exist "%1.pas" goto fileexists
echo *** Error: Missing %1.pas file
goto exit

:fileexists
if "%2"=="" goto continue
if exist "%2" goto continue
echo *** Error: Missing %2 input file
goto stop

:continue
echo.
echo Compiling and running %1
echo.
copy %1.pas prd > nul
pcom
move prr %1.p5 > nul

:stop
del prd

:exit

run.bat

中間形式ファイルを実行するバッチファイルです。

run.bat
@echo off
cls

if not "%1"=="" goto paramok
echo *** Error: Missing parameter
goto exit

:paramok
if exist "%1.p5" goto fileexists
echo *** Error: Missing %1.p5 file
goto exit

:fileexists
if not "%2"=="" goto useinputfile
copy %1.p5 prd > nul
goto run

:useinputfile
rem The input file, if it exists, gets put on the end of the intermediate
type %1.p5 %2 > prd

:run
pint
if "%3"=="" goto stop
copy prr %3 > nul

:stop
del prd
del prr

p5.bat

ソースコードファイルをコンパイルして実行するバッチファイルです。

p5.bat
@echo off
cls

if not "%1"=="" goto paramok
echo *** Error: Missing parameter
goto stop

:paramok
if exist "%1.pas" goto fileexists
echo *** Error: Missing %1.pas file
goto stop

:fileexists
if "%2"=="" goto continue
if exist "%2" goto continue
echo *** Error: Missing %2 input file
goto stop

:continue
echo.
echo Compiling and running %1
echo.
copy %1.pas prd > nul
pcom
move prr %1.p5  > nul
if not "%2"=="" goto useinputfile
copy %1.p5 prd  > nul
goto run

:useinputfile
rem The input file, if it exists, gets put on the end of the intermediate
type %1.p5 %2 > prd

:run
pint
if "%3"=="" goto stop
copy prr %3 > nul

:stop
del prd
del prr

PASCAL-P5 の使い方

まず、サンプルプログラムを用意します。アーカイブの sample-programs フォルダにもサンプルがありますが、今回は FizzBuzz を用意してみました。

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.

まず、PASCAL-P5 (とバッチファイル) を格納したフォルダへ移動します。
image.png
アドレスバーに CMD と入力し〔Enter〕キーを押し、
image.png
カレントディレクトリでコマンドプロンプトを開きます。
image.png
先程の FizzBuzz.pas が違うフォルダにあるのであれば setpath を実行して PASCAL-P5 にパスを通しておきます。
image.png
compile fizzbuzz としてコンパイルします。ここでの拡張子の入力は不要ですが、ソースファイル名は *.pas である必要があります。
image.png
正しくコンパイルされると fizzbuzz.p5 ファイルが生成されます。これが中間形式ファイルです。
image.png
run fizzbuzz として実行します。拡張子は不要です。一旦中間形式ファイルができてしまえば、実行の都度コンパイルする必要はありません。
image.png
p5 fizzbuzz とすると、コンパイルと実行を連続して行います。
image.png

おわりに

目的は達成されました!めでたしめでたし...。

K&R の K の方へ

K&R の K の方「Why Pascal is Not My Favorite Programming Language (何故 Pascal はお気に入りのプログラミング言語ではないのか)」 なんてのを書いていましたが Turbo Pascal や Delphi...それ以前の Apple の Pascal ですらその問題の多くは解決しています (好みの問題は残りますが)。

先の論文が書かれたのは 1981 年ですが、

  • 1983: Pascal の最初の標準化 / Turbo Pascal 1.0
  • 1985: Apple による Object Pascal
  • 1990: Pascal 標準化改訂版 / Turbo Pascal 5.5 (Object Pascal)
  • 1995: Delphi 1.0

それ以降で (Object) Pascal が進化していないハズもなく。

例えば、論文に書かれていたループの問題についてですが、標準 Pascal だと

loop.pas
program loop(output);
begin
  while True do
    begin
      break;
    end;
end.

このような break を使ったループの脱出はできません。
image.png
Delphi とかだと普通にできます。
image.png

Linux の L の方へ

Linux の L の方の Pascal 嫌いという話についても古い Pascal に基づくものなので的外れな指摘もあるかと思います。

例えば

Of course, in stupid languages like Pascal,
where labels cannot be descriptive, goto's can be bad.

labeltest.pas
program labeltest(output);
label 
  jump;
begin
  goto jump;
  writeln('Hello');
jump:
  writeln('World');
end.

確かに標準 Pascal だとラベルに任意の名前を付ける事はできず、符号なしの 4 桁以下の整数を指定する必要がありますが、
image.png
Delphi ならラベルに識別子が使えます (符号なしの整数も使えます)。
image.png

古い Pascal しか知らないと「Pascal...面倒くさいよね!」という意見が出てしまうのもわからなくはないですが、Delphi 等のモダンな (Object) Pascal が面倒くさい訳ではありません。

そして最新版の Delphi

image.png

魔改造 Pascal である Delphi には無償版 (Community Edition) もあるので、K の方や L の方が言ってた事が今でも正しい指摘なのかどうかをぜひ試してみてください。

... Delphi 使いは逆に標準 Pascal を触ってみて Delphi の有難みを知ってください (w

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away