/* lisp.c */ #include #include #include #include "struct.h" #include "lisp.h" struct exp* mk_exp( char* s ) /* makes *any* expression */ { struct exp* ret, * pret, * tmp; char* buf; int simp, c, fst; simp = issimp( s ); c = fst = 0; pret = exp_alloc(); buf = malloc( sizeof ( char ) * ( max_args( s ) + 1 ) ); if ( !simp ) return mk_simp_exp( s ); else { for( ; isspace( *s ); s++ ); for ( ; *s++; ) { if ( *s == '(' ) { if ( !fst ) { ret = mk_exp( s ); fst = 1; } else exp_add( ret, mk_exp( s ) ); for ( ; *s++ != ')'; ); s++; } else if ( isspace( *s ) && c || *s == ')' ) { buf[c] = '\0'; c = 0; if ( !fst ) { ret = exp_alloc(); exp_car_set( B_NODE, ret, strcpy( malloc( sizeof ( char ) * ( strlen( buf ) + 1 ) ), buf ) ); fst = 1; } else { tmp = exp_alloc(); exp_car_set( B_NODE, tmp, strcpy( malloc( sizeof ( char ) * ( strlen( buf ) + 1 ) ), buf ) ); exp_add( ret, tmp ); } if ( *s == ')' ) break; } else buf[c++] = *s; } } exp_car_set( L_NODE, pret, ret ); free( buf ); return pret; } struct exp* mk_simp_exp( char* s ) /* unsafe */ { char* buf; /* temporarily holds individual args */ int c, fst; struct exp* ret, * pret, * tmp; pret = exp_alloc(); buf = malloc( sizeof ( char ) * ( max_args( s ) + 1 ) ); for( ; isspace( *s ); s++ ); for( c = fst = 0; *s++; ) if ( isspace( *s ) && c || *s == ')' ) { buf[c] = '\0'; c = 0; if ( !fst ) { ret = exp_alloc(); exp_car_set( B_NODE, ret, strcpy( malloc( sizeof ( char ) * ( strlen( buf ) + 1 ) ), buf ) ); fst = 1; } else { tmp = exp_alloc(); exp_car_set( B_NODE, tmp, strcpy( malloc( sizeof ( char ) * ( strlen( buf ) + 1 ) ), buf ) ); exp_add( ret, tmp ); } if ( *s == ')' ) /* inelegant piece of crap */ break; } else buf[c++] = *s; exp_car_set( L_NODE, pret, ret ); free( buf ); return pret; } int max_args( char* s ) /* returns the longest argument length */ { int c, d; c = d = 0; for( ; isspace( *s ); s++ ); for ( ; *s++; ) if ( *s == '(' ) for ( ; *s++ != ')'; ); /* we just skip it */ else if ( isspace( *s ) || *s == ')' ) { c = c > d ? c : d; d = 0; } else d++; return c; } int issimp( char* s ) /* checks if a list only consists of atoms */ { int n; n = 0; for ( ; *s != ')'; s++ ) if ( *s == '(' ) n++; return n - 1; }