robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 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: