Commit a737e595 authored by dcw's avatar dcw
Browse files

major change: added deconstructors, (enum kind, kind fn, decons fns)

parent 91a72528
......@@ -15,12 +15,20 @@ static void line( char * , long , long , long , long );
static void h_declns( char * , char * , declnlist );
static void c_declns( char * , char * , declnlist );
static void data_decls( declnlist );
static void declare_type( decln );
static void declfields( paramlist );
static void protos( declnlist , BOOL );
static void one_proto( char * , shapelist , BOOL );
static void proto_type( decln , BOOL );
static void cons_fns( declnlist );
static void cons_fn_hdr( char * , shapelist );
static void cons_fn_body( declnlist , char * , shapelist );
static void cons_fn_proto( decln , shapelist , BOOL );
static void cons_fn( decln , shapelist );
static void decons_fns( declnlist );
static void decons_fns_type( decln );
static void deconskind_proto( decln , BOOL );
static void deconskind_fn( decln );
static void decons_fn_proto( decln , shapelist , BOOL );
static void decons_fn( decln , char * , shapelist );
static void print_fn_proto( char * , BOOL );
static void print_fns( declnlist );
static void print_fn_shape( declnlist , shapelist );
static void print_all_params( declnlist , shapelist );
......@@ -30,12 +38,20 @@ static void line();
static void h_declns();
static void c_declns();
static void data_decls();
static void declare_type();
static void declfields();
static void protos();
static void one_proto();
static void proto_type();
static void cons_fns();
static void cons_fn_hdr();
static void cons_fn_body();
static void cons_fn_proto();
static void cons_fn();
static void decons_fns();
static void decons_fns_type();
static void deconskind_proto();
static void deconskind_fn();
static void decons_fn_proto();
static void decons_fn();
static void print_fn_proto();
static void print_fns();
static void print_fn_shape();
static void print_all_params();
......@@ -72,7 +88,6 @@ void make_declns( exports, globals, d, basename ) declnlist d; char *exports, *g
printf( "datadec: Making data declarations in %s.[ch]\n", basename );
h_declns( basename, exports, d );
c_declns( basename, globals, d );
}
......@@ -81,7 +96,6 @@ static void h_declns( basename, exports, d ) char *basename, *exports; declnlist
char tempname[256];
char *exportptr;
FILE *hfile;
declnlist dl;
sprintf( tempname, "%s.h", basename );
hfile = fopen( tempname, "w" );
......@@ -100,8 +114,6 @@ static void h_declns( basename, exports, d ) char *basename, *exports; declnlist
if( *exports != '\0' )
{
int i;
line( "/* Contents of EXPORT section */" );
for( exportptr=exports; *exportptr; exportptr++ )
{
......@@ -120,14 +132,7 @@ static void h_declns( basename, exports, d ) char *basename, *exports; declnlist
data_decls( d );
for( dl = d; dl != NULL; dl=dl->next )
{
if( dl->UseNull )
{
line( "#define %s_%s() ((%s)NULL)",
dl->name, dl->shapes->name, dl->name );
}
}
line( "\n/* Prototypes for all types */\n" );
line( "#ifdef HASPROTOS" );
protos( d, TRUE );
line( "#else" );
......@@ -184,7 +189,7 @@ static void c_declns( basename, globals, d ) char *basename, *globals; declnlist
}
cons_fns( d );
decons_fns( d );
print_fns( d );
if( *globalptr != '\0' )
......@@ -200,14 +205,12 @@ static void c_declns( basename, globals, d ) char *basename, *globals; declnlist
}
/* --------------------------- The types ---------------------------------- */
/* ------------------------ Declare the types ------------------------------ */
static void data_decls( decs ) declnlist decs;
{
declnlist d;
shapelist s;
int n;
for( d=decs; d != NULL; d=d->next )
{
......@@ -220,64 +223,81 @@ static void data_decls( decs ) declnlist decs;
line( "typedef int %s;", d->name );
}
}
line( "\n" );
nl();
nl();
for( d=decs; d != NULL; d=d->next )
{
line( "/* ---- Type %s ---- */\n", d->name );
n = 0;
if( d->Defines )
declare_type( d );
}
}
static void declare_type( d ) decln d;
{
shapelist s;
line( "/* ---- Type %s ---- */\n", d->name );
if( d->ManyShapes )
{
line( "typedef enum {" );
indent();
for( s = d->shapes; s != NULL; s=s->next )
{
for( s = d->shapes; s != NULL; s=s->next )
{
if( d->Struct )
{
line( "#define %s_%s_tag %d",
d->name, s->name, n++ );
} else
{
line( "#define %s_%s() %d",
d->name, s->name, n++ );
}
}
line( "" );
line( "%s_is_%s,", d->name, s->name );
}
outdent();
line( "} kind_of_%s;\n", d->name );
}
if( d->Struct )
if( d->Struct )
{
line( "struct %s {", d->name );
indent();
if( d->TagField )
{
line( "kind_of_%s\ttag;", d->name );
}
if( d->Union )
{
line( "struct %s {", d->name );
line( "union {" );
indent();
if( d->TagField )
{
line( "int\ttag;" );
}
}
for( s = d->shapes; s != NULL; s=s->next )
{
if( s->params == NULL ) continue;
if( d->Union )
{
line( "union {" );
indent();
}
for( s = d->shapes; s != NULL; s=s->next )
{
if( d->Union && s->params )
/* need internal structures */
if( s->params->next == NULL )
{
/* don't need internal struct */
/* but use {shape name}_{field name} */
line( "%s\t%s_%s;", s->params->type,
s->name, s->params->name );
} else
{
/* need internal struct */
line( "struct {" );
indent();
declfields( s->params );
outdent();
line( "} %s;", s->name );
} else
{
declfields( s->params );
}
}
if( d->Union )
} else
{
outdent();
line( "} u;" );
/* only one chunk of data: this one */
declfields( s->params );
}
}
if( d->Union )
{
outdent();
line( "};\n" );
line( "} u;" );
}
outdent();
line( "};\n" );
}
}
......@@ -291,44 +311,110 @@ static void declfields( p ) paramlist p;
}
/* ------------------------ Constructor functions ------------------------- */
/* ---------------------- Declare all prototypes -------------------------- */
static void protos( d, prot ) declnlist d; BOOL prot;
{
for( ; d != NULL; d = d->next )
{
proto_type( d, prot );
}
}
static void proto_type( d, prot ) decln d; BOOL prot;
{
shapelist s;
shapelist shapes;
for( ; d != NULL; d = d->next )
s = d->shapes;
if( d->Struct )
{
/* genuine constructor functions needed */
if( d->UseNull )
{
/* except for first shape */
line( "#define %s_%s() ((%s)NULL)",
d->name, d->shapes->name, d->name );
s = s->next;
}
for( ; s != NULL; s = s->next )
{
cons_fn_proto( d, s, prot );
}
} else
{
/* enumeration: use #define for all constructors */
for( ; s != NULL; s = s->next )
{
line( "#define %s_%s() ((int)%s_is_%s)",
d->name, s->name,
d->name, s->name );
}
}
if( d->ManyShapes )
{
/* need a deconstructor kind function/macro */
if( d->Struct )
{
shapes = d->shapes;
if( d->UseNull )
{
shapes = shapes->next;
}
for( s = shapes; s != NULL; s = s->next )
/* a true function is required */
deconskind_proto( d, prot );
} else
{
/* enumeration: a macro will do */
line( "#define %s_kind(this) ((kind_of_%s) this)",
d->name, d->name );
}
}
if( d->Struct )
{
for( s = d->shapes; s != NULL; s = s->next )
{
if( s->params != NULL )
{
one_proto( d->name, s, prot );
decons_fn_proto( d, s, prot );
}
}
fprintf( outfile, "extern void print_%s(", d->name );
if( prot )
}
print_fn_proto( d->name, prot );
}
/* ------------------------------- Constructors --------------------------- */
static void cons_fns( d ) declnlist d;
{
shapelist s;
for( ; d != NULL; d=d->next )
{
/* ignore enumerations: constructors already in .h file */
if( ! d->Struct ) continue;
/* We need constructor functions for this type */
s = d->shapes;
if( d->UseNull )
{
fprintf( outfile, " %s ", d->name );
/* Null cons func is a #define in .h file: skip it */
s = s->next;
}
for( ; s != NULL; s=s->next )
{
cons_fn( d, s );
}
fputs( ");\n", outfile );
}
}
static void one_proto( name, s, prot ) char *name; shapelist s; BOOL prot;
static void cons_fn_proto( d, s, prot ) decln d; shapelist s; BOOL prot;
{
paramlist p;
BOOL first;
fprintf( outfile, "extern %s %s_%s( ", name, name, s->name );
ASSERT( d->Struct, ("cons_fn_proto: d->Struct is false!\n") );
fprintf( outfile, "extern %s %s_%s( ", d->name, d->name, s->name );
if( prot )
{
if( s->params == NULL )
......@@ -349,115 +435,264 @@ static void one_proto( name, s, prot ) char *name; shapelist s; BOOL prot;
}
static void cons_fns( d ) declnlist d;
static void cons_fn( d, s ) decln d; shapelist s;
{
shapelist s;
shapelist shapes;
paramlist p;
BOOL first;
for( ; d != NULL; d=d->next )
ASSERT( d->Struct, ("cons_fn: d->Struct is FALSE!\n") );
fprintf( outfile, "%s %s_%s( ", d->name, d->name, s->name );
first = TRUE;
for( p=s->params; p != NULL; p=p->next, first=FALSE )
{
if( d->Struct )
if( !first ) fputs( ", ", outfile );
fputs( p->name, outfile );
}
fputs( " )", outfile );
for( p=s->params; p != NULL; p=p->next )
{
fprintf( outfile, " %s %s;", p->type, p->name );
}
line( "\n{" );
indent();
line( "%s\tnew = NEW(%s);", d->name, d->name );
if( d->TagField )
{
line( "new->tag = %s_is_%s;", d->name, s->name );
}
if( d->Union && s->params != NULL && s->params->next == NULL )
{
/* no internal struct needed for this shape */
line( "new->u.%s_%s = %s;", s->name,
s->params->name, s->params->name );
} else
{
paramlist p;
for( p=s->params; p != NULL; p=p->next )
{
/* We need constructor functions */
shapes = d->shapes;
if( d->UseNull )
if( d->Union )
{
/* Null cons func already made */
shapes = shapes->next;
}
for( s = shapes; s != NULL; s=s->next )
/* an internal struct */
line( "new->u.%s.%s = %s;", s->name,
p->name, p->name );
} else
{
cons_fn_hdr( d->name, s );
cons_fn_body( d, d->name, s );
fprintf( outfile, "\n\n" );
/* only one chunk of data: this one */
line( "new->%s = %s;", p->name, p->name );
}
}
}
line( "return new;" );
outdent();
line( "}\n\n" );
}
static void cons_fn_hdr( name, s ) char *name; shapelist s;
/* ------------------------- Deconstructors ------------------------------- */
static void decons_fns( d ) declnlist d;
{
paramlist p;
BOOL first;
for( ; d != NULL; d=d->next )
{
if( d->Struct )
{
decons_fns_type( d );
}
/* enumerations need none (decon kind macro already in .h) */
}
}
fprintf( outfile, "%s %s_%s( ", name, name, s->name );
first = TRUE;
for( p=s->params; p != NULL; p=p->next, first=FALSE )
static void decons_fns_type( d ) decln d;
{
shapelist s;
ASSERT( d->Struct, ("decons_fns_type: d->Struct is FALSE!\n") );
if( d->ManyShapes )
{
if( !first ) fputs( ", ", outfile );
fputs( p->name, outfile );
/* We need a true deconstructor kind function */
deconskind_fn( d );
}
fputs( " ) ", outfile );
for( p=s->params; p != NULL; p=p->next )
/* We need (some) deconstructor functions */
for( s = d->shapes; s != NULL; s=s->next )
{
fprintf( outfile, "%s %s; ", p->type, p->name );
if( s->params != NULL )
{
decons_fn( d, s );
}
}
nl();
}
static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
/* ------------------- Deconstructor Kind procedure ----------------------- */
static void deconskind_proto( d, prot ) decln d; BOOL prot;
{
paramlist p;
ASSERT( d->ManyShapes,
("deconskind_proto: d->ManyShapes is FALSE!\n") );
ASSERT( d->Struct, ("deconskind_proto: d->Struct is FALSE!\n") );
fprintf( outfile, "extern kind_of_%s %s_kind( ", d->name, d->name );
if( prot )
{
fprintf( outfile, "%s ", d->name );
}
fputs( ");\n", outfile );
}
static void deconskind_fn( d ) decln d;
{
shapelist s = d->shapes;
ASSERT( d->ManyShapes, ("deconskind_fn: d->ManyShapes is FALSE!\n") );
ASSERT( d->Struct, ("deconskind_fn: d->Struct is FALSE!\n") );
fprintf( outfile, "kind_of_%s %s_kind( this ) %s this;\n",
d->name, d->name, d->name );
ASSERT( d->Struct,
("error: cons_fn_body called but d->Struct is FALSE!\n") );
line( "{" );
indent();
line( "%s\tnew;\n", name );
line( "new = NEW(%s);", name );
if ( d->UseNull )
{
line( "if( this == NULL )" );
line( "{" );
indent();
line( "return %s_is_%s;", d->name, s->name );
outdent();
line( "}" );
s = s->next;
}
if( d->TagField )
{
line( "new->tag = %s_%s_tag;", name, s->name );
line( "return this->tag;" );
}
for( p=s->params; p != NULL; p=p->next )
else
{
if( d->Union )
line( "return %s_is_%s;", d->name, s->name );
}
outdent();
line( "}\n\n" );
}
/* ----------------------- Deconstructor functions ------------------------ */
static void decons_fn_proto( d, s, prot ) decln d; shapelist s; BOOL prot;
{
ASSERT( d->Struct, ("decons_fn_proto: d->Struct is FALSE!\n") );
ASSERT( s->params != NULL,
("decons_fn_proto: no fields in shape!!\n") );
fprintf( outfile, "extern void get_%s_%s(", d->name, s->name );
if( prot )
{
paramlist p;
fprintf( outfile, " %s ", d->name );
for( p = s->params; p != NULL ; p=p->next )
{
line( "new->u.%s.%s = %s;",
s->name, p->name, p->name );
} else
fprintf( outfile, ", %s * ", p->type );
}
}
fputs( ");\n", outfile );
}
static void decons_fn( d, s ) decln d; shapelist s;
{
paramlist p;
ASSERT( d->Struct, ("decons_fn: d->Struct is FALSE!\n") );
ASSERT( s->params != NULL, ("decons_fn: no fields in shape!!\n") );
fprintf( outfile, "void get_%s_%s( this", d->name, s->name );
for( p=s->params; p != NULL; p=p->next )
{
fprintf( outfile, ", %s ", p->name );
}
fprintf( outfile, ") %s this;", d->name );
for( p=s->params; p != NULL; p=p->next )
{
fprintf( outfile, " %s *%s;", p->type, p->name );
}
line( "\n{" );
indent();
if( d->Union && s->params != NULL && s->params->next == NULL )
{
/* no internal struct: one field only */
line( "*%s = this->u.%s_%s;",
s->params->name, s->name, s->params->name );
} else
{
for( p=s->params; p != NULL; p=p->next )
{
line( "new->%s = %s;", p->name, p->name );
if( d->Union )
{
/* internal struct */
line( "*%s = this->u.%s.%s;",
p->name, s->name, p->name );
} else
{
/* only one chunk of data: this one */
line( "*%s = this->%s;", p->name, p->name );
}
}
}
line( "return new;" );
outdent();
line( "}" );
line( "}\n\n" );
}
/* -------------------------- Print functions ----------------------------- */
static void print_fns( d ) declnlist d;
static void print_fn_proto( name, prot ) char *name; BOOL prot;
{
shapelist s;
shapelist shapes;
fprintf( outfile, "extern void print_%s(", name );