iT邦幫忙

2024 iThome 鐵人賽

DAY 3
1

書接上回,塵界程式碼彼此依賴,如樹、如網。要想脫出這張樹網,自成一個世界,固然可以一切用組合語言(下稱真言)寫就,但常人負荷不了如此巨大的工作量,借鑑塵界軟體的發展史,先造出一門高階語言,再以此撰寫程式,能大幅加快構造世界的速度。

自舉高階語言編譯器

X 語言的編譯器,未必就要用 X 語言來寫就,但如果能夠 X 語言來寫自己的編譯器,就象徵了 X 語言已經成熟到一定程度,其自成一格,不需要依賴另一種語言。

但若欲「離塵」,就需要去除掉塵界的所有依賴,就斷不可用塵界的語言來寫新世界語言的編譯器了。自舉不再是可選項,而是唯一的方法。

然而,還沒有可執行的 X 語言編譯器時,就算把 X 語言編譯器源碼寫好了,要怎麼編譯出可執行的 X 語言編譯器呢?這是一個雞生蛋蛋生雞的問題,在不同條件下各有做法。

洪荒年代

在還沒有高階語言的年代(195X 之前),要創造高階語言就只能由真言寫起了。流程如下:

  1. 以真言寫出 X 語言零號編譯器 X0。
  2. 以 X 語言寫出 X 語言初號編譯器 X1 源碼。
  3. 用 X0 編譯 X1 源碼,得到 X1。

或者也可以選擇:

  1. 用 X 語言來寫 X 語言的編譯器 X1 。(此時還沒有可執行的 X 語言編譯器)。
  2. 人肉將編譯器 X1 的源碼翻譯成真言,得到可執行的 X 語言編譯器 X1-0。
  3. 用 X1-0 編譯自身原始碼,得到非人肉翻譯的編譯器 X1-1。

這兩種流程其實大同小異,終究都是用人肉寫出第一版編譯器,不過第二種流程在生成第一版編譯器時,是根據 X 語言的源碼爲藍本逐句生成的,較有所憑依,算是流程上的一點優化。

近現代

軟體發展至今,早已有幾十種甚至數百種成熟可靠的語言可用,自舉之初,不必像洪荒年代直接手寫真言,而可以採用現成語言來寫零號編譯器。假設我們採用成熟的 C 語言來輔助自舉,流程如下:

  1. 用 A 語言來寫 X 語言的零號編譯器 X0 。
  2. 以 X 語言寫出 X 語言初號編譯器 X1 源碼。
  3. 用 X0 編譯 X1 源碼,得到 X1。

舉個實際例子, Rust 一開始用 Ocaml 來寫前幾版 Rust 編譯器,待 Rust 編譯器成熟後,再以 Rust 語言重寫一份 Rust 編譯器。此時 X = Rust , A = Ocaml

迭代

寫出完整的 X 語言未必是一蹴而就,畢竟,設計新語言需要反覆實驗,幾乎不可能在零號或初號編譯器就定完 X 語言而毫無問題,很有可能在自舉的過程中才會發現設計缺失。所以初號編譯器所能編譯的語言已經與零號編譯器有所不同了,在語言特性尚未穩定之前,每一版的編譯器都可能不相互兼容。

在洪荒年代,更有可能的狀況是,手寫真言實在太累了。因此零號編譯器只有十分簡單的功能,它僅能編譯 X 語言的子集 X--,例如,僅支援迴圈、分支、函數這幾個最簡單的語言特性。得到了 X-- 編譯器之後,用 X-- 寫一個 X- 編譯器(X- 是能力介於 X-- 與 X 之間的語言),再將 X-- 寫就的 X- 編譯器擴展為用 X- 寫就的 X 編譯器,如此反覆迭代,才最終得到原先定義好的 X 於言編譯器。


上一篇
序・去往新世界
下一篇
什麼語言容易自舉
系列文
離塵指引.卷之一.試結丹:程式語言自舉36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言