Skip to content

Instantly share code, notes, and snippets.

@jgreco
Created September 14, 2011 02:16
Show Gist options
  • Save jgreco/1215709 to your computer and use it in GitHub Desktop.
Save jgreco/1215709 to your computer and use it in GitHub Desktop.
TCO
#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
#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
#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