Tôi muốn thực hiện các hàm bậc cao hơn (HOF) trong C làm đường cú pháp với nỗ lực tối thiểu. Ví dụ, đối với đoạn mã sauCác hàm bậc cao hơn trong C dưới dạng đường cú pháp với nỗ lực tối thiểu
function add(int x) {
return int(int y) {
return x + y;
};
}
int main() {
function add1 = add(1);
return add1(2);
}
nó được transcompiled vào C tinh khiết như
#include <stdlib.h>
typedef struct {
void *ctx;
void* (*fun)(void *arg, void *ctx);
} function;
function new_function(void *ctx, void* (*fun)(void *, void *)) {
function f = {.ctx=ctx, .fun=fun};
return f;
}
void* apply(function f, void *arg) {
return (*(f.fun))(arg, f.ctx);
}
typedef struct {
int x;
} context$1;
void* new_context$1(int x) {
context$1 *ctx = malloc(sizeof(context$1));
ctx->x = x;
return ctx;
}
void* function$1(void *arg, void *ctx) {
int y = (int)arg;
int x = ((context$1*)ctx)->x;
return (void*)(x + y);
}
function add(int x) {
return new_function(new_context$1(x), function$1);
}
int main() {
function add1 = add(1);
return (int)apply(add1, (void*)2);
}
Tôi đã chạy phiên bản (bằng tay) transcompiled và nó hoạt động tốt. Để thực hiện, tôi tin rằng một số thao tác AST và nâng lambda là đủ.
Có bất kỳ sai sót tiềm năng nào trong cách tiếp cận của tôi không? Có phương pháp nào dễ dàng hơn cho HOF hay tôi có thể cải thiện phương pháp tiếp cận của mình để dễ thực hiện hơn không?
Tôi hoàn toàn đồng ý với điểm thứ hai của bạn và +1 cho Boehm GC :-). Nhưng có thể vui lòng giáo dục tôi như thế nào sẽ void * cuối cùng phá vỡ?Tôi tin rằng họ sẽ làm việc tốt vì chúng được tạo tự động. –
@XiaoJia: vấn đề với 'void *' nằm trong 'hàm $ 1'. Điều gì sẽ xảy ra nếu loại 'x + y' lớn hơn' void * '? Trong ví dụ này có nghĩa là 'sizeof (int)> sizeof (void *)', đó sẽ là một thực thi C lạ, nhưng không quá lạ nếu 'x' có kiểu' long long' thay vì 'int'. Sau đó, các diễn viên để 'void *' mất thông tin. –
Vâng, bạn luôn có thể nói rằng trình dịch tự động của bạn sẽ chăm sóc nó bằng cách nào đó (miễn là bạn không mô tả thuật toán nhưng chỉ cung cấp một bản dịch ví dụ). Nhưng tôi chỉ nhìn vào (void *) 2 và thấy rằng nó sẽ mất thông tin nếu có một số giá trị lớn hơn con trỏ thay vì 2. (Và truyền đến/từ void * sẽ không hoạt động ở tất cả các cấu trúc được truyền theo giá trị; bạn có từ chối hỗ trợ tất cả hay không, hoặc bạn sẽ dịch các chức năng như vậy một cách khác nhau?) –