TAG_SYMBOL * defstruct (char *sname, int storage, int is_struct) { int itag ; /* index of tag in tag symbol table */ char nam[20]; /* Dummy name */ TAG_SYMBOL *tag = NULL; if ( tagptr >= ENDTAG ) { error(E_STROV) ; } if ( sname && sname[0] == 0 ) sname = NULL; if ( sname && (tag = findtag(sname) ) ) { if ( tag->weak == 0 ) { if ( rcmatch('{') ) multidef(); else return tag; } itag = tag - tagtab; } /* No tag defined for this, so leave it alone */ if ( tag == NULL ) { tag = tagptr++; itag = tag - tagtab ; sprintf(nam,"0st%d",itag); if ( sname == NULL ) sname = nam; strcpy(tag->name,sname); tag->size = 0; tag->ptr = tag->end = membptr ; /* Set so no member searches done.. */ dummy_sym[NTYPE+1+itag] = addglb(nam,POINTER,STRUCT,0,STATIK,0,itag) ; tag->weak = 1; } if ( rcmatch('{' ) ) { /* increment tagptr to add tag to table */ tag->ptr = membptr; tag->weak = 0; needchar('{') ; while ( dodeclare(storage, tag, is_struct) ) ; needchar('}') ; tag->end = membptr ; } return tag ; }
/* * initialise aggregate */ void agg_init(int size, int type, int ident, int *dim, int more, TAG_SYMBOL *tag) { while (*dim) { if (ident == ARRAY && type == STRUCT) { /* array of struct */ needchar('{'); str_init(tag); --*dim; needchar('}'); } else { init(size, ident, dim, more, (ident == ARRAY && more == CCHAR),0); } if (cmatch(',') == 0) break; blanks(); } }
void PragmaBytes(int flag) { FILE *fp; char sname[NAMESIZE]; int32_t value; int count; if ( symname(sname) ) { if ( (fp=fopen("zcc_opt.def","a")) == NULL ) { error(E_ZCCOPT); } fprintf(fp,"\nIF NEED_%s\n",sname); if ( flag ) fprintf(fp,"\tdefc DEFINED_NEED_%s = 1\n",sname); /* Now, do the numbers */ count=0; while ( !cmatch(';') ) { if ( count == 0 ) fprintf(fp,"\n\tdefb\t"); else fprintf(fp,","); if ( number(&value) ) { fprintf(fp,"%d",value); } else { warning(W_EXPARG); } if ( rcmatch(';') ) { break; } needchar(','); count++; if ( count == 9 ) count=0; } fprintf(fp,"\nENDIF\n"); fclose(fp); needchar(';'); } }
void defenum(char *sname, char storage) { SYMBOL *ptr; char name[NAMEMAX]; long value; /* Add it into the symbol table, we do not need to keep track of the * tag because we treat enums as constants */ addglb(sname, ENUM, CINT, 0, storage, 0, 0); value=0; /* initial constant */ needchar('{'); do { if (symname(name)==0) illname(name); if ( cmatch('=') ) constexpr(&value,1); ptr=addglb(name,VARIABLE,ENUM,0,STATIK,0,0); ptr->size=value; value++; } while (cmatch(',')); needchar('}'); }
/* * Declare a static variable (i.e. define for use) * * makes an entry in the symbol table so subsequent * references can call symbol by name */ void declglb( int typ , /* typ is CCHAR, CINT, DOUBLE, STRUCT, LONG, */ int storage, TAG_SYMBOL *mtag , /* tag of struct whose members are being declared, or zero */ TAG_SYMBOL *otag , /* tag of struct for object being declared */ int is_struct , /* TRUE if struct member being declared, zero if union */ char sign , /* TRUE if need signed */ char zfar ) /* TRUE if far */ { char sname[NAMESIZE]; int size, ident, more, itag, type, size_st; long addr = -1; char flagdef,match,ptrtofn; char libdef,fastcall,callee; SYMBOL *myptr ; do { if ( endst() ) break; /* do line */ type = typ ; size = 1 ; /* assume 1 element */ more = /* assume dummy symbol not required */ itag = 0 ; /* just for tidiness */ flagdef=libdef=fastcall=callee=NO; match=ptrtofn=NO; while (blanks(),rcmatch('_') ) { match=NO; if (amatch("__APPFUNC__") ) { match=YES; flagdef=1; } if (amatch("__LIB__") /* && libdef==0 */) {match=YES; libdef|=LIBRARY; } if (amatch("__FASTCALL__") ) {match=YES; fastcall=REGCALL; } if (amatch("__SHARED__") ) {match=YES; libdef|=SHARED; } if (amatch("__SHAREDC__") ) {match=YES; libdef|=SHAREDC; } if (amatch("__CALLEE__") ) {match=YES; callee=CALLEE; } if (match ==NO )break; } ident = get_ident() ; if (storage==TYPDEF && ident !=VARIABLE && mtag ==0 ) warning(W_TYPEDEF); if ( symname(sname) == 0 ) /* name ok? */ illname(sname) ; /* no... */ if ( ident == PTR_TO_FNP ) { /* function returning pointer needs dummy symbol */ more = dummy_idx(typ, otag) ; type = (zfar ? CPTR : CINT ); size=0; ptrtofn=YES; } else if ( ident == PTR_TO_FN ) { ident = POINTER ; ptrtofn=YES; #if 0 } else if ( cmatch('@') ) { storage = EXTERNP; constexpr(&addr,1); #endif } else if ( cmatch('(') ) { /* * Here we check for functions, but we can never have a pointer to * function because thats considered above. Which means as a very * nice side effect that we don't have to consider structs/unions * since they can't contain functions, only pointers to functions * this, understandably(!) makes the work here a lot, lot easier! */ storage=AddNewFunc(sname,type,storage,zfar,sign,otag,ident,&addr); /* * On return from AddNewFunc, storage will be: * EXTERNP = external pointer, in which case addr will be set * !! FUNCTION = have prototyped a function (NOT USED!) * 0 = have declared a function/!! prototyped ANSI * * If 0, then we have to get the hell out of here, FUNCTION * then gracefully loop round again, if EXTERNP, carry on with * this function, anything else means that we've come up * against a K&R style function definition () so carry on * as normal! * * If we had our function prefixed with __APPFUNC__ then we want * to write it out to the zcc_opt.def file (this bloody thing * is becoming invaluable for messaging! * * __SHARED__ indicates in a library so preserve carry flag * (so we can test with iferror) * * __CALLEE__ indicates that the function called cleans up * the stack * * __SHAREDC__ is indicates call by rst 8 but is unused.. * (old idea unused, but may yet be useful) */ if (flagdef) WriteDefined(sname,0); if (currfn) { /* djm 1/2/03 - since we can override lib functions don't reset the library flag currfn->flags&=(~LIBRARY); */ if (libdef) { // currfn->flags|=LIBRARY; currfn->flags|=libdef; } if (callee && (libdef&SHARED) != SHARED && \ (libdef&SHAREDC) != SHAREDC ) currfn->flags|=callee; if (fastcall) currfn->flags|=fastcall; } if (storage==0) { if ( addr != -1 ) { currfn->size = addr; } return; } /* * External pointer..check for the closing ')' */ if (storage==EXTERNP) { needchar(')'); } else { /* * Must be a devilishly simple prototype! ();/, type... */ ptrerror(ident) ; if ( ident == POINTER ) { /* function returning pointer needs dummy symbol */ more = dummy_idx(typ, otag) ; type = (zfar ? CPTR : CINT ); ident=FUNCTIONP; } else { ident=FUNCTION; } size = 0 ; } } if (cmatch('[')) { /* array? */ ptrerror(ident) ; if ( ident == POINTER) { /* array of pointers needs dummy symbol */ more = dummy_idx(typ, otag) ; type = (zfar ? CPTR : CINT ); } size = needsub() ; /* get size */ if (size == 0 && ident == POINTER ) size=0; ident = ARRAY; if ( ptrtofn ) needtoken(")()"); } else if ( ptrtofn ) { needtoken(")()") ; } else if ( ident == PTR_TO_PTR ) { ident = POINTER ; more = dummy_idx(typ, otag) ; type = (zfar ? CPTR : CINT ); } if ( cmatch('@') ) { storage = EXTERNP; constexpr(&addr,1); }
SYMBOL * #endif dofnansi(SYMBOL *currfn, long *addr) { SYMBOL *prevarg; /* ptr to symbol table entry of most recent argument */ SYMBOL *argptr; /* Temporary holder.. */ TAG_SYMBOL *otag ; /* structure tag for structure argument */ struct varid var; char proto; locptr=STARTLOC; prevarg=0; Zsp=0; /* Reset stack pointer */ undeclared=1; proto=YES; swallow("__TD__"); /* kludge to get round typedef problem */ /* Master loop, checking for end of function */ while ( cmatch(')') == 0 ) { if (amatch("...") ) { /* * Found some ellipses, so, add it to the local symbol table and * then return..(after breaking, and checking for ; & , ) */ if (proto == 1 ) warning(W_ELLIP); needchar(')'); argptr=addloc("ellp",0,ELLIPSES,0,0); argptr->offset.p = prevarg; prevarg=argptr; break; } otag=GetVarID(&var,STATIK); if (var.type==STRUCT) { prevarg=getarg(STRUCT, otag,YES,prevarg,0, var.zfar,proto) ; } else if (var.type) { prevarg=getarg(var.type,NULL_TAG,YES,prevarg,var.sign,var.zfar,proto); } else { warning(W_EXPARG); break; } proto++; /* Now check for comma */ if (ch() !=')' && cmatch(',') == 0) { warning(W_EXPCOM); break; } } /* * Check for semicolon - I think this should be enough, just * have to have prototypes on separate lines - good practice * in anycase!! */ if (cmatch('@') ) { constexpr(addr,1); } if (cmatch(';') ) return (prevarg); setlocvar(prevarg,currfn); return (0); }
/* * initialise global object */ int initials(char *sname, int type, int ident, int dim, int more, TAG_SYMBOL * tag, char zfar) { int size, desize = 0; int olddim = dim; if (cmatch('=')) { /* initialiser present */ defstatic = 1; /* So no 2nd redefine djm */ gltptr = 0; glblab = getlabel(); if (dim == 0) dim = -1; switch (type) { case CCHAR: size = 1; break; case LONG: size = 4; break; case CINT: default: size = 2; } output_section("data_compiler"); // output_section("text"); prefix(); outname(sname, YES); col(); nl(); if (cmatch('{')) { /* aggregate initialiser */ if ((ident == POINTER || ident == VARIABLE) && type == STRUCT) { /* aggregate is structure or pointer to structure */ dim = 0; olddim = 1; if (ident == POINTER) point(); str_init(tag); } else { /* aggregate is not struct or struct pointer */ agg_init(size, type, ident, &dim, more, tag); } needchar('}'); } else { /* single initialiser */ init(size, ident, &dim, more, 0, 0); } /* dump literal queue and fill tail of array with zeros */ if ((ident == ARRAY && more == CCHAR) || type == STRUCT) { if (type == STRUCT) { dumpzero(tag->size, dim); desize = dim < 0 ? abs(dim+1)*tag->size : olddim * tag->size; } else { /* Handles unsized arrays of chars */ dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } dumplits(0, YES, gltptr, glblab, glbq); } else { if (!(ident == POINTER && type == CCHAR)) { dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab,glbq); if ( type != CCHAR ) /* Already dumped by init? */ desize = dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } } output_section("code_compiler"); // output_section("code"); } else { char *dosign, *typ; dosign = ""; if (ident == ARRAY && (dim == 0)) { typ = ExpandType(more, &dosign, (tag - tagtab)); warning(W_NULLARRAY, dosign, typ); } /* no initialiser present, let loader insert zero */ if (ident == POINTER) type = (zfar ? CPTR : CINT); cscale(type, tag, &dim); desize = dim; } return (desize); }
/* * initialise structure */ int str_init(TAG_SYMBOL *tag) { int dim, flag; int sz, usz, numelements = 0; SYMBOL *ptr; int nodata = NO; ptr = tag->ptr; while (ptr < tag->end) { numelements++; dim = ptr->size; sz = getstsize(ptr,NO); if ( nodata == NO ) { if ( rcmatch('{') ) { needchar('{'); while (dim) { if ( ptr->type == STRUCT ) { if ( ptr->ident == ARRAY ) /* array of struct */ needchar('{'); str_init(tag); if ( ptr->ident == ARRAY ) { --dim; needchar('}'); } } else { init(sz, ptr->ident, &dim, 1, 1,1); } if (cmatch(',') == 0) break; blanks(); } needchar('}'); dumpzero(sz,dim); } else { init(sz, ptr->ident, &dim, ptr->more, 1, 1); } /* Pad out afterwards */ } else { /* Run out of data for this initialisation, set blank */ defstorage(); outdec(dim * getstsize(ptr,YES)); nl(); } usz = (ptr->size ? ptr->size : 1 ) * getstsize(ptr,YES); ++ptr; flag = NO; while (ptr->offset.i == 0 && ptr < tag->end) { if (getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) > usz) { usz = getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) ; flag = YES; } ++ptr; } /* Pad out the union */ if (usz != sz && flag) { defstorage(); outdec(usz - sz); nl(); } if (cmatch(',') == 0 && ptr != tag->end) { nodata = YES; } } return numelements; }