/* lisp.c */ #include #include #include #include "struct.h" #include "lisp.h" #include "san.h" struct exp* mk_exp( char* s ) /* safe */ { char* str; struct exp* ret; str = format_wspace( s ); ret = unsafe_mk_exp( str ); free( str ); return ret; } struct exp* unsafe_mk_exp( char* s ) /* builds a simple exp, unsafe, s must be stripped and legal */ { char* buf; /* temporarily stores each arg */ int pos, fst, skp; struct exp* lst, /* the lst we make */ * tmp, * ret; /* what we actually return, a pointer to the list */ ret = exp_alloc(); lst = exp_alloc(); fst = pos = skp = 0; buf = malloc( sizeof ( char ) * ( max_args( s ) + 1 ) ); for ( ; *s++ != ')'; ) if ( pos && isspace( *s ) ) { buf[pos] = '\0'; pos = 0; if ( !fst ) /* first elem of the lst */ { exp_car_set( B_NODE, lst, 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( lst, tmp ); } } else if ( *s == '(' ) { if ( !fst ) { exp_car_set( L_NODE, lst, unsafe_mk_exp( s ) ); fst = 1; } else exp_add( lst, unsafe_mk_exp( s ) ); for ( skp = 1, s++; skp; s++ ) if ( *s == '(' ) skp++; else if ( *s == ')' ) skp--; } else buf[pos++] = *s; free( buf ); exp_car_set( L_NODE, ret, lst ); return ret; }