感觉还可以呀~ 除了 symbol table 保存的居然是 symbol name 而非 symbol 本身,都是很正统、很普遍的写法。cons 前保护引用,cons 后解除什么的,也都很常见。总之目前没什么问题。
建议的话,比如 GC 可以改成
void **root = NULL;
size_t total_allocated = 0;
void *gc_alloc(size_t s) {
void **res = (void **)malloc(s + sizeof(void *) * 2);
assert(("allocation fail", res != NULL));
total_allocated += s + 2;
res[0] = (voie *)root; root = res;
res[1] = s;
// rmaybe res[2] is type?
return res + 2;
}
void gc() {
void **p = root;
while (p != NULL) {
void **next = (void **)p[0];
if (!scanned(p)) free(p);
p = next;
}
}
又比如,现在的代码命名又有点不清晰?以及为了精确回收,可以使用一些宏?类似
/* I believe this function could be inlined */
INLINE void __protect(int n, ref *xs) {
int i;
for (i = 0; i < n; i++) push(xs[i]);
}
#define protect(...) (__protect(sizeof((ref[]){__VA_ARGS__})/sizeof(ref), (ref[]){__VA_ARGS__});
// see the following link for the technology
// https://github.com/emacs-mirror/emacs/blob/9a431e431ad92f94f4290c3f0bf043b0f97a7b56/src/lisp.h#L4492
然后就可以用 protect(a, b) 来保护 a、b 两个变量了。