在 IBM 1130 模擬器上跑 LISP 1.6!

作者:Lisp Taiwan http://wikipedia.org

先講個故事

Guy Steele ── Common Lisp The Language 2nd 的作者、Java 語言規範制定者、Common Lisp 標準化委員會成員 ── 早在高中時代,年僅十七歲,就在 IBM 1130 機器上,用 Assembly Language 寫出了 LISP。

故事是這樣子的,在 Guy Steele 就讀波士頓拉丁學校時,有個朋友帶他去了地下室,那裡有一台校友捐贈給學校的 IBM 1130。朋友給他展示了一段 5 行的 Fortran 程式,從此 Guy Steele 就對編程著迷了。接著在 1968 年的秋天,感恩節的連假期間,自學了 Fortran。又在聖誕節前後自學了 IBM 1130 的 Assembly。Guy Steele 與學校的朋友迷上了 IBM 1130,一有空就往 IBM 的辦公室跑,和那邊的員工聊天,並用微薄的零用錢,在市中心裡買計算機相關的刊物、也買一些 PL/I 的書。

時間來到 1969 年的春天,在一次類似校外參訪的機遇下, Guy Steele 來到了 MIT,每週六早上去,那邊的大學生(黑客)會教你一些酷炫的新玩意。就在那,Guy Steele 感染了黑客氣息,也更熟悉了 IBM 1130、DEC 公司的 PDP-10,以及精進了編程技術。

很快的他與幾個夥伴,跑到了 DEC 的辦公室,遞交了一份在 PDP-8 上實作 APL 的計畫(APL 是他在 1969 年春自己學的。)。雖然最後並沒有被 DEC 公司採納,但 Guy Steele 此時的編程實力已經不容小覷了。

在 1970 年左右,精準的說是 1972 年 2 月 14 日, Guy Steele 在 IBM 1130 上實作了 LISP 1.6,這與他去 MIT 參訪有很大的關聯。他自己是這麼說的(大意):“要不是在 MIT 看了許多精妙的 LISP 代碼,不然我也無法在 IBM 1130 上實作出 LISP”

模擬 IBM 1130

IBM 1130 在它所處的年代非常受歡迎,它是一款便宜的機種,也是因為便宜,它讓許多人體會到了,什麼是“個人電腦”的感覺。IBM 1130 在計算機歷史中佔有一席之地,有著一大堆愛好者。

愛好者成立了 http://ibm1130.org/

上面提供了 IBM 1130 模擬器,以及其它你所需要的軟件,都在上面。以下我將敘述,如何在 Linux / Mac OSX 上模擬一個 IBM 1130,跑一個簡單的 Lisp 程式,並使用 LISP 1.6 的 REPL。

下載 IBM 1130 模擬器及 LISP 鏡像。

下載並解壓縮:

1
2
3
$ mkdir ibm1130 && cd ibm1130
$ curl -O http://media.ibm1130.org/sim/ibm1130.zip -O http://media.ibm1130.org/lisp.zip
$ unzip '*.zip'

編譯 IBM 1130 執行檔

需要安裝 GCC。

1
$ make

注意,若是使用 linux 系的作業系統,make 之後會有錯誤:

1
undefined reference to `clock_getres'

這個在 time.h 定義的 clock_getres 函數,需要連結 librt.so 這個 Runtime 連結庫。

修改 makefile (MacOSX 無需修改),在 74 行最後加上 -lrt

1
2
${BIN}ibm1130 : ${ibm1130} ${SIM} ${ibm1130_INC} ${SIM_INC}
true${CC} ${ibm1130} ${SIM} -o $@ -lrt

編譯成功就看到目錄下有個 IBM 1130 的可執行檔。

Factorial in IBM 1130 LISP 1.6

1
$ touch fact.job

用你喜愛的編輯器輸入:

1
2
3
4
5
6
7
8
//JOB
//XEQ LISP
(SETQQ FACT (LAMBDA (N)
             (COND
               ((LESSP N 2) 1)
               (T (TIMES N (FACT (SUB1 N)))))))
(FACT 5)
(QUIT)

關於 IBM 1130 的 LISP 1.6 的語法可查閱這兩個手冊:

IBM1130-LispUsersGuidePart1.pdf   IBM1130-LispUsersGuidePart2.pdf

運行 fact.job:

1
2
3
4
5
6
7
$ ./ibm1130 job fact
IBM 1130 simulator V3.8-0
PRT: creating new file
Loaded DMS V2M12 cold start card

Wait, IAR: 0000002A (4c80 BSC  I  ,0028   )
sim>

進到模擬器輸入 quit

1
2
3
4
5
6
7
IBM 1130 simulator V3.8-0
PRT: creating new file
Loaded DMS V2M12 cold start card

Wait, IAR: 0000002A (4c80 BSC  I  ,0028   )
sim> quit
Goodbye

此時會產生一個 fact.lst 文件,打開看看程序運行的結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
PAGE   1

// JOB    1234

LOG DRIVE   CART SPEC   CART AVAIL  PHY DRIVE
  0000        1234        1234        0000

V2 M12   ACTUAL 32K  CONFIG 32K

PAGE   1

// JOB

LOG DRIVE   CART SPEC   CART AVAIL  PHY DRIVE
  0000        1234        1234        0000

V2 M12   ACTUAL 32K  CONFIG 32K

// XEQ LISP

***** 1130 LISP 1.6 ***** BOSTON LATIN SCHOOL ***** LITHP ITH LITHTENING...




(SETQQ FACT (LAMBDA (N) (COND ((LESSP N 2) 1) (T (TIMES N (FACT (SUB1 N)))))))

(LAMBDA (N) (COND ((LESSP N 2) 1) (T (TIMES N (FACT (SUB1 N))))))



(FACT 7)

5040



(QUIT)

***** 1130 LISP 1.6 ***** END OF RUN ***** THO LONG, COME AGAIN THOON

注意到別嘗試太大的數字,IBM 1130 的整數最大只到 32768(2 的 15 次方)。

IBM 1130 LISP 1.6 REPL

一個宏的例子:

1
2
3
4
5
6
7
8
9
10
$ ./ibm1130 job ilisp

(SETQQ CONSCONS (MLAMBDA X (COND
    ((NULL X) NIL)
    ((NULL (CDR X)) (CAR X))
    (T (LIST 'CONS (CAR X) (CONS 'CONSCONS (CDR X)))) )))

(CONSCONS A B C)

(A B . C)

輸入 (QUIT) 可離開 REPL。

你可以把 LISP 1.6 手冊上的指令在 REPL 裡都試一遍,在 1970 年,就有這樣的交互式環境,程序可直譯+編譯、宏、垃圾回收,太強大了!

而這只是 Guy Steele 17 歲寫的小 Project...


備註:

IBM 1130 的 LISP 實現源代碼 (Assembly):

IBM1130LispPart1.pdf   IBM1130LispPart2.pdf

所有的文件 Guy Steele 都以 CC 3.0 的授權釋出。