Cã§ç¶ç¶æ¸¡ã
ã§ããã試è¡é¯èª¤ãã¦ããå ã«ç¡é§ã«åã£ãä½ãã«ãªã£ã¦ãã¾ã£ããããã¾ã§æ¥ãã¨å®å ¨ã«æ段ãç®çã¨åãã¦ãããªã
- fib.h:
#ifndef __FIB_H__ #define __FIB_H__ typedef void (*destructor_t)(); typedef struct object { int ref_count; size_t size; destructor_t destructor; } *object_t; void addRef(object_t obj); void release(object_t obj); object_t newObject(size_t size, destructor_t destructor); void deleteObject(object_t obj); typedef void* (*func_t)(); typedef struct closure { // inherited from object_t int ref_count; size_t size; destructor_t destructor; // own data func_t func; int var_num; void *vars[0]; } *closure_t; closure_t newClosure(); #endif /* __FIB_H__ */
- fib.c:
#include <stdio.h> #include <stdlib.h> #include "fib.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, destructor_t destructor) { 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) { 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; } int fib_cps(int n, closure_t k); static int fib_cps_2(int v2, closure_t k2) { int v1 = (int) k2->vars[1]; closure_t k = k2->vars[0]; release((object_t) k2); return (int) k->func(v1 + v2, k); } static int fib_cps_1(int v1, closure_t k1) { int n = (int) k1->vars[1]; closure_t c = newClosure(3); c->func = (func_t) fib_cps_2; c->vars[0] = k1->vars[0]; c->vars[1] = (void*) v1; c->vars[2] = (void*) n; release((object_t) k1); return (int) fib_cps(n - 2, c); } int fib_cps(int n, closure_t k) { if ((n == 1) || (n == 2)) { return (int) k->func(1, k); } else { closure_t c = newClosure(2); c->func = (func_t) fib_cps_1; c->vars[0] = (void*) k; c->vars[1] = (void*) n; return fib_cps(n - 1, c); } } static int fib_cps_0(int n, closure_t k) { release((object_t) k); return n; } int main(int argc, char *argv[]) { 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)); } release((object_t) c); return EXIT_SUCCESS; }
è¦ã¦åããéããåç §ã«ã¦ã³ã¿ã使ã£ã¦èªåã§ãªãã¸ã§ã¯ãã®å¯¿å½ã管çãã¦ãããã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ããªãè¨èªã§ã¯ãã¼ã¸ã£ã使ãã®ãããã«å¤§å¤ãã¨ãããã¨ãããåãã£ãã
ãªããC99ã§æ¡å¼µãããæ©è½ã使ã£ã¦ããã®ã§ãgccã§ã³ã³ãã¤ã«ããå ´åã¯
% gcc -Wall -std=c99 -DDEBUG fib.c
ã®ããã«-std=c99ãä»ãã¦ã³ã³ãã¤ã«ãã¦ä¸ããã