[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

any tricks to golf this code further?

luserXtrog

8/4/2011 1:17:00 AM

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;
}