robot
最新文章(10)
這並不是一個創新
Tossug 2/9 SVG 加 XBL 分享
SVG and XBL No Widget
OpenSource 與嵌入式系統
Internet 的工人智慧
GCC Spec Files
Android Native code 的繪圖方法
Android Native code 不用 NDK
基於隱私的一種 DRM
Build Android SDK on FreeBSD
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (120)
Python (93)
FreeBSD (71)
WEB (61)
雜記 (48)
URL (48)
hardware (46)
javascript (36)
Linux (31)
blog (30)
所有關鍵字
新增 URL
真 C 語言實做 Functional Language 的 Currying
by thinker
2 Columns
關鍵字:
coding
C
C++
jserv 寫了一篇 linkname:[$C$ 語言實做 Functional Language 的 Currying] http://blog.linux.org.tw/~jserv/archives/002029.html ,結果根本不是用 $C$ 實作,其中使用了大量的 assembly 或者是 opcode,讓我大呼「中招了」。既然如此,我就重新 implement 一個完全使用 $C$ 的 「真 $C$ 語言」 版本。本$範例$基本上分成兩個部分,前半部著眼於「收集參數,最後才將參數傳送給 target function ,並執行」,後半部著眼於「如何將資料和 target function 包裝成一個 partial function 的外觀」。 {{{#!cpp #include <stdio.h> #include <stdlib.h> #include <string.h> #define ERROR() typedef struct _curry { void *func; int max; int cur_sz; char *buf; } curry_t; void _new_curry(curry_t *co, void *func) { co->func = func; co->max = 32; co->cur_sz = 0; co->buf = (char *)malloc(32); } curry_t *new_curry(void *func) { curry_t *co; co = (curry_t *)malloc(sizeof(curry_t)); _new_curry(co, func); return co; } void partial(curry_t *co, int dsz, void *d) { int new_sz; char *new_buf; new_sz = co->cur_sz + dsz; if(new_sz > co->max) { new_buf = realloc(co->buf, ((new_sz + 31) / 32) * 32); if(new_buf == NULL) { ERROR(); } co->buf = new_buf; } memcpy(co->buf + co->cur_sz, d, dsz); co->cur_sz = new_sz; } void *_partial = &partial; #define PARTIAL(co, d) ((void (*)(void *, int, ...))_partial)(co, sizeof(d), d) char *dummy(int a) { return (char *)&a; } int complete(curry_t *co) { char *buf; int r; alloca(co->cur_sz); buf = dummy(0); memcpy(buf, co->buf, co->cur_sz); if(co->cur_sz > 0) { r = (*(int (*)(int))co->func)(*(int *)buf); } else { r = (*(int (*)())co->func)(); } return r; } int foo(int a, int b) { return a + b; } /* ------------------------------------------------------------- */ typedef int (*intf)(int); int obj_diff = 0; int set_diff(void *a) { obj_diff = (int)*(char **)((char *)(&a) - sizeof(void *)); return 0; } int add_part(void *a) { char *buf; curry_t *co; buf = *(char **)((char *)&a - sizeof(void *)) + obj_diff; co = (curry_t *)buf; partial(co, sizeof(int), a); return 0; } int (*partial_worker)(void *) = (int(*)(void *))&set_diff; void *partial_call(int a) { return (void*)partial_worker(&a); } int partial_sz; void partial_init(void) { void *buf; partial_sz = ((char *)partial_init - (char *)partial_call + 3) & ~0x3; buf = malloc(partial_sz + sizeof(curry_t)); memcpy(buf, partial_call, partial_sz); ((void (*)(void))buf)(); obj_diff = (int)buf + partial_sz - obj_diff; partial_worker = add_part; free(buf); } intf new_partial(void *func) { char *buf; buf = malloc(partial_sz + sizeof(curry_t)); _new_curry((curry_t *)(buf + partial_sz), func); memcpy(buf, partial_call, partial_sz); return (intf)buf; } int partial_result(intf f) { curry_t *co; co = (curry_t *)((char *)f + partial_sz); return complete(co); } int main(int argc, const char *argv[]) { int r, a; curry_t *co; intf f; co = new_curry(foo); a = 3; PARTIAL(co, &a); a = 9; PARTIAL(co, &a); r = complete(co); printf("%d\n", r); partial_init(); f = new_partial(foo); f(33); f(21); printf("%d\n", partial_result(f)); return 0; } }}} 看不懂嗎? 所有的解釋都在 linkname:[這裡] http://blog.linux.org.tw/~jserv/archives/002029.html 。抱歉,我是個懶人,還好有 $hyperlink$ 這個東西。 本程只是一個測試,有些 memory 沒釋放,請勿直接 production 使用 :p == 相關 == * linkname:[真 $C$ 之二] http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/327 * linkname:[真 $C$ 之三] http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/328
最後更新時間: 2008-06-19 16:42:43 CST |
引用
查詢:
COMMENTS: