トーフサロン

Common Lisp クックブックもぼちぼちやってます。

2010-02-27

[] Ada 基礎文法最速マスター

今まで文法を知ろうとさえ思ったことがなかったけど、調べてみると学んどくべき言語のような気がしてきた。始めたばかりでよく知らないため、間違いがあったら指摘して下さい。このページに少しずつ書いていきます。

Ada の日本語情報が少ないので、文法以前の基礎知識から書く。 Ada Programming - Wikibooks が詳しい。

パラダイム

  • 構造化
  • 命令型
  • オブジェクト指向

実行方式

ネイティブコードにコンパイル、または Java や .NET などの VM で動作。処理系による。

規格

ISO と ANSI で制定されている。これまでに何度か改訂され、制定された年度によって次のように呼び分けている。ちなみにオブジェクト指向言語としては世界で初めて標準規格化 (ISO, 1995 年) された言語

  • Ada 83 (1983 年 MIL 規格化、後に ISO/ANSI 標準化)
  • Ada 95 (1995 年 ISO/ANSI 標準化)
  • Ada 2005 (2005 年 ISO/ANSI 標準化)

この文法なんちゃらマスターでは Ada 2005 を対象とする。 Ada 2005 は Ada 05 と呼ばれることもある。

フリーの処理系

GNAT (GNU NYU Ada Translator) が最も有名。ただし歴史的な経緯でライセンスも機能も異なるバージョンがあってややこしい。これに開発サポートをつけて商用にした GNAT Pro があり、航空、軍事、宇宙に関わってる模様。空飛ぶ Ada 、潜航する Ada 。 GNAT は (C を通して) ネイティブコードにコンパイルするが、 GNAT Pro ではネイティブコードに加えて Java VM や .NET VM で動くコードを吐くこともできるらしい。

Mac の場合は MacPorts だとインストールできたりできなかったりするので、 Drew さんとこの公開ファイル からコンパイル済みバイナリをダウンロードするといい。 10. 6 であれば、 "Ada/i686/fsf-i686-ada-4.4-20091023-10.6-most-langs.tgz" をダウンロードし、展開したアーカイブを /usr/local/gnat に置くなどする。

% tar xzf fsf-i686-ada-4.4-20091023-10.6-most-langs.tgz
% sudo mv ada-4.4 /usr/local/gnat
# あとは /usr/local/gnat/bin をパスに追加する

詳しくは 指向性メモ::2008-12-08::Mac OS XにおけるAda開発環境の構築とAdaコンパイラの種類について を参照。

ソースコードのコンパイルと実行

GNAT では、プログラムを実行するにはソースコードをコンパイルする必要がある。コンパイルには gnatmake を使うか、 gcc と各 gnat のコマンドを組み合わせて行う。

gcc
% gcc -c hello.adb
% gnatbind hello
% gnatlink hello

以上で実行可能形式のファイル hello が生成される。

Mac の場合、 Developer Tools でインストールされる gcc は Ada に対応していないので注意。 MacPorts やその他で配布されているバイナリパッケージに、 Ada に対応した gcc が含まれている。

gnatmake

gnatmake を使うと、 gcc を使う場合のコマンドを一度で実行できる。

% gnatmake hello.adb
% gnatmake hello

ソースファイルの構造

ソースファイルの前半に使用するライブラリの宣言、後半に各種ロジック (サブプログラム、パッケージなど) の定義を記述する。

-- 使用するライブラリの宣言
with Ada.Text_IO;
use Ada.Text_IO;

-- 各種ロジック (サブプログラム、パッケージなど) の定義
procedure Hello is
begin
   Ada.Text_IO.Put_Line("Hello, world!");
end Hello;

メモリ管理

GC

Ada の仕様としては導入可能ではある ( GC を想定したプラグマがある) が、現在 GC に対応しているコンパイラは仮想マシンを前提としたものだけらしい。つまり、 Java VM や .NET VM 向けの中間コードを吐くコンパイラのみで、 VM の GC をそのまま利用するらしい。 GNAT には GC のコンパイルオプションがあるが、プログラム終了時にしか動かないそうな。まあ Ada のミッションクリティカルな用途を考えると、 GC は二の次三の次なんだろう。実装すれば使えるだけましか。

基本的な型

Boolean
論理値。 True または False
Character
文字。それぞれ 8 ビット、 16 ビット、 32 ビットの型がある。
String
文字列。 Character の配列。
Integer
整数。
Float
浮動小数点数。
Duration
期間を表す浮動小数点数。
System.Address
メモリアドレス。

print

Ada.Text_IO ライブラリに文字列出力関数がある。数値を出力するには Ada.Integer_IO, Ada.Float_IO などのライブラリがある。

Ada.Text_IO.Put_Line("Hello, world!");

コメント

-- 行末までコメント

変数宣言と代入

変数の代入は := を使う。

My_Name := "Ada";

変数を宣言できる箇所は宣言部 (procedure, function などの予約語から begin の間) のみ。 Ada は強い型付けを行う言語で、変数には型を指定しなければならない。

-- 変数名 : [access] 型 [:= 初期値]
My_Name : String;
My_Name : String := "Ada Lovelace";

型の前に access をつけると、その型への参照 (ポインタ) を表す。

My_Name : access String;

手続きや関数の引数に限り、 access に加えて次の修飾子を指定できる。

in
読み出しのみ行える。
in out
読み書きを行える。
out
読み書きのみ行える。 Ada 83 では書き込みのみだった。
procedure My_Proc (Arg : in String)
...
end My_Proc;

数値

リテラル
-- 整数
12
0
1E6
123_456

-- 整数 (進数表記)
-- 255
2#1111_1111#
16#FF#
016#0ff#

-- 224
16#E#E1 -- 二つ目の # 以降はべき指数
2#1110_0000#

-- 実数12.0
0.0
0.456
3.14159_26

-- 実数 (進数表記)
-- 4095.0
16#F.FF#E+2
2#1.1111_1111_1110#E11

演算
Value_1 + Value_2
Value_1 - Value_2
Value_1 * Value_2
Value_1 / Value_2
Value_1 mod Value_2 -- 商
Value_1 rem Value_2 -- 余り
Value_1 ** Value_2 -- 冪乗

文字列

文字列リテラル (固定長)

ダブルクォートで囲む。ダブルクォート自体を文字列に含ませるには、ダブルクォートを二つ重ねる。

""
"A"
""""
"Hello, world!"
文字列操作

Ada の文字列には、文字列長とバッファ長によって次の三種類がある。 C のように自分でバッファを管理してもいいし、ライブラリにバッファの伸長を任せてもいい。まあ、どのみちメモリ効率は自分でやれという言語なので GC つきの言語ほどお手軽ではなさそう。

固定長文字列 (Fixed-Length String)
長さが固定の文字列。
有限長文字列 (Bounded-Length String)
バッファ長は固定だが、その範囲で長さが可変の文字列。
無限長文字列 (Unbounded-Length String)
必要に応じてバッファを伸長してくれる文字列。
-- 結合
Ada.Strings.Bounded.Append(Left, Right);
Ada.Strings.Unbounded.Append(Left, Right);

-- 分割
-- 自分でバッファを用意してちまちま分割?

-- 長さを得る
Ada.Strings.Bounded.Length(Source);
Ada.Strings.Unbounded.Length(Source);

-- 一部を得る
Ada.Strings.Fixed.Move(Source, Target); -- 別のバッファにコピー
Ada.Strings.Bounded.Slice(Source, Low, High);
Ada.Strings.Unbounded.Slice(Source, Low, High);

-- 検索
-- Bounded, Unbounded にも同名の関数がある
Ada.Strings.Fixed.Index(Source, Pattern, From)
Ada.Strings.Fixed.Find_Token(Source, Set, Test, First, Last);

制御構造

if 文
if 条件式 then
   ...
elsif 条件式 then
   ...
end if;
case 文
caseis
   when=>
      ...
   when=>
      ...
   ...
end case;
for 文

範囲の始めから終わりまでを繰り返す。

for 変数 in 範囲 loop
   ...
end loop;

ブロックに名前をつけることもできる。ループからの脱出に使う。

名前:
    for 変数 in 範囲 loop
      ...
    end loop 名前;
while 文
while 条件式 loop
   ...
end loop;

for 文と同様に名前をつけることもできる。

名前:
    while 条件式 loop
       ...
    end loop 名前;
loop 文

無条件にループを繰り返す。

loop
   ...
end loop;

for, while 文と同様に名前をつけることもできる。

名前:
    loop
       ...
    end loop 名前;
exit 文

ループ文 (for, while) の中からループ外に脱出する。

exit [ループ名] [when 条件式];
goto 文とラベル
<<ラベル名>>
goto ラベル名;

例を次に示す。

<<Sort>>
for I in 1 .. N-1 loop
   if A(I) > A(I+1) then
      Exchange(A(I), A(I+1));
      goto Sort;
   end if;
end loop;

手続きと関数

戻り値のない関数を手続き (procedure) と呼ぶ。引数には in, in out, out, access の 4 つのモードを指定することができる。ローカル変数は begin の前で宣言する。

手続き定義
procedure A_Test (A, B: in Integer; C: out Integer) is
   D : Integer := 0;
begin
   C := A + B + D;
end A_Test;
関数定義
function Minimum (A, B : Integer) return Integer is
begin
   if A <= B then
      return A;
   else
      return B;
   end if;
end Minimum;

コーディングスタイル

インデント

3 が推奨されている。インデントは文法に影響しない。

サンプルプログラム

Hello, World (hello.adb)
with Ada.Text_IO;

procedure Hello is
begin
   Ada.Text_IO.Put_Line("Hello, world!");
end Hello;
FizzBuzz (fizz_buzz.adb)
with Ada.Text_IO;
with Ada.Integer_Text_IO;
use Ada.Text_IO;

procedure Fizz_Buzz is
begin
   for I in Integer range 1 .. 15 loop
      if I mod 3 = 0 and I mod 5 = 0 then
         Put_Line("FizzBuzz");
      elsif I mod 3 = 0 then
         Put_Line("Fizz");
      elsif I mod 5 = 0 then
         Put_Line("Buzz");
      else
         Ada.Integer_Text_IO.Put(I, 1);
         New_Line(1);
      end if;
   end loop;
end Fizz_Buzz;

参考書籍

Ada Essentials: Overview, Examples and Glossary (Learnada, Vol. 1)

Ada 95 が対象の入門書。 Kindle Store なら $9.99 で買えるが、順に文法と機能を説明するだけなのでチュートリアルとしては使いにくい。

Programming in Ada 2005 with CD (International Computer Science Series)

Ada 2005 の解説書。 2006 年にすぐ発売されてんだよこれ。注文したんで読んだら感想書く。

Concurrent and Real-Time Programming in Ada

Ada による並列&リアルタイムプログラミング。第 3 版なんだよこれ。 Amazon.com じゃ星 5 つの賞賛の嵐。これも注文したんで (ry

Real-Time Systems and Programming Languages: Ada, Real-Time Java and C/Real-Time POSIX (International Computer Science Series)

Java, Ada, C によるリアルタイムプログラミング。著者は二人とも上の本と同じ人なので、 Ada について深く知りたいか他の言語についても知りたいかで選べばいい…のかはわからない。

Ada 2005 Reference Manual. Language and Standard Libraries: International Standard ISO/IEC 8652/1995(E) with Technical Corrigendum 1 and Amendment 1 (Lecture Notes in Computer Science / Programming and Software Engineering)

Ada 2005 のリファレンスマニュアル + 標準ライブラリマニュアル。これだけで本が出るって。

Ada 2005 Rationale: The Language, The Standard Libraries (Lecture Notes in Computer Science / Programming and Software Engineering)

上の本から標準ライブラリの部分のみを抜き出したように見えるが、著者が Programming in Ada 2005 の人なので違うっぽい。これだけで本が (ry


続く。