【futaba】三、沒有類型是什麼類型

如果每一篇文章都像前面兩篇那麼長,那不說有沒有人願意看,一篇幾小時的時間開銷我自己也吃不消。從今往後只有過年過節才碼長文,所有以這張亞絲娜作頭圖的都是粗製濫造的小短篇。哦,對應的commit是這一個,不過這篇文章只討論它最開頭的一點點所以看不看也無所謂。


承蒙 @目錄 同學的厚愛我有機會參考一下大大的類型系統。不過這回我沒參考上……不好意思

// `Piece` structure// Everything in Futaba is a `Piece`.struct _Piece;typedef struct _Piece *(*PieceFunc)(struct _Piece *, void *);struct _Piece { PieceFunc function; void *backpack;};typedef struct _Piece Piece;

這就是futaba里唯一的一種類型Piece的定義。簡單的說,一個Piece可以以另一個Piece為參數進行求值(當然也可以作為參數傳給另一個Piece),求值的結果還是一個Piece。一篇代碼在本質上就是這種互相作參數的一種描述,運行一篇代碼就是按照代碼里描述的順序依次把各個Piece以調用的方式「拼」在一起,最後形成一個大Piece。對這個Piece求值再把值扔掉,解釋器就完成工作了。

可以看出,Piece的模式有點像拼圖,所以我給它起名為「片」。不過拼圖並不能實現「把自己拼在自己身上」 等一系列違反物理規律的操作,所以我以後會以「超拼圖」稱呼一個Piece實例。

以上這段說明較好地反映在了代碼中,值得多說一句的是backpack。每塊超拼圖都有一個自己的背包,這個背包會在超拼圖被調用時起到閉包的作用:

Piece *apply(Piece *caller, Piece *callee) { return caller->function(callee, caller->backpack);}

(回憶一下上一個版本複雜的applyeval(這個版本已經不需要eval了)……恍如隔世。)不僅如此,它的void *類型也使得上篇文章中苦大仇深的「無法繼承類型」這一限制不復存在。當然,這也就意味著futaba退化成了真·弱類型語言(正如彙編語言)。不要緊,稍後我會在標準庫中實現類型系統需要的一切。

今天就寫到這裡吧。

推薦閱讀:

TAG:C編程語言 | 編譯器 | 編程 |