any tricks to golf this code further?

L

luser- -droog

This should be usefull to anyone attempting to read the previous post:
a lambda calculus interpreter using cursors. This is the pointer
version I used as reference in writing the cursor version. It shows
some experiments in replacing statements with expressions (and
sometimes the other way, to debug it), and replacing functions with
macros (although implicit int allows functions to be still shorter).

Apologies for bad line breaks, but this is for reading, not running.

#include<stdio.h>
#include<string.h>
#include<unistd.h>
char*new,*br,*v="abcdefghijklmnopqrstuvwxyz";
char* atom(char*x) {return ( (x)? (strchr(v,*x)? (strchr(v,*x)): 0):
0);
}
char* eq(char*x,char*y) {return ( ((x)&&(y)&&(atom(x)==atom(y)))?
atom(x): 0);
}

char*cell(char*x,int d){
char*t=new;
if(!x||!*x/*||*x==')'*/)return 0;
if(*x==' ')++x;
if(!d&&atom(x)){ *new++=*x; *new++='\0'; return new-2; }
if(!d&&*x=='\\'){ memcpy(new,x,4); new[4]='\0'; new+=5; return
t; }
do{d=*x?(*x=='('?d+1:(*x==')'?d-1:d)):0;*new++=*x++;}while(d);
//do{ switch(*x){ case 0:d=0;break; case'(':d++;break;
case')':d--;break; } *new++=*x++; }while(d>0);
*new++='\0';
return t;
}

//char* car(char*x) {return (x? cell((x)+1,0): 0); }
#define car(X) (X?cell(X+1,0):0)
//char* cdr(char*x) {return (car(x)? cell((x)+(strlen(car(x))+1),0):
0); }
#define cdr(X) (car(X)?cell((X)+(strlen(car(X))+1),0):0)

char*cons(char*x,char*y){
char*t=new;
if(!x)return 0;
sprintf(new,y?"(%s %s)":"(%s)",x,y);
//if(y) sprintf(new,"(%s %s)",x,y); else sprintf(new,"(%s)",x);
new+=strlen(new)+1;
return t;
}

char*subst(char*x,char*y,char*z){
if(!x||!y||!z)return 0;
//printf("subst %s %s %s\n", x, y, z);
if(atom(z))
if(eq(z,y)) return x;
else return z;
else
if(cdr(z))
if(z[1]=='\\') return cons(car(z), subst(x,y,cdr(z)));
else return cons(subst(x,y,car(z)), subst(x,y,cdr(z)));
else
return cons(subst(x,y,car(z)), 0);
//return (atom(z)) ? (eq(z,y)?x:z) :
cons(subst(x,y,car(z)),cdr(z)? subst(x,y,cdr(z)): 0);
}

char*eval(char*e){
char*a,*r;
if(atom(e)) {r=e;goto ret;}
if(atom(a=car(e))) {r=e;goto ret;}
if(*a=='\\'){
r=cons(a,eval(cdr(e)));
//r=cons(car(a),eval(cdr(a)));
goto ret; }
if(*car(a)=='\\'){
char*p=new; //snag param
*new++=car(a)[2];
*new++='\0';
r=eval(subst(eval(cdr(e)),p,cdr(a)));
goto ret;
}
r=eval(cons(eval(a), cdr(e)?eval(cdr(e)):0));
ret:
//printf(":eval %s= %s\n", e, r?r:"null");
return r;
}

void try(char*s){
printf("try %s:\n", s);
#if 0
printf("atom %s= %s\n", s, atom(s));
printf("cell0 %s= %s\n", s, cell(s,0));
printf("cell1 %s= %s\n", s, cell(s,1));
++s;
printf("cell0 %s= %s\n", s, cell(s,0));
printf("cell1 %s= %s\n", s, cell(s,1));
--s;
printf("car %s= %s\n", s, car(s));
printf("cdr %s= %s\n", s, cdr(s));
printf("cons car cdr= %s\n", cons(car(s),cdr(s)));
printf("subst x a %s= %s\n", s, subst("x","a",s));
printf("subst x b %s= %s\n", s, subst("x","b",s));
#endif
printf("eval => %s\n", eval(s));
new=br;
}

char*in[]={
//"a","a","b","b",
"((\\ a. a) (b))", "(b)",
"((\\ x. x) (\\ y. (\\ z. z)))", "(\\ y. (\\ z. z))",
"(\\ x. ((\\ y. y) x))", "(\\ x. x)",
"(((\\ x. (\\ y. x)) (\\ a. a)) (\\ b. b))", "(\\ a. a)",
"((\\ x. (\\ y. y)) (\\ a. a))", "(\\ y. y)",
"(((\\ x. (\\ y. y)) (\\ a. a)) (\\ b. b))", "(\\ b. b)",
"((\\x. (x x)) (\\x. (x x)))", "undef",
NULL};

int main(){
new=br=sbrk(getpagesize()); //one page scratch space
char**t;
for(t=in;*t;t+=2){
try(*t);
printf("s.b. => %s\n",t[1]);
puts("");
}
#if 0
try("a");
try("(a)");
try("(a b)");
try("(a (b))");
#endif
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top