Newer
Older
#include <dcw.h>
#include "struct.h"
#include "decs.h"
#ifdef HASPROTOS
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( char * , shapelist );
static void cons_fns( FILE * , declnlist );
static void print_fns( FILE * , declnlist );
static void print_fn_shape( char * , shapelist );
static void print_param( char * , char * , char * );
static void count_empty_non( shapelist , int *, int * );
static void optimize( declnlist );
static void line( char *, long, long, long, long );
static void init();
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 count_empty_non();
static void optimize();
static void line();
BOOL print, verbose; /* print == generate print functions */
/* verbose == be verbose - diagnostics */
static int numtabs = 0;
static FILE *outfile;
#define indent() numtabs++
#define outdent() numtabs--
#define usefile(f) outfile = f, numtabs = 0
/*VARARGS*/
static void line( fmt, a, b, c, d ) char *fmt; long a, b, c, d;
{
int i;
for( i=numtabs; i; i-- ) fputc( '\t', outfile );
fprintf( outfile, fmt, a, b, c, d );
fputc( '\n', outfile );
}
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 );
static void data_decls( decs ) declnlist decs;
declnlist d;
shapelist s;
paramlist p;
int n;
for( d=decs; d; d=d->next )
line( "typedef struct %s_str *%s;", d->name, d->name );
line( "\n" );
for( d=decs; d; d=d->next )
line( "/* ---- Type %s ---- */\n", d->name );
line( "#define %s_%s_tag %d",
d->name, s->name, n++ );
line( "struct %s_str {", d->name );
indent();
line( "int\ttag;" );
line( "union {" );
indent();
line( "} %s;", s->name );
outdent();
line( "} u;" );
outdent();
line( "};\n" );
static void one_proto( f, name, s, prot ) FILE *f; char *name; shapelist s; BOOL prot;
fprintf( f, "extern %s %s_%s( ", name, name, s->name );
if( prot )
for( p = s->params; p ; p=p->next, first=FALSE )
{
if( !first ) fputs( ", ", f );
fputs( p->type, f );
fputc( ' ', f );
static void protos( f, d, prot ) FILE *f; declnlist d; BOOL prot;
for( s = d->shapes; s; s = s->next )
one_proto( f, d->name, s, prot );
}
if( print )
{
if( prot )
{
fprintf( f, "extern void print_%s( %s );\n",
d->name, d->name );
} else
{
fprintf( f, "extern void print_%s( );\n",
d->name );
}
static void cons_fn_hdr( f, name, s ) FILE *f; char *name; shapelist s;
fprintf( f, "%s %s_%s( ", name, name, s->name );
for( p=s->params; p; p=p->next, first=FALSE )
{
if( !first ) fputs( ", ", f );
fputs( p->name, f );
for( p=s->params; p; p=p->next )
{
fprintf( f, "%s %s; ", p->type, p->name );
static void cons_fn_body( name, s ) char *name; shapelist s;
line( "{" );
indent();
line( "%s new;\n", name );
line( "new = NEW( struct %s_str );", name );
line( "new->tag = %s_%s_tag;", name, s->name );
line( "new->u.%s.%s = %s;", s->name, p->name, p->name );
line( "return new;" );
outdent();
line( "}" );
static void cons_fns( f, d ) FILE *f; declnlist d;
for( ; d; d=d->next )
{
for( s = d->shapes; s; s=s->next )
{
cons_fn_hdr( f, d->name, s );
cons_fn_body( d->name, s );
static void print_param( shape, ftype, fname ) char *shape, *ftype, *fname;
line( "fprintf( f, \"%%d\", %s );", pname );
line( "fputc( %s, f );", pname );
line( "fputs( %s?\"true\":\"false\", f );", pname );
line( "fputs( %s, f );", pname );
line( "print_%s( f, %s );", ftype, pname );
static void print_fn_shape( typename, s ) char *typename; shapelist s;
printlist pl;
paramlist p;
int n;
line( "case %s_%s_tag:", typename, s->name );
line( "fputs( \"%s\", f );", s->name );
if( s->params )
{
line( "fputc( '(', f );" );
}
print_param( s->name, p->type, p->name );
}
if( s->params )
{
line( "fputc( ')', f );" );
}
} else
{
for( pl = s->pl; pl; pl = pl->next )
{
if( pl->item->tag == printitem_is_str )
{
line( "fputs( \"%s\", f );",
pl->item->str );
} else
{
n = pl->item->num;
for( p = s->params; --n; p = p->next )
{
ASSERT( p != NULL,
("datadec: bad printitem in shape %s of type %s\n",s->name,typename));
print_param( s->name, p->type, p->name );
}
static void print_fns( f, d ) FILE *f ; declnlist d;
{
shapelist s;
line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
line( "{" );
indent();
line( "switch( p->tag )" );
line( "{" );
line( "default:" );
indent();
line( "fprintf( stderr," );
line( " \"print_%s: impossible tag %%d\\n\", p->tag );",
d->name );
line( "exit(1);" );
outdent();
line( "}" );
outdent();
line( "}\n" );
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
static void count_empty_non( s, e, ne ) shapelist s; int *e, *ne;
{
*e = *ne = 0;
for( ; s!=NULL; s = s->next )
{
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 )
{
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 is 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
}
("optimizer error: type %s has Union&!TagField\n",d->name) );
("optimizer error: type %s has Union&!Struct\n",d->name) );
("optimizer error: type %s has TagField&!Struct\n",d->name) );
("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;
{
printf( "datadec: Making data declarations\n" );
usefile( h );
data_decls( d );
line( "#ifdef HASPROTOS" );
if( print ) print_fns( c, d );