Oberon-2

コード例

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

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

  PROCEDURE ( l : List ) Add*    ( v : INTEGER );
  BEGIN
       (* ... *)
  END Add;
  PROCEDURE ( l : List ) AddLast*( v : INTEGER );
  BEGIN
       (* ... *)
  END AddLast;
  PROCEDURE ( l : List ) AddAt*  ( i : INTEGER; v : INTEGER );
  BEGIN
       (* ... *)
  END AddAt;
  
  PROCEDURE ( l : List ) Remove*;
  BEGIN
       (* ... *)
  END Remove;
  PROCEDURE ( l : List ) RemoveLast*;
  BEGIN
       (* ... *)
  END RemoveLast;
  PROCEDURE ( l : List ) RemoveAt* ( i : INTEGER );
  BEGIN
       (* ... *)
  END RemoveAt;END ListClass.

実行時型チェック

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(Birds.Bird) END;
            
    PROCEDURE makeSound*( VAR bird: Duck );
    BEGIN COPY("Quack!", bird.sound); END makeSound;END Ducks.(*-------------------------------------*)MODULE Cuckoos;
    IMPORT Birds;

    TYPE Cuckoo* = RECORD(Birds.Bird) END;
            
    PROCEDURE makeSound*( VAR bird: Cuckoo );
    BEGIN COPY("Cuckoo!", bird.sound); END makeSound;END Cuckoos.
WITH 文
MODULE Test;
  IMPORT Out, Birds, Cuckooo, Ducks;

    TYPE SomeBird* = RECORD ( Birds.Bird ) END;

    VAR sb : SomeBird;
    VAR c  : Cuckoos.Cuckoo;
    VAR d  : Ducks.Duck;
    
    PROCEDURE setSound*( VAR bird : Birds.Bird );
    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* ( VAR b : Birds.Bird );
    BEGIN
    Out.Ln;
    Out.String( b.sound );
    Out.Ln;
    END MakeSound;BEGIN

    setSound(c);
    setSound(d);
    setSound(sb);
    
    MakeSound(c);
    MakeSound(d);
    MakeSound(sb);END Test.
POINTER
MODULE PointerBirds;
   IMPORT Out;

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

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

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

    PROCEDURE makeDuckSound*( bird : Duck );
    BEGIN COPY("Quack!", bird.sound) END makeDuckSound;
    
    PROCEDURE makeCuckooSound*( bird : Cuckoo );
    BEGIN COPY("Cuckoo!", bird.sound) END makeCuckooSound;

    PROCEDURE makeSound*( bird : Bird );
    BEGIN
        WITH bird : Cuckoo DO makeCuckooSound(bird);
           | bird : Duck   DO makeDuckSound(bird)
          ELSE
            COPY("Tweet!", bird.sound);
        END;
    END makeSound;BEGIN
   NEW(pc);
   NEW(pd);
   
   makeCuckooSound( pc );
   makeDuckSound( pd );
   
   Out.Ln;Out.String( pc^.sound );Out.Ln;
   Out.Ln;Out.String( pd^.sound );Out.Ln;

   makeSound( pc );
   makeSound( pd );

   Out.Ln;Out.String( pc^.sound );Out.Ln;
   Out.Ln;Out.String( pd^.sound );Out.Ln;(* -------------------------------------- *)(* Pass dynamic type to procedure         *)

   pb := pd;

   makeDuckSound( pb(Duck) );
   Out.Ln;Out.String( pb^.sound );Out.Ln;

   pb := pc;

   makeCuckooSound( pb(Cuckoo) );
   Out.Ln;Out.String( pb^.sound );Out.Ln;(* -------------------------------------- *)

   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;

   pb := pd;
   
   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;(* -------------------------------------- *)
   NEW(pb);
   
   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;
   
END PointerBirds.
第三の方法として、IS 演算子を使った方法もある。これは、等号（=）や不等号（>）などと同じ優先順位の関係演算子であるが、動的な型の検査を行う。しかし、上述の2つの方法とは異なり、検出した派生型によって処理を振り分けることはできない。

文法

ALGOL - Pascal - Modula-2 - Oberon - Component Pascal の系列の言語は文法を単純化させてきたと言える。Oberon-2 はEBNFを使って下記のように33の構文生成規則で表せる（Mössenböck & Wirth, 1993）。
Module        = MODULE ident ";" [ImportList] DeclSeq [BEGIN StatementSeq] END ident ".".ImportList    = IMPORT [ident ":="] ident {"," [ident ":="] ident} ";".DeclSeq       = { CONST {ConstDecl ";" } | TYPE {TypeDecl ";"} | VAR {VarDecl ";"}} {ProcDecl ";" | 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 = "(" [FPSection {";" FPSection}] ")" [":" Qualident].FPSection = [VAR] ident {"," ident} ":" Type.Receiver = "(" [VAR] ident ":" ident ")".Type = Qualident
              | ARRAY [ConstExpr {"," ConstExpr}] OF Type
              | RECORD ["("Qualident")"] FieldList {";" FieldList} END
              | POINTER TO Type
              | PROCEDURE [FormalPars].FieldList = [IdentList ":" Type].StatementSeq = Statement {";" Statement}.Statement = [ Designator ":=" Expr
              | Designator ["(" [ExprList] ")"]
              | 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 ["(" [ExprList] ")"] | number | character | string | NIL | Set | "(" Expr ")" | " ~ " Factor.Set = "{" [Element {"," Element}] "}".Element = Expr [".." Expr].Relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.AddOp = "+" | "-" | OR.MulOp = " * " | "/" | DIV | MOD | "&".Designator = Qualident {"." ident | "[" ExprList "]" | " ^ " | "(" Qualident ")"}.ExprList = Expr {"," Expr}.IdentList = IdentDef {"," IdentDef}.Qualident = [ident "."] ident.IdentDef = ident [" * " | "-"].