I'm having difficulty with the termination indicator for
6bit encoded characters packed into longs, as described in
the McCarthy paper. I'm trying to use -1U for all bits set,
but I'm missing something somewhere.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }
union word {
long i;
struct sexpr *link;
};
struct sexpr {
bool atom;
union word car;
struct { struct sexpr *link; } cdr;
};
bool atom(struct sexpr *sp) { return (sp && sp->atom); }
char *charset = "0123456789"
"abcdefghijklmnopqrstuvwxyz" ;
struct sexpr *assc(char *pnom) {
struct sexpr *ascl, *asct;
char *code, *cp = pnom;
int c=24;
for ( ((ascl=malloc(sizeof*ascl)) || error("poof!")), asct=ascl,
asct->car.i=-1U;
*cp && (code=strchr(charset, *cp));
cp++, c-=6 )
{
if ( (cp-pnom) && !((cp-pnom)%5) ) { //5 6bit codes fit in
32bits
(asct->cdr.link=malloc(sizeof*asct)) || error("poof!");
asct=asct->cdr.link;
asct->car.i=0;
}
asct->car.i&= (code-charset)<<c;;
}
asct->cdr.link=NULL;
return ascl;
}
char *pname(struct sexpr *ascl) {
struct sexpr *asct=ascl;
char *pnom, *cp;
size_t sz;
((pnom=malloc(sz=6)) || error("poof"));
cp=pnom;
while (asct) {
for ( int i=0, c=24;
i<5;
i++, c-=6, cp++ )
{
int in;
in= (asct->car.i>>c)%64
if(in==-1U) *cp=0, goto ret;
*cp= charset[ in ];
}
((pnom=realloc(pnom,sz+=5)) || error("poof"));
asct=asct->cdr.link;
}
ret:return pnom;
}
bool print(FILE *f, struct sexpr *sp) {
if (sp) {
if (sp->atom) {
fprintf(f, "%d %s\n", sp->car.i, pname(sp->cdr.link));
} else {
print(f,sp->car.link);
print(f,sp->cdr.link);
}
return true;
} else return false;
}
struct sexpr *globl;
bool init() {
struct sexpr *lp, *h;
(lp=malloc(sizeof*lp)) || error("poof!");
h=lp;
for(int *i = (int[]){ 42, 69, 613, 0 }; *i; i++) {
struct sexpr *neu;
lp->atom = false;
(neu=malloc(sizeof*neu)) || error("poof!");
neu->atom = true;
neu->car.i = *i;
neu->cdr.link = assc("foo");
lp->car.link = neu;
(lp->cdr.link=malloc(sizeof*lp)) || error("poof!");
lp = lp->cdr.link;
}
free(lp);
lp=NULL;
globl=h;
return true;
}
bool run() {
//while (print(stdout,eval(read(stdin)))) ;
print(stdout,globl);
return true;
}
int main() {
return init()&&run()?0:EXIT_FAILURE;
}
/*eof*/