rendered paste body/* lisp.c */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}