Commit e530ad65 authored by dcw's avatar dcw
Browse files

major changes;

in a nice state now..
-- output file is selected and stored globally rather than being
   passed around all the time;
-- implicit NULL tests are now explicit;
-- some details of the generated code are different now.
parent 25d62868
...@@ -3,45 +3,46 @@ ...@@ -3,45 +3,46 @@
#include "decs.h" #include "decs.h"
/*
/^#ifdef HASPROTOS
!/endif$
stat %
*/
#ifdef HASPROTOS #ifdef HASPROTOS
static void init( FILE * , FILE * , char * ); static void line( char * , long , long , long , long );
static void declfields( paramlist );
static void data_decls( declnlist ); static void data_decls( declnlist );
static void one_proto( FILE * , char * , shapelist , BOOL ); static void one_proto( char * , shapelist , BOOL );
static void protos( FILE * , declnlist , BOOL ); static void protos( declnlist , BOOL );
static void cons_fn_hdr( FILE * , char * , shapelist ); static void cons_fn_hdr( char * , shapelist );
static void cons_fn_body( declnlist, char * , shapelist ); static void cons_fn_body( declnlist , char * , shapelist );
static void cons_fns( FILE * , declnlist ); static void cons_fns( declnlist );
static void print_fns( FILE * , declnlist );
static void print_fn_shape( declnlist , shapelist );
static void print_param( char * , paramlist , BOOL ); static void print_param( char * , paramlist , BOOL );
static void print_all_params( declnlist , shapelist ); static void print_all_params( declnlist , shapelist );
static void count_empty_non( shapelist , int *, int * ); static void print_fn_shape( declnlist , shapelist );
static void optimize( declnlist ); static void print_fns( declnlist );
static void line( char *, long, long, long, long ); static void h_declns( char * , char * , declnlist );
static void declfields( paramlist ); static void c_declns( char * , char * , declnlist );
#else #else
static void init(); static void line();
static void declfields();
static void data_decls(); static void data_decls();
static void one_proto(); static void one_proto();
static void protos(); static void protos();
static void cons_fn_hdr(); static void cons_fn_hdr();
static void cons_fn_body(); static void cons_fn_body();
static void cons_fns(); static void cons_fns();
static void print_fns();
static void print_fn_shape();
static void print_param(); static void print_param();
static void print_all_params(); static void print_all_params();
static void count_empty_non(); static void print_fn_shape();
static void optimize(); static void print_fns();
static void line(); static void h_declns();
static void declfields(); static void c_declns();
#endif #endif
BOOL print, verbose, opt; /* print == generate print functions */
/* verbose == be verbose - diagnostics */
/* opt == perform optimizations */
static int numtabs = 0; static int numtabs = 0;
static FILE *outfile; static FILE *outfile;
...@@ -63,28 +64,9 @@ static void line( fmt, a, b, c, d ) char *fmt; long a, b, c, d; ...@@ -63,28 +64,9 @@ static void line( fmt, a, b, c, d ) char *fmt; long a, b, c, d;
} }
static void init( h, c, basename ) FILE *c, *h; char *basename;
{
fputs( "/*\n", h );
fputs( " * Automatically Generated by DataDec\n", h );
fputs( " */\n\n", h );
fputs( "typedef char *string;\n\n", h );
fputs( "typedef char BOOL;\n", h );
fputs( "#define TRUE 1\n", h );
fputs( "#define FALSE 0\n\n", h );
fputs( "#define NEW(t) ((t *)malloc(sizeof(t)))\n\n\n", h );
fputs( "/*\n", c );
fputs( " * Automatically Generated by DataDec\n", c );
fputs( " */\n\n", c);
fputs( "#include <stdio.h>\n", c );
fprintf( c, "#include \"%s.h\"\n\n\n", basename );
}
static void declfields( p ) paramlist p; static void declfields( p ) paramlist p;
{ {
for( ; p; p=p->next ) for( ; p != NULL; p=p->next )
{ {
line( "%s\t%s;", p->type, p->name ); line( "%s\t%s;", p->type, p->name );
} }
...@@ -95,10 +77,9 @@ static void data_decls( decs ) declnlist decs; ...@@ -95,10 +77,9 @@ static void data_decls( decs ) declnlist decs;
{ {
declnlist d; declnlist d;
shapelist s; shapelist s;
paramlist p;
int n; int n;
for( d=decs; d; d=d->next ) for( d=decs; d != NULL; d=d->next )
{ {
if( d->Struct ) if( d->Struct )
{ {
...@@ -110,13 +91,13 @@ static void data_decls( decs ) declnlist decs; ...@@ -110,13 +91,13 @@ static void data_decls( decs ) declnlist decs;
} }
} }
line( "\n" ); line( "\n" );
for( d=decs; d; d=d->next ) for( d=decs; d != NULL; d=d->next )
{ {
line( "/* ---- Type %s ---- */\n", d->name ); line( "/* ---- Type %s ---- */\n", d->name );
n = 0; n = 0;
if( d->Defines ) if( d->Defines )
{ {
for( s = d->shapes; s; s=s->next ) for( s = d->shapes; s != NULL; s=s->next )
{ {
if( d->Struct ) if( d->Struct )
{ {
...@@ -133,7 +114,7 @@ static void data_decls( decs ) declnlist decs; ...@@ -133,7 +114,7 @@ static void data_decls( decs ) declnlist decs;
if( d->Struct ) if( d->Struct )
{ {
line( "struct %s_str {", d->name ); line( "struct %s {", d->name );
indent(); indent();
if( d->TagField ) if( d->TagField )
{ {
...@@ -144,7 +125,7 @@ static void data_decls( decs ) declnlist decs; ...@@ -144,7 +125,7 @@ static void data_decls( decs ) declnlist decs;
line( "union {" ); line( "union {" );
indent(); indent();
} }
for( s = d->shapes; s; s=s->next ) for( s = d->shapes; s != NULL; s=s->next )
{ {
if( d->Union && s->params ) if( d->Union && s->params )
/* need internal structures */ /* need internal structures */
...@@ -171,79 +152,76 @@ static void data_decls( decs ) declnlist decs; ...@@ -171,79 +152,76 @@ static void data_decls( decs ) declnlist decs;
} }
static void one_proto( f, name, s, prot ) FILE *f; char *name; shapelist s; BOOL prot; static void one_proto( name, s, prot ) char *name; shapelist s; BOOL prot;
{ {
paramlist p; paramlist p;
BOOL first; BOOL first;
fprintf( f, "extern %s %s_%s( ", name, name, s->name ); fprintf( outfile, "extern %s %s_%s( ", name, name, s->name );
if( prot ) if( prot )
{ {
if( s->params == NULL ) if( s->params == NULL )
{ {
fputs( "void ", f ); fputs( "void ", outfile );
} else } else
{ {
first = TRUE; first = TRUE;
for( p = s->params; p ; p=p->next, first=FALSE ) for( p = s->params; p != NULL ; p=p->next, first=FALSE )
{ {
if( !first ) fputs( ", ", f ); if( !first ) fputs( ", ", outfile );
fputs( p->type, f ); fputs( p->type, outfile );
fputc( ' ', f ); fputc( ' ', outfile );
} }
} }
} }
fputs( ");\n", f ); fputs( ");\n", outfile );
} }
static void protos( f, d, prot ) FILE *f; declnlist d; BOOL prot; static void protos( d, prot ) declnlist d; BOOL prot;
{ {
shapelist s; shapelist s;
shapelist shapes; shapelist shapes;
for( ; d; d = d->next ) for( ; d != NULL; d = d->next )
{ {
shapes = d->shapes; shapes = d->shapes;
if( d->UseNull ) if( d->UseNull )
{ {
shapes = shapes->next; shapes = shapes->next;
} }
for( s = shapes; s; s = s->next ) for( s = shapes; s != NULL; s = s->next )
{ {
one_proto( f, d->name, s, prot ); one_proto( d->name, s, prot );
} }
if( print ) fprintf( outfile, "extern void print_%s(", d->name );
if( prot )
{ {
fprintf( f, "extern void print_%s(", d->name ); fprintf( outfile, " %s ", d->name );
if( prot )
{
fprintf( f, " %s ", d->name );
}
fputs( ");\n", f );
} }
fputs( ");\n", outfile );
} }
} }
static void cons_fn_hdr( f, name, s ) FILE *f; char *name; shapelist s; static void cons_fn_hdr( name, s ) char *name; shapelist s;
{ {
paramlist p; paramlist p;
BOOL first; BOOL first;
fprintf( f, "%s %s_%s( ", name, name, s->name ); fprintf( outfile, "%s %s_%s( ", name, name, s->name );
first = TRUE; first = TRUE;
for( p=s->params; p; p=p->next, first=FALSE ) for( p=s->params; p != NULL; p=p->next, first=FALSE )
{ {
if( !first ) fputs( ", ", f ); if( !first ) fputs( ", ", outfile );
fputs( p->name, f ); fputs( p->name, outfile );
} }
fputs( " ) ", f ); fputs( " ) ", outfile );
for( p=s->params; p; p=p->next ) for( p=s->params; p != NULL; p=p->next )
{ {
fprintf( f, "%s %s; ", p->type, p->name ); fprintf( outfile, "%s %s; ", p->type, p->name );
} }
fputc( '\n', f ); fputc( '\n', outfile );
} }
...@@ -256,12 +234,12 @@ static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s; ...@@ -256,12 +234,12 @@ static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
line( "{" ); line( "{" );
indent(); indent();
line( "%s\tnew;\n", name ); line( "%s\tnew;\n", name );
line( "new = NEW_(%s);", name ); line( "new = NEW(%s);", name );
if( d->TagField ) if( d->TagField )
{ {
line( "new->tag = %s_%s_tag;", name, s->name ); line( "new->tag = %s_%s_tag;", name, s->name );
} }
for( p=s->params; p; p=p->next ) for( p=s->params; p != NULL; p=p->next )
{ {
if( d->Union ) if( d->Union )
{ {
...@@ -278,14 +256,12 @@ static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s; ...@@ -278,14 +256,12 @@ static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
} }
static void cons_fns( f, d ) FILE *f; declnlist d; static void cons_fns( d ) declnlist d;
{ {
shapelist s; shapelist s;
shapelist shapes; shapelist shapes;
usefile( f ); for( ; d != NULL; d=d->next )
for( ; d; d=d->next )
{ {
if( d->Struct ) if( d->Struct )
{ {
...@@ -296,11 +272,11 @@ static void cons_fns( f, d ) FILE *f; declnlist d; ...@@ -296,11 +272,11 @@ static void cons_fns( f, d ) FILE *f; declnlist d;
/* Null cons func already made */ /* Null cons func already made */
shapes = shapes->next; shapes = shapes->next;
} }
for( s = shapes; s; s=s->next ) for( s = shapes; s != NULL; s=s->next )
{ {
cons_fn_hdr( f, d->name, s ); cons_fn_hdr( d->name, s );
cons_fn_body( d, d->name, s ); cons_fn_body( d, d->name, s );
fprintf( f, "\n\n" ); fprintf( outfile, "\n\n" );
} }
} }
} }
...@@ -351,7 +327,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s; ...@@ -351,7 +327,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s;
{ {
line( "fputc( '(', f );" ); line( "fputc( '(', f );" );
} }
for( p = s->params; p; p = p->next ) for( p = s->params; p != NULL; p = p->next )
{ {
print_param( s->name, p, d->Union ); print_param( s->name, p, d->Union );
} }
...@@ -361,7 +337,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s; ...@@ -361,7 +337,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s;
} }
} else } else
{ {
for( pl = s->pl; pl; pl = pl->next ) for( pl = s->pl; pl != NULL; pl = pl->next )
{ {
if( pl->item->tag == printitem_is_str ) if( pl->item->tag == printitem_is_str )
{ {
...@@ -392,14 +368,12 @@ static void print_fn_shape( d, s ) declnlist d; shapelist s; ...@@ -392,14 +368,12 @@ static void print_fn_shape( d, s ) declnlist d; shapelist s;
} }
static void print_fns( f, d ) FILE *f ; declnlist d; static void print_fns( d ) declnlist d;
{ {
shapelist s; shapelist s;
shapelist shapes; shapelist shapes;
usefile( f ); for( ; d != NULL; d = d->next )
for( ; d; d = d->next )
{ {
shapes = d->shapes; shapes = d->shapes;
line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name ); line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
...@@ -420,7 +394,7 @@ static void print_fns( f, d ) FILE *f ; declnlist d; ...@@ -420,7 +394,7 @@ static void print_fns( f, d ) FILE *f ; declnlist d;
{ {
line( "switch( p->tag )" ); line( "switch( p->tag )" );
line( "{" ); line( "{" );
for( s = shapes; s; s = s->next ) for( s = shapes; s != NULL; s = s->next )
{ {
print_fn_shape( d, s ); print_fn_shape( d, s );
} }
...@@ -439,7 +413,7 @@ static void print_fns( f, d ) FILE *f ; declnlist d; ...@@ -439,7 +413,7 @@ static void print_fns( f, d ) FILE *f ; declnlist d;
{ {
line( "switch( p )" ); line( "switch( p )" );
line( "{" ); line( "{" );
for( s = shapes; s; s = s->next ) for( s = shapes; s != NULL; s = s->next )
{ {
line( "case %s_%s:", d->name, s->name ); line( "case %s_%s:", d->name, s->name );
indent(); indent();
...@@ -455,121 +429,41 @@ static void print_fns( f, d ) FILE *f ; declnlist d; ...@@ -455,121 +429,41 @@ static void print_fns( f, d ) FILE *f ; declnlist d;
} }
static void count_empty_non( s, e, ne ) shapelist s; int *e, *ne; void make_declns( exports, globals, d, basename ) declnlist d; char *exports, *globals, *basename;
{ {
*e = *ne = 0; printf( "datadec: Making data declarations in %s.[ch]\n", basename );
for( ; s!=NULL; s = s->next ) h_declns( basename, exports, d );
{ c_declns( basename, globals, d );
if( s->params == NULL ) (*e)++; else (*ne)++;
}
}
#define implies( a, b ) (!(a) || (b))
static void optimize( d ) declnlist d;
{
int t, e, ne;
for( ; d != NULL; d = d->next )
{
if( ! opt )
{
d->Defines = d->TagField = d->Struct = d->Union = TRUE;
d->UseNull = FALSE;
} else
{
count_empty_non( d->shapes, &e, &ne );
t = e+ne;
d->Defines = d->TagField = d->Struct =
d->Union = d->UseNull = FALSE;
/* ONE, EMPTY, eg. 'data x = y' => ERROR */
ASSERT( t!=1 || e!=1,
( "datadec: type %s is empty!\n",d->name) );
if( t==1 && ne==1 )
/* ONE, NON EMPTY, eg. 'data x = fred(string z)' */
{
d->Struct = TRUE;
/* !Defines, !TagField, !Union, !UseNull */
} else if( t>1 && ne==0 )
/* >1, ALL EMPTY, eg. 'data x = a | b | c | d | e' */
{
d->Defines = TRUE;
/* !TagField, !Struct, !Union, !UseNull */
} else if( d->shapes->params == NULL ) /* 1st empty */
{
d->UseNull = d->Struct = TRUE;
if( t==2 && ne==1 )
{
/* TWO, 1ST EMPTY, 2ND NE, eg. 'data x = a | b(char z)' */
d->UseNull = d->Struct = TRUE;
/* !Union, !TagField, !Defines */
} else if( t>2 && ne==1 )
{
/* >TWO, 1ST EMPTY, ONLY ONE NE, eg. 'data x = a | b | c(char z) | d | e' */
d->UseNull = d->Struct =
d->Defines = d->TagField = TRUE;
/* !Union */
} else
{
/* >TWO, 1ST EMPTY, >ONE NE, eg. 'data x = a | b(int y) | c(char z) | d | e' */
d->UseNull = d->Struct =
d->Defines = d->TagField =
d->Union = TRUE;
}
} else
/* ELSE */
{
d->Defines = d->TagField = d->Struct =
d->Union = TRUE;
}
if( verbose )
{
#define XXX(x) ( (x)?' ':'!')
printf( "type %s: %cDefines, %cTagField, ",
d->name, XXX(d->Defines),
XXX(d->TagField) );
printf( "%cStruct, %cUnion, %cUseNull\n",
XXX(d->Struct), XXX(d->Union),
XXX(d->UseNull) );
#undef XXX
}
ASSERT( implies(d->Union,d->TagField),
("optimizer error: type %s has Union&!TagField\n",d->name) );
ASSERT( implies(d->Union,d->Struct),
("optimizer error: type %s has Union&!Struct\n",d->name) );
ASSERT( implies(d->TagField,d->Struct),
("optimizer error: type %s has TagField&!Struct\n",d->name) );
ASSERT( implies(d->UseNull,d->Struct),
("optimizer error: type %s has UseNull&!Struct\n",d->name) );
ASSERT( implies(d->TagField,d->Defines),
("optimizer error: type %s has TagField&!Defines\n",d->name) );
}
}
} }
void make_declns( d, c, h, basename ) declnlist d; FILE *c, *h; char *basename; static void h_declns( basename, exports, d ) char *basename, *exports; declnlist d;
{ {
declnlist dl; char tempname[256];
FILE *hfile;
declnlist dl;
printf( "datadec: Making data declarations\n" ); sprintf( tempname, "%s.h", basename );
hfile = fopen( tempname, "w" );
ASSERT( hfile != NULL, ("datadec: can't create '%s'\n",tempname) );
init( h, c, basename ); usefile( hfile );
optimize( d ); line( "/*" );
line( " * Automatically Generated by DataDec" );
line( " */\n" );
line( "typedef char *string;\n" );
line( "typedef char BOOL;" );
line( "#define TRUE 1" );
line( "#define FALSE 0\n" );
line( "#define NEW(t) ((t)malloc(sizeof(t)))\n\n" );
usefile( h ); line( exports );
data_decls( d ); data_decls( d );
for( dl = d; dl; dl=dl->next ) for( dl = d; dl != NULL; dl=dl->next )
{ {
if( dl->UseNull ) if( dl->UseNull )
{