Created
September 14, 2011 02:16
-
-
Save jgreco/1215709 to your computer and use it in GitHub Desktop.
TCO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "tco.h" | |
#include <stdlib.h> | |
#include <stdarg.h> | |
conscell cons_f(void *car, void *cdr) | |
{ | |
conscell ret = malloc(sizeof(struct conscell_str)); | |
ret->car = car; | |
ret->cdr = cdr; | |
return ret; | |
} | |
#define MAXARGS 31 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef TCO_H_ | |
#define TCO_H_ | |
#include "stdarg.h" | |
void (*nextfun)(void *); | |
void *nextarg; | |
#define CALL(fun, arg) \ | |
do { \ | |
nextfun = fun; \ | |
nextarg = arg; \ | |
while(nextfun) \ | |
nextfun(nextarg); \ | |
} while(0); | |
#define CALL2(fun, arg) \ | |
do { \ | |
nextfun = fun; \ | |
nextarg = arg; \ | |
return; \ | |
} while(0); | |
#define RETURN CALL2(NULL, NULL) | |
typedef struct conscell_str { | |
void *car; | |
void *cdr; | |
} *conscell; | |
#define cons(x, y) cons_f((void *)x, (void *)y) | |
conscell cons_f(void *car, void *cdr); | |
#define car(x) ((conscell)x)->car | |
#define cdr(x) ((conscell)x)->cdr | |
#define integer(x) (uint64_t)(x) | |
/*conscell list(...); */ | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdint.h> | |
#include "tco.h" | |
void print_sums(void *); | |
int main() | |
{ | |
uint64_t i; /* 64 bit machine */ | |
conscell c = NULL; | |
for(i=50; i>0; i--) | |
c = cons(i,c); | |
CALL(print_sums, c); | |
return 0; | |
} | |
/* recursive (tail call optimized) */ | |
void print_sums(void * n) | |
{ | |
conscell c = (conscell)n; | |
printf("count: %ld\n", integer(car(c))); | |
if(cdr(c) && cdr(cdr(c))) | |
CALL2(print_sums, | |
cons( | |
integer(car(c)) + integer(car(cdr(c))), | |
cdr(cdr(c)))); | |
RETURN; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment