4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Hello World あたたたた 標準 Pascal 編

Last updated at Posted at 2025-12-24

はじめに

この記事は Hello World あたたたた Advent Calendar 2025 の記事です。

この記事では標準 Pascal でHellow World あたたたた を実装します。標準 Pascal の実行環境として 『Pascal-P5』を利用しています。

そもそも「Hello World あたたたた」が何かは 1日目の記事 をご覧ください。

実装例

2/3 くらいが乱数絡みのコードです (^^;A

Atatata.pas
program Atatata(Output);

var
  hako: packed array [1..5] of Char;
  running: Boolean;
  Ch: Char;
  i, RandomIndex: Integer;
  RandomTable: array [1..55] of Real;
  
  function MachineEpsilon: Real;
  var 
    E, LastE: Real;
  begin
    E := 1;
    repeat
      LastE := E;  
      E := E / 2;
    until 1 + E = 1;
    E := 1 + LastE;  
    MachineEpsilon := E - 1;
  end; { MachineEpsilon() }

  procedure Randomize;
  var 
    I: Integer;
    R: Real;
  begin
    for I := 1 to 24 do 
    begin
      R := RandomTable[I] - RandomTable[I + 31];
      if R >= 0 then 
        RandomTable[I] := R
      else
        RandomTable[I] := R + 1.0;
    end;
    for I := 25 to 55 do 
    begin
      R := RandomTable[I] - RandomTable[I - 24];
      if R >= 0 then 
        RandomTable[I] := R
      else
        RandomTable[I] := R + 1.0;
    end;
  end; { Randomize() }

  procedure InitRandom(Seed: Real); (* 0 <= Seed < 1 *)
  var 
    I, J: Integer;
    R: Real;
  begin
    RandomTable[55] := Seed;
    R := MachineEpsilon;
    for I := 1 to 54 do 
    begin
      J := 21 * I mod 55;
      RandomTable[J] := R;
      R := Seed - R;
      if R < 0 then 
        R := R + 1.0;
      Seed := RandomTable[J];
    end;
    for I:=1 to 3 do
      Randomize; (* Warm up *)
    RandomIndex := 55;
  end; { InitRandom() }

  function Random: Real;
  begin
    RandomIndex := RandomIndex + 1;
    if RandomIndex > 55 then 
    begin
      Randomize;  
      RandomIndex := 1;
    end;
    Random := RandomTable[RandomIndex];
  end; { Random() }

  function IRandom(M: Integer): Integer;
  begin
    IRandom := Trunc(M * Random);
  end; { IRandom() }
  
begin
  InitRandom(0.123);
  hako := '     ';
  running := True;
  while running do 
  begin
    for i:=1 to 4 do
      hako[i] := hako[i+1];
    if IRandom(2) = 0 then 
      ch := 'ア'
    else  
      ch := 'タ';
    Write(ch);  
    hako[5] := ch;  
    if hako = 'アタタタタ' then 
    begin
      Writeln;
      Writeln('オマエハモウシンデイル');
      running := False;
    end;
  end;
end.

実行結果

image.png

コードと文法の解説

コードと文法の解説です。

  • 大文字小文字を区別しない
  • 代入は :=、等価の比較演算子は =
  • ブロック (複合文) は begin~end
  • 繰り返し文には for, repeat, while がある
  • 条件式には if, case がある
  • 演算順位を変更する必要がないのなら条件式に () は不要
  • 文の終わりではなく文の区切りに ; が使われる
  • プログラムの終わりは . で、これ以降の記述は無視される (エラーにならない) 処理系が多い
  • 変数の代入互換性は名前等価

欧文では「カンマ (,) < セミコロン (;) < ピリオド (.)」なので、理屈は通っています。

私が書く Qiita の記事が はじめに で始まって おわりに で終わるのは Pascal 由来です。

文字

標準 Pascal では文字を Char 型の変数に格納できます。

レギュレーションは次の通りなのですが...

変数 hako に空文字をセット
変数 running に true をセット
running が true なら繰り返す
    0か1をランダムに決める
    もし0なら
        変数 char に「あ」をセット
    その他なら
        変数 char に「た」をセット
    画面に char を出力
    char を hako に追加
    もし 最後の 5 文字が「あたたたた」なら
        "お前はもう死んでいる" を出力
        running に false をセット  

標準 Pascal では日本語 (いわゆるマルチバイト文字) を 1 文字として扱えません。こればかりは仕方がないですね。

幸い Pascal-P5 は 8bit 文字が通るので、半角カナで表示するようにしました。

program ヘッダ

標準 Pascal にはプログラムヘッダと、標準テキストファイル変数 Output を使うためのパラメータ指定があります。

program Atatata(Output);

標準 Pascal で標準出力するには、プログラムヘッダのパラメータに標準テキストファイル変数 Output を指定する必要があります。

See also:

変数名 char

レギュレーションに

変数 char に...

とありましたが、標準 Pascal では Char は型名 (定義済みの型識別子) なので、これを使う事はできません。

Char は予約語ではないので再定義も可能なのですが、再帰的な型定義は許されていないのでエラーになります。Pascal は予約語や識別子の大文字/小文字を区別しません。

再帰的な型定義
var
  ...
  char: Char;

できたとしても、後述の文字列型の変数宣言で引っ掛かってしまいます。

このため、変数名を ch としています。

var
  ...
  Ch: Char;

乱数生成

標準 Pascal の標準手続き/関数に乱数ジェネレータは存在しないので、『コンピュータアルゴリズム辞典』掲載のアルゴリズムを使っています。

image.png

それでも、ランダムシードに適当な値をセットできないので、シード値を変更しない限り、何度実行しても同じ答えが返ってきます。

標準 Pascal ではローカル変数の値は不定なので、次のような関数を使えばよさそうに思えますが、

function GetSeed: Integer;
var
  Seed: Integer;
begin
  GetSeed := Seed;
end;

Pascal-P5 ではエラーになります。

Undefined location access

文字列

標準 Pascal の文字列型は特殊なルールの文字配列です。

var
  str12: packed array [1..12] of Char;
  • 配列はパック (packed) されていなければならない
  • 配列の添字型は 1..N の部分範囲型でなくてはならない (N ≧ 2)
  • 文字列型は比較に関係演算子が使える
  • 長さが同じ文字列型 (および文字列リテラル) を代入可能 (ここだけ構造等価)

いわゆる Pascal 文字列は標準 Pascal に存在せず、もちろん動的配列なんてものも存在しないため、文字列の末尾 5 文字だけを保持して、それが アタタタタ と一致するかを調べるようにしています。

    for i:=1 to 4 do
      hako[i] := hako[i+1];
    if IRandom(2) = 0 then 
      ch := 'ア'
    else  
      ch := 'タ';
    Write(ch);  
    hako[5] := ch;  
    if hako = 'アタタタタ' then 
    ...

レギュレーションには、

変数 hako に空文字をセット

とありますが、標準 Pascal では長さが一致していないとリテラル文字列も代入できません。つまり空文字はセットできません。よって、長さ 5 の空白を代入しています。

空白の代わりに 0x00 で埋める事は可能ですが、Pascal においてはそれを空文字とみなしません。Pascal の文字列はヌル終端文字列ではないからです。

See also:

標準 Pascal の概要と歴史

標準 Pascal は強い型付け・構造化・教育重視のために設計された、最小限で明確な手続き型言語です。規格書は表紙等を含めてもたったの 80 ページしかありません。

一方、拡張を行わない純粋な Pascal は足りないものが多く、融通の利かない事が一部批判の対象となっています。

標準 Pascal の特徴

  • 強い型付け
  • 構造化プログラミング
  • 豊富なデータ構造やファイル型
  • 式と演算の厳密な定義 (処理系に依存しない)
  • 手続き・関数はネストや再帰が可能

標準 Pascal の歴史

ざっくりと。

規格 備考
1970 The programming language Pascal 最初期の Pascal のドキュメント
1973 The programming language Pascal
(Revised Report)
The programming language Pascal の改訂版
1983 ISO 7185:1983 規格化された最初の標準 Pascal
1983 ANSI/IEEE 770X3.97-1983 ISO 7185:1983 の 水準 0 とほぼ同じ
1990 ISO/IEC 7185:1990 ISO/IEC 7185 改訂版
1990 JIS X 3008:1990 ISO 7185:1983 準拠
1994 JIS X 3008:1994 ISO/IEC 7185:1990 準拠

See also:

おわりに

Pascal / Delphi 実装の記事は既に他の方も投稿されているので、比較してみると更に興味深いかと思います。

See also:

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?