Cã§ç¶ç¶æ¸¡ã(æ«å°¾æé©åãã¼ã¸ã§ã³)
Cã§ç¶ç¶æ¸¡ããæ¸ãã¦ãããããå°ãããã°ãã°æ«å°¾æé©åãã§ãããã ã¨ãããã¨ã«æ°ä»ãã¦ããã£ã¦ã¿ãããªãã¨ãã§ããããããã絶対ã«ã¢ã»ã³ãã©ãå¿ è¦ã ããã¨æã£ã¦ãããã ãã©çµæçã«ã¯ã¢ã»ã³ãã©ã«é ¼ããã«Cã®ç¯å²å ã§å®ç¾ãããã¨ãã§ããããããé«ç´ã¢ã»ã³ãã©ã
- fib2.c
#include <stdio.h> #include <stdlib.h> #include "obj.h" int main(int argc, char *argv[]) { // æ±ç¨ã¬ã¸ã¹ã¿ã®ã¤ãã void *r1; void *r2; closure_t c = newClosure(0); c->func = (func_t) &&fib_cps_0; for (int i = 1; i < 10; i++) { addRef((object_t) c); // printf("Fibonacci(%d) = %d\n", i, fib_cps(i, c)); r1 = (void*) i; r2 = (void*) c; goto fib_cps; fib_cps_0: // int fib_cps_0(int n, closure_t k) { int n = (int) r1; closure_t k = (closure_t) r2; release((object_t) k); printf("Fibonacci(%d) = %d\n", i, n); } } release((object_t) c); return EXIT_SUCCESS; fib_cps: // int fib_cps(int n, closure_t k) { int n = (int) r1; closure_t k = (closure_t) r2; if ((n == 1) || (n == 2)) { r1 = (void*) 1; r2 = (void*) k; goto *(k->func); // return (int) k->func(1, k); } else { closure_t c = newClosure(2); c->func = &&fib_cps_1; c->vars[0] = (void*) k; c->vars[1] = (void*) n; r1 = (void*) (n - 1); r2 = (void*) c; goto fib_cps; // return fib_cps(n - 1, c); } } fib_cps_1: // int fib_cps_1(int v1, closure_t k1) { int v1 = (int) r1; closure_t k1 = (closure_t) r2; int n = (int) k1->vars[1]; closure_t c = newClosure(3); c->func = &&fib_cps_2; c->vars[0] = k1->vars[0]; c->vars[1] = (void*) v1; c->vars[2] = (void*) n; release((object_t) k1); r1 = (void*) (n - 2); r2 = (void*) c; goto fib_cps; // return (int) fib_cps(n - 2, c); } fib_cps_2: // int fib_cps_2(int v2, closure_t k2) { int v2 = (int) r1; closure_t k2 = (closure_t) r2; int v1 = (int) k2->vars[1]; closure_t k = k2->vars[0]; release((object_t) k2); r1 = (void*) (v1 + v2); r2 = (void*) k; goto *(k->func); // return (int) k->func(v1 + v2, k); } }
æåã©ãã«ã®ã¢ãã¬ã¹ãå¾ãæ¹æ³ã¨ããã¤ã³ã¿å¤æ°ã®æãã¢ãã¬ã¹ã«gotoããæ¹æ³ãåãããªãã¦å°ã£ãï¼ãããã&&label, goto *varãªã©ã¨æ¸ãã°ããï¼ã
ãã®ã³ã¼ãã¯å ¨ãå®ç¨çã§ã¯ãªããã©ãæ«å°¾å¼ã³åºããã¸ã£ã³ãã«å¤æããã¨æ¬å½ã«é¢æ°å¼ã³åºããæ¶ããã¨ããå®è¨¼ã«ã¯ãªã£ã¦ããã¨æãããããããã¨ãã³ã³ãã¤ã©ããã£ã¦ãããã¨ãããã°ã©ãã¯å¹çã®å¿é ãããã«ãªãã§ãå帰å¼ã³åºãã«ãã¦ãã¾ããã¨ãã§ããã
以ä¸ã¯28æ¥ã®fib.h, fib.cã®ä¸é¨ãå¥ãã¡ã¤ã«ã¨ãããã®ï¼å 容ã¯ã»ã¨ãã©åãã§ããå¾®å¦ã«ä¿®æ£ãã¦ããã¾ãï¼
- obj.h
#ifndef __OBJ_H__ #define __OBJ_H__ typedef void* (*func_t)(); typedef void (*proc_t)(); typedef struct object { int ref_count; size_t size; proc_t destructor; } *object_t; void addRef(object_t obj); void release(object_t obj); object_t newObject(size_t size, proc_t destructor); void deleteObject(object_t obj); typedef struct closure { // inherited from object_t int ref_count; size_t size; proc_t destructor; // own data func_t func; int var_num; void *vars[0]; } *closure_t; closure_t newClosure(int var_num); #endif /* __OBJ_H__ */
- obj.c
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include "obj.h" void addRef(object_t obj) { obj->ref_count++; } void release(object_t obj) { obj->ref_count--; if (obj->ref_count <= 0) { if (obj->destructor) obj->destructor(obj); deleteObject(obj); } } object_t newObject(size_t size, proc_t destructor) { assert(size >= sizeof(struct object)); object_t obj = malloc(size); #ifdef DEBUG fprintf(stderr, "malloc: %p\n", obj); #endif obj->ref_count = 0; obj->size = size; obj->destructor = destructor; addRef(obj); return obj; } void deleteObject(object_t obj) { #ifdef DEBUG size_t size = obj->size; char *p = (char*) obj; // filled by `de ad be ef' ... pattern for (int i = 0; i < size / 4; i++) { *p++ = '\xde'; *p++ = '\xad'; *p++ = '\xbe'; *p++ = '\xef'; } switch (size % 4) { case 3: p[2] = '\xbe'; case 2: p[1] = '\xad'; case 1: p[0] = '\xde'; } #endif /* DEBUG */ free(obj); #ifdef DEBUG fprintf(stderr, "free: %p\n", obj); #endif } closure_t newClosure(int var_num) { assert(var_num >= 0); size_t size = sizeof(struct closure) + sizeof(void*) * var_num; closure_t c = (closure_t) newObject(size, NULL); c->var_num = var_num; return c; }