Oberon-2

Oberon-2 とは、プログラミング言語 Oberon を拡張し、オブジェクト指向的なコンセプトを取り入れた言語である。

1991年、チューリッヒ工科大学のニクラウス・ヴィルトと Hanspeter Mössenböckが開発した。Oberon-2 は Oberon の上位互換である。Oberon-2 は Object Oberonの再設計でもあった。

Oberon-2 は Oberon から限定されたリフレクションとインタフェースなどを持たない単一継承を受け継いでいるが、効果的な仮想メソッドを追加している。メソッド呼び出しは、C++のような仮想メソッドテーブルを使って実行時に確定する。

Smalltalk などの完全なオブジェクト指向言語に比べると、Oberon-2 の基本データ型はオブジェクトになっておらず、クラスもオブジェクトではなく、多くの操作がメソッドではないし、メッセージパッシングの概念もなく、ポリモーフィズムも限定的である。オブジェクト/クラスレベルでのカプセル化もサポートしていないが、モジュールをその目的で使用することができる。

Oberon-2 のリフレクションはメタオブジェクトを使わず、実行ファイル内に含まれる型記述子を単に読み、それが型やプロシージャを定義しているモジュールに渡される。その構造体の形式が言語レベルで渡されるなら、ライブラリレベルでのリフレクションの実装が可能である。従って、言語コードを全く変えずにライブラリレベルでほとんど全てを実行することも可能である。実際、Oberon System 3 は言語レベルとライブラリレベルのリフレクションを多用している。

1. コード例
-------

以下の Oberon-2 のコードは、単純なリストクラスを実装したものである。

MODULE ListClass;

TYPE List* = POINTER TO ListNode; ListNode = RECORD value : INTEGER; next : List; END;

PROCEDURE  Add* ; BEGIN  END Add; PROCEDURE  AddLast*; BEGIN  END AddLast; PROCEDURE  AddAt* ; BEGIN  END AddAt;

PROCEDURE  Remove*; BEGIN  END Remove; PROCEDURE  RemoveLast*; BEGIN  END RemoveLast; PROCEDURE  RemoveAt* ; BEGIN  END RemoveAt;

END ListClass.<WtXmlEndTag />

2. Oberon からの拡張
---------------

型束縛プロシージャ プロシージャは、レコード型に束縛することができる。オブジェクト指向的用語で言えば、インスタンスメソッドと等価である。 リードオンリーのエクスポート エクスポートされた変数やレコードのフィールドについて、参照だけにアクセスを制限することもできる。これは、visibility flag に "-" を付与することで示される。 Open arrays Oberon では正式なパラメータ型としてのみ宣言可能だったが、Oberon-2 ではポインタベースの型として宣言できる。 FOR 文 Pascal や Modula-2 にあった FOR 文は、Oberon では実装されなかった。それが、Oberon-2 で復活している。

2.1. 実行時型チェック
-------------

Oberon-2 はオブジェクトの型について、動的なチェックを行う機構がいくつか用意されている。例えば、Bird オブジェクトのインスタンスとして Duck や Cuckoo があったとき、Oberon-2 では実行時にオブジェクトの実際の型に応じた処理が可能である。

従来的な方法としては、「型束縛システム」を使った方法がある。第二の方法として、WITH 文を使った方法がある。これは、変数の動的な派生型を直接チェックするものである。どちらの場合も、派生型を特定したら、プログラマはその派生型に適切な型束縛プロシージャや型束縛変数を使うことができる。以下に具体例を示す。

なお、Oberon-2 の WITH 文と Pascal や Modula-2 の WITH 文は無関係である。以下のメソッドではレコードのフィールドへのアクセスを略記しているが、Oberon や Oberon-2 では実際にはこのような記法は使わない。

型束縛 MODULE Birds;

TYPE Bird* = RECORD sound* : ARRAY 10 OF CHAR; END; END Birds.  MODULE Ducks; IMPORT Birds;

TYPE Duck* = RECORD END;

PROCEDURE makeSound*; BEGIN COPY; END makeSound;

END Ducks.  MODULE Cuckoos; IMPORT Birds;

TYPE Cuckoo* = RECORD END;

PROCEDURE makeSound*; BEGIN COPY; END makeSound;

END Cuckoos.<WtXmlEndTag />WITH 文 MODULE Test; IMPORT Out, Birds, Cuckooo, Ducks;

TYPE SomeBird* = RECORD  END;

VAR sb : SomeBird; VAR c : Cuckoos.Cuckoo; VAR d : Ducks.Duck;

PROCEDURE setSound*; BEGIN WITH bird : Cuckoos.Cuckoo DO bird.sound := "Cuckoo!"; | bird : Ducks.Duck DO bird.sound := "Quack!"; ELSE bird.sound := "Tweet!"; END; END setSound;

PROCEDURE MakeSound* ; BEGIN Out.Ln; Out.String; Out.Ln; END MakeSound;

BEGIN

setSound; setSound; setSound;

MakeSound; MakeSound; MakeSound;

END Test.<WtXmlEndTag />POINTER MODULE PointerBirds; IMPORT Out;

TYPE BirdRec* = RECORD sound* : ARRAY 10 OF CHAR; END; DuckRec* = RECORD END; CuckooRec* = RECORD END;

TYPE Bird = POINTER TO BirdRec; Cuckoo = POINTER TO CuckooRec; Duck = POINTER TO DuckRec;

VAR pb : Bird; pc : Cuckoo; pd : Duck;

PROCEDURE makeDuckSound*; BEGIN COPY END makeDuckSound;

PROCEDURE makeCuckooSound*; BEGIN COPY END makeCuckooSound;

PROCEDURE makeSound*; BEGIN WITH bird : Cuckoo DO makeCuckooSound; | bird : Duck DO makeDuckSound ELSE COPY; END; END makeSound;

BEGIN NEW; NEW;

makeCuckooSound; makeDuckSound;

Out.Ln;Out.String;Out.Ln; Out.Ln;Out.String;Out.Ln;

makeSound; makeSound;

Out.Ln;Out.String;Out.Ln; Out.Ln;Out.String;Out.Ln;  

pb := pd;

makeDuckSound ); Out.Ln;Out.String;Out.Ln;

pb := pc;

makeCuckooSound ); Out.Ln;Out.String;Out.Ln; 

makeSound; Out.Ln;Out.String;Out.Ln;

pb := pd;

makeSound; Out.Ln;Out.String;Out.Ln;  NEW;

makeSound; Out.Ln;Out.String;Out.Ln;

END PointerBirds.

<WtXmlEndTag /> 第三の方法として、IS 演算子を使った方法もある。これは、等号や不等号などと同じ優先順位の関係演算子であるが、動的な型の検査を行う。しかし、上述の2つの方法とは異なり、検出した派生型によって処理を振り分けることはできない。

3. 文法
-----

ALGOL - Pascal - Modula-2 - Oberon - Component Pascal の系列の言語は文法を単純化させてきたと言える。Oberon-2 はEBNFを使って下記のように33の構文生成規則で表せる。

Module = MODULE ident ";" [ImportList] DeclSeq [BEGIN StatementSeq] END ident ".". ImportList = IMPORT [ident ":="] ident {"," [ident ":="] ident} ";". DeclSeq = TYPE TypeDecl ";"} ForwardDecl ";"}. ConstDecl = IdentDef "=" ConstExpr. TypeDecl = IdentDef "=" Type. VarDecl = IdentList ":" Type. ProcDecl = PROCEDURE [Receiver] IdentDef [FormalPars] ";" DeclSeq [BEGIN StatementSeq] END ident. ForwardDecl = PROCEDURE "^" [Receiver] IdentDef [FormalPars]. FormalPars = "" [":" Qualident]. FPSection = [VAR] ident {"," ident} ":" Type. Receiver = "". Type = Qualident | ARRAY [ConstExpr {"," ConstExpr}] OF Type | RECORD [""] FieldList {";" FieldList} END | POINTER TO Type | PROCEDURE [FormalPars]. FieldList = [IdentList ":" Type]. StatementSeq = Statement {";" Statement}. Statement = [ Designator ":=" Expr | Designator [""] | IF Expr THEN StatementSeq {ELSIF Expr THEN StatementSeq} [ELSE StatementSeq] END
| CASE Expr OF Case " Case} [ELSE StatementSeq] END | WHILE Expr DO StatementSeq END | REPEAT StatementSeq UNTIL Expr | FOR ident ":=" Expr TO Expr [BY ConstExpr] DO StatementSeq END | LOOP StatementSeq END | WITH Guard DO StatementSeq " Guard DO StatementSeq} [ELSE StatementSeq] END | EXIT | RETURN [Expr] ]. Case = [CaseLabels {"," CaseLabels} ":" StatementSeq]. CaseLabels = ConstExpr [".." ConstExpr]. Guard = Qualident ":" Qualident. ConstExpr = Expr. Expr = SimpleExpr [Relation SimpleExpr]. SimpleExpr = ["+" | "-"] Term {AddOp Term}. Term = Factor {MulOp Factor}. Factor = Designator [""] | number | character | string | NIL | Set | "" | " ~ " Factor. Set = "{" [Element {"," Element}] "}". Element = Expr [".." Expr]. Relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS. AddOp = "+" | "-" | OR. MulOp = " * " | "/" | DIV | MOD | "&". Designator = Qualident "[" ExprList "]" . ExprList = Expr {"," Expr}. IdentList = IdentDef {"," IdentDef}. Qualident =
[ident "."] ident. IdentDef = ident [" * " | "-"].

4. 実装
-----

チューリッヒ工科大学では、Windows、Linux、Solaris、Mac OS X向けのOberon-2コンパイラを実装・保守している。
マンチェスター大学のStephen J. BevanによるOberon-2対応のLex字句解析器とYacc構文解析器がある。現在のバージョンは1.4である。
[1]  は、エディタ、リンカ、Oneron-2コンパイラを備えた単純な統合開発環境である。Windows上の実行ファイルを生成する。全ソースコードも提供されており、コンパイラ自体が Oberon-2 で書かれている。
[2]  は、ロシアの University of Vologda で書かれた Oberon-2 コンパイラである。生成するコードはJavaクラスファイルである。Java互換の専用クラスが提供されているが、全体としての階層構造はOberonのものである。
[3]は、一旦Cに変換し、gccを使ってオブジェクトを生成する。

5. 参考文献
-------

"Second International Modula-2 Conference", 1991年9月

6. Oberon と Oberon-2 の変遷
------------------------

"//[ftp://ftp.inf.ethz.ch/pub/software/Oberon/OberonV4/Docu/ModToOberon.ps.gz From Modula-2 to Oberon]"// Wirth 
"//[ftp://ftp.inf.ethz.ch/pub/software/Oberon/OberonV4/Docu/OberonReport.ps.gz The Programming Language Oberon]"// Wirth 
"//[ftp://ftp.inf.ethz.ch/pub/software/Oberon/OberonV4/Docu/Oberon2.Differences.ps.gz Differences between Oberon and Oberon-2]"// Mössenböck and Wirth 
"//[4]//" H. Mössenböck, N. Wirth, Institut für Computersysteme, ETH Zürich , January 1992
"//[5]//" maintained at ETHZ
"//[6]//" , Pfister 

7. 外部リンク
--------

[7]
[8]
[9]

en:Oberon-2