Oberon/ETH Oberon/Tutorial/編譯器
這些教程頁面由 André Fischer (afi) 編寫,Hannes Marais 提供編輯協助,託管在 ETHZ,並保留在 ETH 許可 下。相關內容可以在系統中透過 Book.Tool 找到。擴充套件內容也可在 紙質版 上找到。一些教程頁面在 WayBack 存檔 中。
學習使用 Oberon 編譯器及其稱為構建器的前端。
預計時間:30 分鐘。
編譯器的輸入是文字。這些文字方便地在文字檢視器中使用系統編輯器[1]建立。以下命名約定 (廣泛使用) 建議用於儲存源程式的檔案
- name.Mod 其中 name 通常對應於模組的名稱 (MODULE name;)。
有關 Oberon 程式語言的介紹,請參閱 有關 Oberon 的文獻。但學習一門新的程式語言的唯一方法是閱讀和編寫該語言的程式。
第一個程式對於所有程式語言都是一樣的!在 Oberon 中,編寫 hello, world 的程式是
MODULE Hello;
IMPORT Out;
PROCEDURE World*;
BEGIN
Out.String("hello, world");
Out.Ln
END World;
END Hello.
要學習如何使用編譯器,請按照以下步驟操作
- 標記 上面的文字並執行 Compiler.Compile * ,[2]
- 觀察 Oberon 日誌中的訊息
正在編譯 Hello 33
模組名稱後面的數字是現在儲存在當前目錄中的目標檔案的大小。 - 執行 Hello.World 並觀察日誌中的輸出 hello, world。
編譯器是 Oberon 系統的重要組成部分。除了核心的一部分,Oberon 系統 3 是用原始的 Oberon 語言實現的。提供的編譯器是 Oberon-2 編譯器。原則上,任何 Oberon-2 編譯器都與系統 3 相容,並且可以使用 Oberon-2 編寫和編譯系統 3 程式。 編譯器可以生成兩種型別的目標檔案:包含目標機器程式碼的經典本地目標檔案,或者預設情況下,瘦二進位制檔案。瘦二進位制檔案是一種新的目標檔案形式,它根本不包含目的碼,而是一個模組內容的行動式描述,這使得這些檔案完全獨立於最終的目標機器 (平臺無關)。目的碼生成是由模組載入器 (取決於底層硬體) 在執行時進行的,並且與載入傳統目標檔案的時間一樣長。
模組 Compiler 只匯出兩個命令,它們在 Compiler.Tool 中的幾個變體中都有文件,並在下面描述。
Compiler.Compile @[\options] 編譯從最近的文字選擇開始的原始碼。
Compiler.Compile *[\options] 編譯標記的檢視器的原始碼。
這兩個第一個命令變體允許直接從文字編輯器編譯模組:不需要先儲存文字。
Compiler.Compile {[\dst=pathName] [\options] {fileName[\options]}}~ | ^ 編譯引數列表中命名的檔案的文字。pathName 指示編譯器將新目標檔案儲存在指定的子目錄中。
options 是
- s - 啟用生成新的 symbol 檔案
- e - 啟用生成 extended 符號檔案
- u - 如果目標檔案是最新的,則抑制編譯
- w - 啟用生成 warning 訊息
編譯一系列模組時,檔名順序必須符合模組匯入層次結構:從底層到頂層;也就是說,模組的客戶端必須在模組本身之後編譯。您可以透過使用 構建器 功能來避免這種情況。請注意,每個檔名後都可以跟選項。
以下選項僅在編譯器必須生成本地目標檔案時才有效。這些檔案不跨平臺邊界可移植。因此,這些選項應僅在編寫使用低階模組 SYSTEM 或內建 SIZE 函式的擴充套件時使用。示例:Win.Audio.Mod
- N - nable 生成本地目標檔案
- a - 抑制為 ASSERT 函式生成程式碼
- p - 抑制將本地 pointers 初始化為 NIL
- x - 停用 Index 檢查
- n - 停用 NIL 檢查
- t - 停用 Type 檢查
- v - 啟用 Overflow 檢查
- c - 停用 Range Checks
- r - 抑制生成 ref-info
- d - 生成 MacsBug debugger 資訊 (MacOberon)
- f - find 對應於所選程式計數器值的文字位置
- g - 抑制此次編譯後的 garbage 收集
如果抑制垃圾收集,編譯執行速度更快,但如果使用了太多記憶體或太多檔案,則可能無法完成編譯 (將捕獲)。
指定目標檔案路徑 - Compiler.SetDestPath
[edit | edit source]Compiler.SetDestPath pathName 指示編譯器將新的目標檔案儲存在指定的子目錄中。
指導載入精簡二進位制檔案
[edit | edit source]以下命令影響精簡二進位制檔案的載入
OMI.AssertsOn / OMI.AssertsOff 啟用/停用為 ASSERTS 函式生成程式碼。
OMI.ChecksOn / OMI.ChecksOff 啟用/停用索引檢查。
OMI.RefsOn / OMI.RefsOff 啟用/停用生成詳細引用資訊。
這些命令可以方便地放在 Configuration.Text 檔案中。
在執行之前解除安裝模組
[edit | edit source]如果您對模組進行更改,並在使用(即載入)後重新編譯它,您必須使用 System.Free 命令或使用滑鼠將其解除安裝
當滑鼠焦點位於命令名稱 M.P 上並且按下滑鼠中鍵時,□ ■ 左鍵點選會解除安裝包含該命令的模組 M 並載入它的新副本,然後執行該命令。
程式設計師提示和警告: 這在開發和除錯 Oberon 過程時非常有用。這是一個方便的快捷方式來執行 System.Free 命令,但只有在模組 M 沒有客戶端時才會解除安裝它。因此,請記住 System.Free 以及 Builder.Free 提供了額外的可能性。
如果您的更正沒有產生任何影響,請不要感到驚訝:舊的 模組版本仍在控制中!您經常會忘記強制系統使用更新的版本。
以下示例應有助於具體化之前所說的話
MODULE Client; IMPORT Hello; PROCEDURE MyAction*; BEGIN Hello.World END MyAction; END Client.
- 選擇模組文字的開頭
- 執行 Compiler.Compile @
- 執行 Client.MyAction
- 執行 System.Free Hello ~
- 觀察並解釋日誌訊息:Hello 解除安裝失敗
編譯修改後的示例
[edit | edit source]MODULE Hello;
IMPORT Out;
PROCEDURE World*;
BEGIN
Out.String("hello, world");
Out.Ln
END World;
END HELLO.
- 修改文字 "hello, world"(例如 "Hello Oberon")
- 執行 Compiler.Compile *(即重新編譯程式)
- 執行 Hello.World 並檢視 Oberon 日誌中如何顯示相同的 "hello, world"。
- 強制系統解除安裝模組並使用滑鼠中鍵 + 左鍵點選執行命令 Hello.World 的新版本。
定位和糾正語法錯誤
[edit | edit source]MODULE Hello;
IMPORT Out;
PROCEDURE World*;
BEGIN
Out.String("hello, world");
Out.Ln
END World;
END HELLO.
- 刪除程式中的分號
- 將插入符號移動到文字中的另一個位置
- 執行 Compiler.Compile *
然後 Oberon 日誌顯示compiling Hello pos nn err 39 - 選擇包含錯誤訊息的行,然後單擊 Oberon 日誌選單欄中的 [Locate] 按鈕。這將把插入符號設定在缺少分號的位置。錯誤可以很容易地糾正。
除錯編譯器檢測到的語法錯誤
[edit | edit source]編譯器檢測到的錯誤在 Oberon 日誌中以以下形式的訊息報告
pos <錯誤位置> err <錯誤編號>
含義:錯誤 <錯誤編號> 發生在源文字中的位置 <錯誤位置>。
以下過程將插入符號放置在源文字中的錯誤位置
- 確保源文字出現在檢視器中
- 標記檢視器
- 在 Oberon 日誌中選擇包含錯誤訊息的行
- 單擊選單欄中的 [Locate] 按鈕或
- 執行命令 TextDocs.Locate 或
- 執行命令 Edit.Locate.
在某些版本中,Oberon 編譯器錯誤編號及其簡短說明列在 OberonErrors.Text 中。在 PlugIn Oberon 中,它執行在各種 MS Windows 系統上,該檔名為 OP2.Errors。在 Oberon 2.3.7 中,類似的列表位於 Oberon.Text 的 Errors 部分。 [3]
您需要重新編譯模組,直到沒有報告錯誤。但是,可能會發出警告,但它們不被視為錯誤,因此會建立目標檔案。
陷阱檢視器
[edit | edit source]如果命令執行失敗,執行時錯誤會導致程式異常終止,並且會在文字檢視器 'System.Trap' 中顯示錯誤報告。導致陷阱的錯誤由陷阱程式碼標識,顯示某些系統暫存器的內容,並顯示過程啟用堆疊,從呼叫堆疊頂部的過程開始。所有標量變數和字串以及它們的值也列出。
MODULE Trap; VAR arr: ARRAY 3 OF INTEGER; PROCEDURE count(n: INTEGER); BEGIN arr[n] := n; count(n+1) END count; PROCEDURE ForceIt*; BEGIN count(0) END ForceIt; END Trap.
- 選擇模組文字的開頭
- 執行 Compiler.Compile @
- 執行 Trap.ForceIt 並研究檢視器的內容。
最初,陷阱程式碼在 OberonErrors.Text 的末尾進行了解釋。隨後,當陷阱檢視器被建立或增強時,OberonErrors.Text 中的解釋變得多餘並被刪除。
為了找到失敗的語句,只需顯示源程式並標記其檢視器。然後在陷阱檢視器中選擇包含感興趣過程名稱的行,並使用 "\d" 或 "\f" 選項重新編譯程式。
使用構建器
[edit | edit source]Builder 為上面描述的 Oberon 編譯器提供了一個方便的前端。它確保模組文字以正確的順序呈現給編譯器,無論引數列表中檔名的順序如何。但是,它不是真正的 make 工具:必須指定所有要編譯的模組。請注意,引數列表必須包含檔名:這些檔名可能與模組名稱不同,但這只是一個約定問題。Builder 模組命令在 Builder.Tool 中有記錄。
編譯源文字 - Builder.Compile
[edit | edit source]Builder.Compile [\options] * 編譯標記的檢視器的源文字。文字中插入的所有錯誤標記都將被刪除。
Builder.Compile [\options] ({fileName}~ | ^ | *) 編譯引數列表中命名的檔案的文字,自動確定模組的正確編譯順序。必須指定所有要編譯的模組,即它不是真正的 make 工具。選項與 Compiler.Compile 命令的選項相同。
有效處理編譯器檢測到的錯誤
[edit | edit source]Builder.MarkErrors [^] 當選擇包含編譯器在 Oberon 日誌中寫入的錯誤訊息時,此命令會為該訊息以及所有後續訊息在標記的文字中插入錯誤標記。錯誤標記是一個特殊的(構建器)小工具,它顯示在程式文字中該位置發現的錯誤程式碼的編號。以下錯誤訊息
pos 111 err 4
將在位置 111 處放置 4。
Builder.NextError 將插入符號前進到下一個錯誤標記。當到達文字末尾時,搜尋將環繞回到開頭。
Builder.ClearErrors 刪除標記文字中的所有錯誤標記。由 Builder.Compile * 命令自動執行。
解除安裝模組 - Builder.Free
[edit | edit source]Builder.Free {fileName}~ | ^ 以正確的順序解除安裝引數列表中命名的每個模組。由於檔名必須出現在引數列表中,因此此命令只能釋放源文字可用的模組。要解除安裝其他模組,請使用 System.Free.
插入模組圖示 - Builder.InsertHierarchy
[edit | edit source]Builder.InsertHierarchy {fileName}~ | ^ 在插入符號處為引數列表中命名的每個模組插入一個圖示。圖示以正確的編譯順序插入。每個圖示都帶有檔名作為標題,並且它的Cmd 屬性值為 "Desktops.OpenDoc '#Caption '". 在 Compiler.Panel 中可以找到此類圖示的示例。
使用分析器
[edit | edit source]分析器為 Oberon 編譯器提供了一個便捷的補充,用於在語法正確的程式文字中查詢其他潛在錯誤。編譯器錯誤首先報告。不生成目的碼。分析器定位
- 未匯出的專案(變數/常量/型別/欄位),這些專案已宣告但從未使用過,在初始化 (*) 之前使用過,從未初始化過,以及初始化過但從未使用過。
- 未匯出的 [型別繫結] 過程,這些過程從未呼叫過。
- 從未使用的匯入模組。
(*) 對於在不同範圍內宣告的變數,不會產生警告(但是,請參閱選項 \u)。
分析器模組命令在 Analyzer.Tool. 中有記錄。
Analyzer.Analyze @[\options] 分析從最新文字選擇開始的源文字。
Analyzer.Analyze *[\options] 分析標記檢視器的源文字。
這兩個命令的第一個變體允許直接從文字編輯器分析模組:無需先儲存文字。
Analyzer.Analyze {fileName[\options]}~ | ^ 分析引數列表中命名的檔案的源文字。
Analyzer.Analyze 透過以下形式的訊息警告 Oberon 日誌中可能出現的錯誤
pos <error position> warning <warning number>
請參閱 除錯編譯器檢測到的語法錯誤.
Analyzer.Analyze 還報告模組中語句(賦值、if、while、過程呼叫等)的數量。這對於確定程式的複雜性(而不是行數)很方便。
錯誤標記可以插入源文字中,如 有效處理編譯器檢測到的錯誤 中所述。
可以透過指定一個或多個 選項 獲得更多資訊
- i (intermediate) - 定位
- - 已經在外部範圍內宣告的專案。
- - 對中間專案的使用或賦值,例如在外部範圍內宣告的區域性變數/引數。
- s (evaluation sequence) - 定位引數列表中出現函式呼叫的多引數過程的呼叫。引數的求值順序可能會影響這些函式的副作用。
- t (type-bound) - 定位
- - 型別繫結過程的重新定義。
- - 在擴充套件型別中對型別繫結過程的重新定義。
- u (used) - 定位在不同範圍內宣告並在設定之前使用的變數。
- v (VAR parameter) - 定位用作 VAR 引數的變數,因此不能確保已初始化這些變數。
- x (exported) - 定位已宣告但模組本身未使用、在初始化之前使用、從未初始化或已初始化但從未使用的匯出專案。
A
Analyzer.Analyze
Analyzer.Tool
B
Builder.ClearErrors
Builder.Compile
Builder.Free
Builder.InsertHierarchy
Builder.MarkErrors
Builder.NextError
Builder.Tool
C
Compiler.Compile
Compiler.Panel
Compiler.SetDestPath
Compiler.Tool
E
N
O
S
T
U
修訂,afi 1996 年 12 月 10 日
安裝於 1997 年 05 月 30 日
- ↑ 在 V2(Ceres Oberon)中 Edit.Open <fileName> 。在 ETH Oberon 中 Edit.Open <fileName> 或 ET.Open <fileName> 。在 V5(FPGA Oberon)中 Edit.Open <fileName> 。
- ↑ 可以在 ETH Oberon 中使用 MM 執行的命令是深紅色。目標超連結是藍色。非目標超連結是猩紅色。
- ↑ 郵件列表有一個從 2023-01-07 開始的討論。