Modula-2,是一種通用的結構化過程式編程語言,由尼克勞斯·維爾特在1978年至1985年間於蘇黎世聯邦理工學院開發。它具有充分的靈活性用於系統編程,和更加廣闊應用領域。特別是,它被設計為以一種直接的方式支持分離編譯和數據抽象。它的很多語法基於了維爾特早先的周知語言Pascal

Modula-2
編程範型指令式結構化模塊化數據和方法隱藏英語information hiding並發
語言家族Wirth Modula
設計者尼克勞斯·維爾特
面市時間1978年,​46年前​(1978
型態系統強,靜態
系統平台Lilith英語Lilith (computer)AMD 2901英語AMD Am2900
操作系統跨平台
文件擴展名.mod .m2 .def .MOD .DEF .mi .md
網站www.modula2.org
主要實作產品
Niklaus Wirth編寫的ETH編譯器, GNU Modula-2, ADW Modula-2
衍生副語言
PIM2、PIM3、PIM4、ISO
啟發語言
Modula, Mesa, Pascal, ALGOL W, Euclid英語Euclid (programming language)
影響語言
Modula-3, Oberon, Ada, Fortran, Lua, Seed7英語Seed7, Zonnon英語Zonnon, Modula-GM

歷史 編輯

在1976年至1977年年間,維爾特在Xerox Palo Alto研究中心,與一群設計Alto電腦的工作夥伴一同工作。1978年,維爾特在瑞士聯邦理工學院資訊研究所,根據其早期對Pascal程式語言Modula模組程式語言、及Alto電腦的經驗,定義了Modula-2語言,他還開始了一個Lilith英語Lilith (computer)個人電腦計畫。

Modula-2語言本身與Lilith結構之設計,都以優雅及簡單為原則,是以Modula-2為Lilith的系統程式語言,而不需用到組譯器,並且以Lilith為Modula-2的組織架構。為此,Modula-2語言不僅要適用於編寫高階的應用程式,也要應適用於編寫低階的與機器相關的編碼程式,用於裝置的操控與儲存體的配置。

Modula-2提供了一些標準程式庫模組,如異常處置、字串處理、輸入/輸出及並行程式設計等,通過重複使用它們來降低語言本身的複雜度。在Lilith計畫從1978年到1988年的整個生命期中,作業系統、繪圖套裝軟體、資料庫系統、網路協議、檔案伺服器,及許多其他系統和應用模組,都是藉著Modula-2發展出來的。

描述 編輯

Modula-2被設計為顯著的類似於Pascal,移除了一些元素和語法歧義,增補了「模塊」這個重要概念,並且對多道程序有直接的語言支持。維爾特將Modula-2看作他早期的編程語言PascalModula的後繼者[1][2]。主要的概念是:

  1. 模塊是分離編譯的編譯單元。
  2. 協程並發處理的基本建造塊。
  3. 類型和過程允許訪問特定於機器的數據。

Modula-2提供了(有限的)單處理器並發(監視器協程和顯式控制轉移)和硬件訪問(絕對地址、位操縱和中斷)。它使用了名稱類型系統英語nominal type system。Modula-2語言允許使用一趟編譯器英語One-pass compilerGutknecht英語Jürg Gutknecht和維爾特的這種編譯器大致上比早前的多趟編譯器英語Multi-pass compiler要快上四倍[3]

Modula-2有兩種主要方言:PIM和ISO/IEC 10514-1:1996,PIM得名於Niklaus Wirth的著作《Programming in Modula-2》[4],這本書一共有四個版本,成為方言的是PIM2(1983年)、PIM3(1985年)和PIM4(1988年)。

例子代碼 編輯

下面是"Hello world"程序的Modula-2源代碼例子:

MODULE Hello;
  FROM STextIO IMPORT WriteString;
BEGIN
  WriteString("Hello World!");
END Hello.

語言元素 編輯

保留字 編輯

PIM版本2、3、4定義了40個保留字

AND         ELSIF           LOOP       REPEAT
ARRAY       END             MOD        RETURN
BEGIN       EXIT            MODULE     SET
BY          EXPORT          NOT        THEN
CASE        FOR             OF         TO
CONST       FROM            OR         TYPE
DEFINITION  IF              POINTER    UNTIL
DIV         IMPLEMENTATION  PROCEDURE  VAR
DO          IMPORT          QUALIFIED  WHILE
ELSE        IN              RECORD     WITH

內建標識符 編輯

PIM版本3、4定義了29個內建標識符

ABS         EXCL            LONGINT    REAL
BITSET      FALSE           LONGREAL   SIZE
BOOLEAN     FLOAT           MAX        TRUE
CAP         HALT            MIN        TRUNC
CARDINAL    HIGH            NIL        VAL
CHAR        INC             ODD
CHR         INCL            ORD
DEC         INTEGER         PROC

模塊 編輯

Modula-2的模塊(module),可以用來封裝一組有關的子程序和數據結構,並限制它們對程序其他部份的可見性。模塊設計以清晰的方式,實現了Modula-2的數據抽象特徵。語言有嚴格的作用域控制。模塊的作用域,可以被當作是不可逾越的牆:除了標準標識符之外,來自外部的對象在模塊內是不可見的,除非顯式的導入它;內部的模塊對象在外部是不可見的,除非顯式的導出它。

Modula-2程序是由模塊組成,其中「程序模塊」包含一個Modula-2程序的主程序。所有Modula-2程序,必須有定義了執行開始之處的一個主程序。在一個單一的程序中,不能有鏈接在一起的兩個程序模塊。「局部模塊」是在其他模塊內聲明的模塊。程序模塊和局部模塊的起始關鍵字,就是單獨的MODULE

定義模塊與實現模塊 編輯

除了程序模塊之外的「全局模塊」,都構成自兩個部份:作為接口部份的「定義模塊」,它只包含「導出」(對其他模塊可見)的那部份子系統,和同名的「實現模塊」,它包含模塊內部的工作代碼:

DEFINITION MODULE GM;
  ...
  
IMPLEMENTATION MODULE GM;
  ...

定義模塊中可以包含不透明類型英語Opaque data type聲明,它有如下形式:

TYPE name;

它對應的實際類型,對於這個模塊的用戶是不可見的。這個類型名字,可以用在定義模塊內的其他聲明之中。對於在定義模塊中聲明的任何不透明類型,在對應的實現模塊中,必須包含它的完全類型聲明。完全類型聲明,必須定義一個指針類型。

導出 編輯

假定局部模塊M1導出對象abcP,可將它們的標識符列舉於顯式EXPORT導出列表之中:

MODULE M1;
  EXPORT a, b, c, P;
  ...

如果加上了可選的關鍵字QUALIFIED,它們以一種有限制的方式給導出至外部,必須將導出的這個模塊名字用作限定符,並跟隨着對象的名字。這裡的來自模塊M1的對象abcP,在模塊M1外部就叫做M1.aM1.bM1.cM1.P

PIM2在定義模塊中要求顯式的EXPORT子句;PIM3從定義模塊中刪除了EXPORT子句,因為發現了它是多餘的。

導入 編輯

假定模塊M2包含下列IMPORT聲明:

MODULE M2;
  IMPORT M1;
  ...

然後這意味着模塊M1導出至它所包圍的程序的外部的對象,現在可以用在模塊M2內部。它們以一種限定方式來引用,也就是M1.aM1.bM1.cM1.P。例如:

  ...
  M1.a := 0;
  M1.c := M1.P(M1.a + M1.b);
  ...

限定導出避免了名字衝突:例如,如果另一個模塊M3也導出了一個對象叫做P,那麼我們仍可以區分這兩個對象,因為M1.P不同於M3.P。憑藉限定導出,兩個對象在它們的導出模塊M1M3中都叫做P是不礙事的。

存在一種可作為替代的方式,它在Modula-2編程者中廣泛採用。假定模塊M3是公式化為如下:

MODULE M3;
  FROM M1 IMPORT a, b, c, P;

然後這意味着模塊M1導出至外部的對象,可以用在模塊M3內部,但可以用無限定方式來引用導出的標識符,也就是abcP。例如:

  ...
  a := 0;
  c := P(a + b);
  ...

這種無限定導入的方法,允許在其導出模塊之外,以同在它們的導出模塊之內一樣簡單的方式,來使用這些變量和其他對象。對於所有這些已經被顯式允許的對象,包圍所有模塊的牆變得與它們無關了。當然無限定導入只在沒有名字衝突時是可用的。

這些導出和導入規則,看起來可能是沒有必要的限制和冗餘的。但是它們不只是守衛對象免於不希望的訪問,而且還有一個讓人愉悅的副作用,提供了在程序中定義的所有標識符的自動交叉引用:如果標識符被一個模塊名字所限定,那麼它的定義位於那個模塊。否則如果它是無限定的出現的,簡單的回溯查找,將會要麼遇到這個標識符的聲明,要麼遇到它出現在一個IMPORT語句中,指出了它所來自的模塊的名字。這個性質在嘗試理解包含很多模塊的大型程序時是非常有用的。

參見 編輯

引用 編輯

  1. ^ Wirth, Niklaus. Pascal and its Successors. Broy, Manfred; Denert, Ernst (編). Software Pioneers: Contributions to Software Engineering. Berlin, Heidelberg: Springer-Verlag. 2002: 108–120. ISBN 978-3-642-59412-0. doi:10.1007/978-3-642-59412-0. 
  2. ^ Wirth, Niklaus. History and Goals of Modula-2. Dr. Dobb's Journal (Informa PLC). 18 February 2005 [2021-06-15]. (原始內容存檔於2021-04-10). 
  3. ^ Wirth, Niklaus. A Single-pass Modula-2 Compiler for Lilith (PDF). CFB Software. 1 May 1984 [28 January 2019]. (原始內容 (PDF)存檔於2021-01-24). 
  4. ^ Wirth, Niklaus. Programming in Modula-2 4th. Berlin, Heidelberg: Springer. 1988. ISBN 978-3-642-83565-0. doi:10.1007/978-3-642-83565-0.  Page 4.

圖書 編輯

外部連結 編輯

本條目部分或全部內容出自以GFDL授權發佈的《自由線上電腦詞典》(FOLDOC)。