簡體   English   中英

將函數式語言編譯為C語言

[英]Compiling functional languages to C

假設您正在為便攜式C編譯函數式語言,並且假設由於各種原因您需要精確而非保守的垃圾收集。 垃圾收集器沒有可移植的方法(在一般情況下可能完全沒有辦法)來弄清楚什么是C堆棧上的指針而不是指針。 在我看來,這個問題有兩個解決方案:

  1. 影子堆棧。 使每個C函數保持關於什么是指針和不是指針的簿記信息。 這是LLVM推薦的方法。

  2. 利用您正在編譯函數式語言的事實,這意味着主線代碼沒有副作用。 當分配器檢測到內存不足時,不是調用垃圾收集器本身,而是使用longjmp將當前操作中止回主循環,主循環調用垃圾收集器(在可能包含指針的變量集已知的上下文中)提前)然后重新開始操作。

在我看來,如果你正在處理第二種方法適用的純函數式語言,它必須比第一種方法更有效,並且更容易與手寫的C語言混合。

我有什么問題可以忽略嗎? 對此技術的現有討論或實現的任何引用?

可以使用單個數據結構設計純FP語言:

typedef enum record_type { RT_SYMBOL, RT_NUMBER, RT_PAIR };

struct record
{
  record_type type;
  void *value;  
};

程序和數據可以使用records pairs表示:

struct pair
{
  record *car;
  record *cdr;
};

這是一個簡單的表達式 - 2 * 3 - 如何使用records來表示:

record r1;
r1.type = RT_NUMBER;
r1.value = &two; 

record r2;
r1.type = RT_NUMBER;
r1.value = &three; 

record opr1;
opr1.type = RT_NUMBER;
opr1.value = &OP_MULT; /* A machine op-code for multiplication. */

pair p_oprnds;
p_oprnds.car = &r1;
p_oprnds.cdr = &r2;

pair p;
p.car = opr1;
p.cdr = p_oprnds;

這與Lisp表達式相同: (* 2 3) 現在,您可以定義一pairspairs上運行的機器,將car視為操作員,將cdr視為操作數。 由於我們只處理一種數據結構,因此可以使用精確的GC。 有關此類VM的體系結構,請參閱Lispkit Lisp

在開始嘗試編寫FP - > C編譯器之前,還要閱讀Small Pieces中的Lisp

我認為你沒有描述的最明顯的事情是如何處理持久的內存不足。 正如您所描述的那樣,假設我的操作使用的內存多於可用內存。 最終我到達:

  1. 開始操作的任何階段都超過限制。
  2. 跑了一會兒。
  3. 內存耗盡。
  4. 釋放此階段分配的所有內存(沒有其他內容可以免費)。
  5. 轉到1。

也就是說,一個無限循環。 所以至少你想要某種世代垃圾收集,它允許你檢測循環並退出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM