Oberon是一種通用編程語言,最初由尼克勞斯·維爾特在1987年推出,是維爾特風格的類ALGOL語言中的最後一員(繼Euler英語Euler (programming language)ALGOL WPascalModulaModula-2之後)[1][2][3][4]。Oberon是增進Pascal的直接後繼者Modula-2的能力,並減少其複雜度的集中努力的結果。它的原理性新特徵是記錄類型的數據類型擴展的概念[5]。它允許新數據類型構造在現存數據類型之上並將它們關聯起來,脫離了嚴格的靜態類型數據的教條。Oberon是在瑞士蘇黎世聯邦理工學院作為Oberon操作系統英語Oberon (operating system)實現的一部份而開發的。這個名字來自天王星的衛星奧伯隆

Oberon
編程範型指令式, 結構化, 模塊化, 面向對象
語言家族Wirth Oberon
設計者Niklaus Wirth
實作者蘇黎世聯邦理工學院
面市時間1987年,​37年前​(1987
型態系統強類型, 混合(靜態動態
作用域詞法
系統平台ARM, StrongARM; IA-32, x86-64; SPARC, Ceres英語Ceres (workstation) (NS32032英語NS32000)
操作系統Windows, Linux, Solaris, classic Mac OS, Atari TOS, AmigaOS
網站www.projectoberon.com
啟發語言
Modula-2
影響語言
Modula-3, Oberon-2英語Oberon-2, Component Pascal英語Component Pascal, Active Oberon英語Active Oberon, Oberon-07, Nim, Go, Zonnon英語Zonnon

Oberon的當前版本是2007年修訂的Oberon-07,它由維爾特來維護而Oberon計劃編譯器最近更新於2020年3月6日[6]

設計

Oberon的基本指導原則是集中於基礎和根本的特徵,並忽略短暫性的問題。另一個因素是認識到了在語言如C++Ada中複雜度的增長。與它們相反,Oberon強調使用概念來擴展語言。在Modula-2中提供的枚舉和子範圍類型被省略了,並且集合類型被限制為小的整數集合。所有的導入項目都必須用它們在其中聲明的那個模塊的名字來限定。通過只允許低層設施在包含了標識符SYSTEM於其導入列表的模塊中使用而突顯了它們。甚至跨越模塊的非常嚴格的類型檢查運行時間索引檢查空指針檢查和安全的類型擴展概念,在很大程度上允許編程單獨的依仗於語言規則。

這種策略的意圖是產生易於學習、實現更簡單和高效的語言。Oberon編譯器被認為是簡明和快速的,卻提供了可比擬於商業編譯器的代碼質量[7]

特徵

 
Oberon的曾用標誌

刻畫Oberon語言的特徵包括[8]

  • 具有大寫關鍵字的大小寫敏感語法。
  • 具有類型測試的類型擴展。
  • 模塊和分離編譯。
  • 字符串操作。
  • 孤立不安全代碼。
  • 支持系統編程。

面向對象示例

Oberon支持對記錄類型的擴展,用於抽象和異構結構的構造。不同於後期方言即1991年提出的Oberon-2英語Oberon-2和1998年提出的Active Oberon英語Active Oberon,最初的Oberon缺乏作為語言特徵的分派機制,而是把它作為一種編程技術或設計模式。這給出了在OOP上的巨大靈活性。在Oberon操作系統英語Oberon (operating system)中,兩種技術被一起用於分派調用:方法套件和消息處理器。

方法套件

在這種技術中,泛化模塊定義過程變量的一個表格類型,而擴展模塊中聲明這個類型的一個共享變量,泛化模塊中的方法要訪問這個表格的對應項目,而擴展模塊將這個表格的項目指派到自己相應的過程:

MODULE Figures; (* 抽象模块 *)

  TYPE
    Figure* = POINTER TO FigureDesc;
    Interface* = POINTER TO InterfaceDesc;
 
    InterfaceDesc* = RECORD
      draw* : PROCEDURE (f : Figure);
      clear* : PROCEDURE (f : Figure);
      mark* : PROCEDURE (f : Figure);
      move* : PROCEDURE (f : Figure; dx, dy : INTEGER);
    END;
 
    FigureDesc* = RECORD
      if : Interface;
    END;
 
  PROCEDURE Init* (f : Figure; if : Interface);
  BEGIN
    f.if := if;
  END Init;
 
  PROCEDURE Draw* (f : Figure);
  BEGIN
    f.if.draw(f);
  END Draw;
 
(* 这里是其他过程Clear、Mark和Move *)
 
END Figures.

擴展泛化類型Figure為特定形狀Rectangles

MODULE Rectangles;
 
  IMPORT Figures;
 
  TYPE
    Rectangle* = POINTER TO RectangleDesc;
 
    RectangleDesc* = RECORD
      (Figures.FigureDesc)
      x, y, w, h : INTEGER;
    END;
 
  VAR
    if : Figures.Interface;
 
  PROCEDURE New* (VAR r : Rectangle);
  BEGIN
    NEW(r);
    Figures.Init(r, if);
  END New;
 
  PROCEDURE Draw* (f : Figure);
    VAR
      r : Rectangle;
  BEGIN
    r := f(Rectangle); (* f具有Rectangle类型 *)
    (* ... *)
  END Draw;
 
(* 这里是其他过程Clear、Mark和Move *)
 
BEGIN (* 模块初始化 *)
  NEW(if);
  if.draw := Draw;
  if.clear := Clear;
  if.mark := Mark;
  if.move := Move;
END Rectangles.

動態分派只能通過泛化模塊的Figures中的方法集合完成,比如這裡的DrawClearMarkMove過程,它們通過接口表格調用了擴展模塊Rectangles中的同名過程。

消息處理器

這種技術形成於,在泛化模塊中定義一個單一的處理器過程類型,並在擴展模塊中聲明這個類型的一個過程,用它處理對應各種方法並包含了相應的實際參數的消息記錄:

MODULE Figures; (* 抽象模块 *)
 
  TYPE
    Figure* = POINTER TO FigureDesc;
 
    Message* = RECORD END;
    DrawMsg* = RECORD (Message) END;
    ClearMsg* = RECORD (Message) END;
    MarkMsg* = RECORD (Message) END;
    MoveMsg* = RECORD (Message) dx*, dy* : INTEGER END;
 
    Handler* = PROCEDURE (f : Figure; VAR msg : Message);
 
    FigureDesc* = RECORD
      (* 抽象 *)
      handle : Handler;
    END;
 
  PROCEDURE Handle* (f : Figure; VAR msg : Message);
  BEGIN
    f.handle(f, msg);
  END Handle;
 
  PROCEDURE Init* (f : Figure; handle : Handler);
  BEGIN
    f.handle := handle;
  END Init;
 
END Figures.

擴展泛化類型Figure為特定形狀Rectangles

MODULE Rectangles;
 
  IMPORT Figures;
 
  TYPE
    Rectangle* = POINTER TO RectangleDesc;
 
    RectangleDesc* = RECORD (Figures.FigureDesc)
      x, y, w, h : INTEGER;
    END;
 
  PROCEDURE Draw* (r : Rectangle);
  BEGIN
    (* ... *)
  END Draw;
 
  (* 这里是其他过程Clear、Mark和Move *)
 
  PROCEDURE Handle* (f: Figure; VAR msg: Figures.Message);
    VAR
      r : Rectangle;
  BEGIN
    r := f(Rectangle);
    IF msg IS Figures.DrawMsg THEN Draw(r)
    ELSIF msg IS Figures.MarkMsg THEN Mark(r)
    ELSIF msg IS Figures.MoveMsg THEN 
      Move(r, msg(Figures.MoveMsg).dx, msg(Figures.MoveMsg).dy)
    ELSE (* 忽略 *)
    END
  END Handle;
 
  PROCEDURE New* (VAR r : Rectangle);
  BEGIN
    NEW(r);
    Figures.Init(r, Handle);
  END New;
 
END Rectangles.

在Oberon操作系統中,這兩種技術都用於動態分派。前者用於已知的方法集合;後者用於在擴展模塊中聲明的任何新方法。例如,如果擴展模塊Rectangles要實現一個新的Rotate()過程,在擴展模塊之外只能通過它的消息處理器過程來調用。

參見

引用

  1. ^ Wirth, Niklaus. From Modula to Oberon and the programming language Oberon (報告). ETH Technical Reports D-INFK. Band 82. Wiley. [2021-06-18]. (原始內容存檔於2021-12-17). 
  2. ^ Wirth, Niklaus. The Programming Language Oberon. Software: Practice and Experience. July 1988, 18 (7): 661–670. 
  3. ^ Wirth, Niklaus. From Modula to Oberon. Software: Practice and Experience. July 1988, 18 (7): 671–690. 
  4. ^ Wirth, Niklaus. Type Extensions. ACM Transactions on Programming Languages. April 1988, 10 (2): 204–214. 
  5. ^ Pountain, D. March 1991. Modula's Children, Part II: Oberon. Byte英語Byte (magazine). Vol. 16 no. 3: 135–142. 
  6. ^ Wirth, Niklaus. Oberon Change Log. ETH Zurich. [2021-01-16]. (原始內容存檔於2019-04-07). 
  7. ^ Mössenböck, Hanspeter. Compiler Construction: The Art of Niklaus Wirth (PDF). Johannes Kepler University. [失效連結]
  8. ^ Niklaus Wirth; Jürg Gutknecht英語Jürg Gutknecht. Project Oberon. 1987–2021 [2021-06-18]. (原始內容存檔於2021-07-19). 

外部資源鏈接

一般性

Oberon的演化