Commit e530ad65 authored by dcw's avatar dcw

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 @@
#include "decs.h"
/*
/^#ifdef HASPROTOS
!/endif$
stat %
*/
#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 one_proto( FILE * , char * , shapelist , BOOL );
static void protos( FILE * , declnlist , BOOL );
static void cons_fn_hdr( FILE * , char * , shapelist );
static void cons_fn_body( declnlist, char * , shapelist );
static void cons_fns( FILE * , declnlist );
static void print_fns( FILE * , declnlist );
static void print_fn_shape( declnlist , shapelist );
static void one_proto( char * , shapelist , BOOL );
static void protos( declnlist , BOOL );
static void cons_fn_hdr( char * , shapelist );
static void cons_fn_body( declnlist , char * , shapelist );
static void cons_fns( declnlist );
static void print_param( char * , paramlist , BOOL );
static void print_all_params( declnlist , shapelist );
static void count_empty_non( shapelist , int *, int * );
static void optimize( declnlist );
static void line( char *, long, long, long, long );
static void declfields( paramlist );
static void print_fn_shape( declnlist , shapelist );
static void print_fns( declnlist );
static void h_declns( char * , char * , declnlist );
static void c_declns( char * , char * , declnlist );
#else
static void init();
static void line();
static void declfields();
static void data_decls();
static void one_proto();
static void protos();
static void cons_fn_hdr();
static void cons_fn_body();
static void cons_fns();
static void print_fns();
static void print_fn_shape();
static void print_param();
static void print_all_params();
static void count_empty_non();
static void optimize();
static void line();
static void declfields();
static void print_fn_shape();
static void print_fns();
static void h_declns();
static void c_declns();
#endif
BOOL print, verbose, opt; /* print == generate print functions */
/* verbose == be verbose - diagnostics */
/* opt == perform optimizations */
static int numtabs = 0;
static FILE *outfile;
......@@ -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;
{
for( ; p; p=p->next )
for( ; p != NULL; p=p->next )
{
line( "%s\t%s;", p->type, p->name );
}
......@@ -95,10 +77,9 @@ static void data_decls( decs ) declnlist decs;
{
declnlist d;
shapelist s;
paramlist p;
int n;
for( d=decs; d; d=d->next )
for( d=decs; d != NULL; d=d->next )
{
if( d->Struct )
{
......@@ -110,13 +91,13 @@ static void data_decls( decs ) declnlist decs;
}
}
line( "\n" );
for( d=decs; d; d=d->next )
for( d=decs; d != NULL; d=d->next )
{
line( "/* ---- Type %s ---- */\n", d->name );
n = 0;
if( d->Defines )
{
for( s = d->shapes; s; s=s->next )
for( s = d->shapes; s != NULL; s=s->next )
{
if( d->Struct )
{
......@@ -133,7 +114,7 @@ static void data_decls( decs ) declnlist decs;
if( d->Struct )
{
line( "struct %s_str {", d->name );
line( "struct %s {", d->name );
indent();
if( d->TagField )
{
......@@ -144,7 +125,7 @@ static void data_decls( decs ) declnlist decs;
line( "union {" );
indent();
}
for( s = d->shapes; s; s=s->next )
for( s = d->shapes; s != NULL; s=s->next )
{
if( d->Union && s->params )
/* need internal structures */
......@@ -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;
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( s->params == NULL )
{
fputs( "void ", f );
fputs( "void ", outfile );
} else
{
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 );
fputs( p->type, f );
fputc( ' ', f );
if( !first ) fputs( ", ", outfile );
fputs( p->type, outfile );
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 shapes;
for( ; d; d = d->next )
for( ; d != NULL; d = d->next )
{
shapes = d->shapes;
if( d->UseNull )
{
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 );
if( prot )
{
fprintf( f, " %s ", d->name );
}
fputs( ");\n", f );
fprintf( outfile, " %s ", d->name );
}
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;
BOOL first;
fprintf( f, "%s %s_%s( ", name, name, s->name );
fprintf( outfile, "%s %s_%s( ", name, name, s->name );
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 );
fputs( p->name, f );
if( !first ) fputs( ", ", outfile );
fputs( p->name, outfile );
}
fputs( " ) ", f );
for( p=s->params; p; p=p->next )
fputs( " ) ", outfile );
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;
line( "{" );
indent();
line( "%s\tnew;\n", name );
line( "new = NEW_(%s);", name );
line( "new = NEW(%s);", name );
if( d->TagField )
{
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 )
{
......@@ -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 shapes;
usefile( f );
for( ; d; d=d->next )
for( ; d != NULL; d=d->next )
{
if( d->Struct )
{
......@@ -296,11 +272,11 @@ static void cons_fns( f, d ) FILE *f; declnlist d;
/* Null cons func already made */
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 );
fprintf( f, "\n\n" );
fprintf( outfile, "\n\n" );
}
}
}
......@@ -351,7 +327,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s;
{
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 );
}
......@@ -361,7 +337,7 @@ static void print_all_params( d, s ) declnlist d; shapelist s;
}
} 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 )
{
......@@ -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 shapes;
usefile( f );
for( ; d; d = d->next )
for( ; d != NULL; d = d->next )
{
shapes = d->shapes;
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;
{
line( "switch( p->tag )" );
line( "{" );
for( s = shapes; s; s = s->next )
for( s = shapes; s != NULL; s = s->next )
{
print_fn_shape( d, s );
}
......@@ -439,7 +413,7 @@ static void print_fns( f, d ) FILE *f ; declnlist d;
{
line( "switch( p )" );
line( "{" );
for( s = shapes; s; s = s->next )
for( s = shapes; s != NULL; s = s->next )
{
line( "case %s_%s:", d->name, s->name );
indent();
......@@ -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;
for( ; s!=NULL; s = s->next )
{
if( s->params == NULL ) (*e)++; else (*ne)++;
}
}
#define implies( a, b ) (!(a) || (b))
printf( "datadec: Making data declarations in %s.[ch]\n", basename );
h_declns( basename, exports, d );
c_declns( basename, globals, d );
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 );
for( dl = d; dl; dl=dl->next )
for( dl = d; dl != NULL; dl=dl->next )
{
if( dl->UseNull )
{
......@@ -578,11 +472,37 @@ void make_declns( d, c, h, basename ) declnlist d; FILE *c, *h; char *basename;
}
}
line( "#ifdef HASPROTOS" );
protos( h, d, TRUE );
protos( d, TRUE );
line( "#else" );
protos( h, d, FALSE );
protos( d, FALSE );
line( "#endif" );
cons_fns( c, d );
if( print ) print_fns( c, d );
fclose( hfile );
}
static void c_declns( basename, globals, d ) char *basename, *globals; declnlist d;
{
char tempname[256];
FILE *cfile;
sprintf( tempname, "%s.c", basename );
cfile = fopen( tempname, "w" );
ASSERT( cfile != NULL, ("datadec: can't create '%s'\n",tempname) );
usefile( cfile );
line( "/*" );
line( " * Automatically Generated by DataDec" );
line( " */\n" );
line( "#include <stdio.h>" );
line( "#include \"%s.h\"\n\n", basename );
line( globals );
cons_fns( d );
print_fns( d );
fclose( cfile );
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment