なんか急にPascalやりたくなった!

http://www.taoyue.com/tutorials/pascal/index.htmlをやることにする随時更新

こんにちは!

もうなにも憶えてなかったのでhelloworldから。

program Hello;
begin (* Main *)
  writeln ('Hello, world.');
end. (* Main *)

(* Main *)ってなんだよ! とおもったけどvimシンタックスハイライトのおかげでコメントだとわかった。

% gpc hello.pas
% ./a.out
Hello, world.

writelnがあればもちろんwriteあるよね。

program Hello;
begin (* Main *)
  write('Hello, world.');
end. (* Main *)
% gpc hello2.pas
% ./a.out
Hello, world.%

読み書き

writeあるならreadある。引数無しなら()省略できんのかね。

program ReadWrite;
begin
  writeln('hogehoge');
  readln
end.
% gpc readwrite.pas
% ./a.out
hogehoge
dsjafi

読んだ値は使えるんですか

program ReadWrite;
begin
  writeln(readln)
end.
% gpc readwrite2.pas
readwrite2.pas: In main program:
readwrite2.pas:3: error: syntax error before `readln'

なんかちがうらしい。どうやるんだ。

一旦おちついて言語構造など

PROGRAM ProgramName (FileList);

CONST
  (* Constant declarations *)

TYPE
  (* Type declarations *)

VAR
  (* Variable declarations *)

(* Subprogram definitions *)

BEGIN
  (* Executable statements *)
END. 

なるほど。FileListあたりがかなりわからんけど先行こう。ところで、予約語は大文字小文字区別なしってことかなたぶん。最小プログラムは

program DoNothing;
begin
end.

と。ところでProgramNameてなんの意味があるんだろうね。

const

こんな感じで定数を宣言できると。

program Constant;
const
  hoge = 'hoge';
  pi = 3.1415926535;
begin
  writeln(hoge);
  writeln(pi);
end.
% gpc const.pas
% ./a.out
hoge
 3.141592653500000e+00

writeさん意外と高機能ですね。アセンブリ出力見てみよう。

% gpc const.pas -S
% cat const.s
        .file   "const.pas"
        .section        .rodata
.LC0:
        .string "hoge\n"
...

ちゃんと"hoge"という文字列用意されてるなーと思ったら"hoge\n"だった。なんで! と思ってたらすげえ、writelnでしか使われんから"hoge\n"にしちゃってwriteしちゃってるみたい。

program Constant;
const
  hoge = 'hoge';
  pi = 3.1415926535;
begin
  write(hoge);
  writeln(pi);
end.
% gpc const2.pas -S
% cat const2.s
        .file   "const2.pas"
        .section        .rodata
.LC0:
        .string "hoge"
        .text
...

ちなみに型をちゃんと指定してやると、

program Constant;
const
  hoge : string[5] = 'hoge';
  pi : real = 3.1415926535;
begin
  writeln(hoge);
  writeln(pi);
end.

こんなんかね。stringの長さ指定はちょっとわからんな。たぶん、十分な長さとっておけばいいんだろうけど。自動で長さ読むとかできねえかな。

% gpc const3.pas
% ./a.out
hoge
 3.141592653500000e+00

Pascal型推論があったのですかすげええ!! 型推論っていうのかこれ。

var節

変数がねえとなんにもできないよね!(手続き脳の恐怖

program Variable;
var
  i, j : integer;
  pi : real;
  ch : char;
  success : boolean;
begin
  i := 3;
  j := 4;
  i := i + j;
  read(ch);
  write(ch);
  writeln(i);
end.

適当に、たぶんこんなだったかなというプログラム。基本的なデータ型はinteger, real, char, booleanだそうで。さっき書いたstringってなんだ。

% gpc var.pas
% ./a.out
hoge
h7

うごいた。

標準関数とか

文字と整数の変換とか

program StdFun;
var
  ch : char;
begin
  read(ch);
  writeln(chr(ord(ch)+2));
  writeln(succ(succ(ch)));
end.
% gpc stdfun.pas
% ./a.out
3
5
5

すこしはプログラムらしいプログラム

(* Author:    Tao Yue
   Date:      19 June 1997
   Description:
   Find the sum and average of five predefined numbers
   Version:
   1.0 - original version
*)

program SumAverage;

const
  NumberOfIntegers = 5;

var
  A, B, C, D, E : integer;
  Sum : integer;
  Average : real;

begin    (* Main *)
  A := 45;
  B := 7;
  C := 68;
  D := 2;
  E := 34;
  Sum := A + B + C + D + E;
  Average := Sum / NumberOfIntegers;
  writeln ('Number of integers = ', NumberOfIntegers);
  writeln ('Number1 = ', A);
  writeln ('Number2 = ', B);
  writeln ('Number3 = ', C);
  writeln ('Number4 = ', D);
  writeln ('Number5 = ', E);
  writeln ('Sum = ', Sum);
  writeln ('Average = ', Average)
end.     (* Main *)

うわーA..Eは配列にしてえなあ。

% gpc sumaverage.pas
% ./a.out
Number of integers = 5
Number1 = 45
Number2 = 7
Number3 = 68
Number4 = 2
Number5 = 34
Sum = 156
Average =  3.120000000000000e+01

いちおう入力ありのプログラム

program SumAverage;
const
  NumberOfIntegers = 5;
var
  A, B, C, D, E : integer;
  Sum : integer;
  Average : real;
begin
  read(A, B, C, D, E);
  Sum := A + B + C + D + E;
  Average := Sum / NumberOfIntegers;
  writeln ('Number of integers = ', NumberOfIntegers);
  writeln ('Number1 = ', A);
  writeln ('Number2 = ', B);
  writeln ('Number3 = ', C);
  writeln ('Number4 = ', D);
  writeln ('Number5 = ', E);
  writeln ('Sum = ', Sum);
  writeln ('Average = ', Average)
end.
% gpc sumaverage2.pas
% ./a.out
1 2 3 4 5
Number of integers = 5
Number1 = 1
Number2 = 2
Number3 = 3
Number4 = 4
Number5 = 5
Sum = 15
Average =  3.000000000000000e+00

わー合計と平均値がだせたー、と。

Formatting Output

どうもwriteとかもっと高機能だったらしい。まじでか。

program Format;
begin
  writeln(1:10, 'i''m hungry':20);
  writeln(123:10, 'plz':20);
  writeln(3.1415926535:10:3, 'hoge':20);
end.
% gpc format.pas
% ./a.out
         1          i'm hungry
       123                 plz
     3.142                hoge

おー。普通に便利だな。

ファイルの読み書きとか

program FileIO;
var
  buf : string[100];
  filein, fileout : text;
begin
  reset(filein, 'file.pas');
  rewrite(fileout, 'hoge');
  read(filein, buf);
  writeln(fileout, buf);
  close(filein);
  close(fileout);
end.
% gpc file.pas
% ./a.out
% cat hoge
program FileIO;

まあなんか一行読めてる。resetとかrewriteとかなんだ。

EndOfFileのチェック

cだとまあ大抵返り値がEOFだったりNULLだったりとかを読んだりするかもしれんけど、Pascalだとeofで見るしか無いのかな?

program EOFcheck;
var
  filein : text;
begin
  reset(filein, 'hoge');
  writeln(eof(filein));
end.
% gpc eof.pas
% cat >hoge
% ./a.out
True

真偽値

not, and, or, xorなどあり。あとC系などとは違ってnot equalは!=じゃなくて<>

program BoolExp;
begin
  writeln('3=8':20, ' = ', 3=8);
  writeln('3<>2':20, ' = ', 3<>2);
  writeln('3<2.3':20, ' = ', 3<2.3);
  writeln('(3>8) or (10>2)':20, ' = ', (3>8) or (10>2));
end.
% gpc boolexp.pas
% ./a.out
                 3=8 = False
                3<>2 = True
               3<2.3 = False
     (3>8) or (10>2) = True

左寄せでformattingとかできねえかな。


はらへったからとりあえずここまで。

test