3 * (C) Copyright Apr 15 1995, Edmond J. Breen.
5 * This code may be copied for personal, non-profit use only.
24 int EiC_iskeyword(keyword_t *keywords,char*id,int n)
28 if(strcmp(keywords[i].id,id) == 0)
29 return keywords[i].token;
34 void EiC_eicpush(eicstack_t *s, val_t v)
38 s->val = (val_t*)xcalloc(sizeof(val_t),MoD);
40 s->val = (val_t*)xrealloc(s->val,(s->n+MoD)*sizeof(val_t));
46 int EiC_eicpop(eicstack_t *s, val_t *pop)
56 s->val = (val_t*)xrealloc(s->val,s->n*sizeof(val_t));
62 /* LOOK UP TABLE ROUTINES
63 --------------------------*/
65 static size_t _EnTrY_No = 0;
66 int hashsmc(char * s,int mod);
67 symentry_t *EiC_HTAB[HSIZE];
70 /* code for generating tempories */
71 unsigned int NumTemps=0, CurTemp =0;
73 symentry_t * EiC_nxtTemp(int obj, int level)
77 sprintf(tmpName,"%s%d","__TeMp",NumTemps);
79 /* There should be no need to watch out for change of level !!!!
80 * It will be assumed that the compound statement routine will
85 sym = EiC_insertLUT(EiC_work_tab,tmpName,obj);
90 if(sym->val.ival == -1) /* needs a home */
91 EiC_stackit(sym,level);
93 /* Setting up the token information is left
94 * to the caller of this routine.
103 size_t EiC_lut_NextEntryNum(void)
108 int hashsmc(char * s,int mod)
110 register unsigned int h, c;
112 while( (c = (int) *s++) > 0)
121 char *EiC_getClashedfname(char nspace,char *id)
124 for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
125 if(sym->nspace == nspace && strcmp(id,sym->id) == 0)
126 if((sym->sclass & c_private) &&
127 sym->fname != CurrentFileName()) {
133 symentry_t * EiC_lookup(char nspace, char *id)
137 for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
138 if(sym->nspace == nspace && strcmp(id,sym->id) == 0) {
139 if((sym->sclass & c_private) &&
140 sym->fname != CurrentFileName()) {
153 symentry_t * EiC_insertLUT(char nspace,char *id,int type)
158 sym = (symentry_t *) xcalloc(1,sizeof(symentry_t));
161 if( (sym->id = EiC_strsave(id)) == NULL) {
165 sym->entry = _EnTrY_No++;
166 hashval = hashsmc(sym->id,HSIZE);
167 sym->next = EiC_HTAB[hashval];
168 EiC_HTAB[hashval] = sym;
169 sym->nspace = nspace;
170 sym->val.ival = -1; /* indicates unused */
171 sym->type = EiC_addtype(type,NULL);
172 sym->fname = CurrentFileName();
177 void delete(symentry_t *sym)
179 auto symentry_t * this;
182 idx = hashsmc(sym->id,HSIZE);
183 this = EiC_HTAB[idx];
185 EiC_HTAB[idx] = sym->next;
186 else { /* find and unlink */
187 while(this && this->next != sym)
189 this->next = sym->next;
193 void EiC_UpdateSymPos(symentry_t * sym)
196 if(sym->next && sym->next->level > sym->level) {
197 symentry_t * p = EiC_HTAB[hashsmc(sym->id,HSIZE)];
199 while(p->next != sym)
201 if(p->next->level > sym->level)
214 void EiC_remsym(symentry_t *sym)
224 void remBuiltin(symentry_t *sym)
226 /* removes the prototype of the builtin function only */
227 EiC_freetype(sym->type);
228 sym->type = EiC_addtype(t_builtin,NULL);
229 sym->fname = "::EiC::";
235 void EiC_remlevel(int level)
238 symentry_t * sym, *symh;
240 for(i=0;i<HSIZE;i++) {
242 while(sym && sym->level >= level) {
251 /*CUT lutRemTempories*/
252 void EiC_remTempories(void)
255 symentry_t * sym, *symh;
257 for(i=0;i<HSIZE;i++) {
259 while(sym && IsTemp(sym->type)) {
271 int EiC_lutClearFileEntries(char *FileName)
275 symentry_t * sym, *p, *t;
277 for(i=0;i<HSIZE;i++) {
278 t = sym = EiC_HTAB[i];
281 if(strcmp(sym->fname,FileName) == 0) {
303 void EiC_lut_CleanUp(size_t bot)
307 symentry_t * sym, *p, *t;
308 for(i=0;i<HSIZE;i++) {
309 t = sym = EiC_HTAB[i];
312 if(sym->entry >= bot) {
313 if(EiC_gettype(sym->type) == t_builtin) {
338 #define freeAg(X) do {\
340 if(!isconst(x->type)) \
341 xfree(EiC_ENV->AR[x->val.ival].v.p.p);\
342 else xfree(x->val.p.p);\
346 #define freeAg1(X) xfree(EiC_ENV->AR[X->val.ival].v.p.p)
349 static void free_sym(symentry_t *sym)
353 printf("Freeing [%s] %d %d [%d]\n",
354 sym->id, sym->entry, sym->val.ival,EiC_gettype(sym->type));
358 if(EiC_gettype(sym->type) == t_func) {
360 } else if(sym->level == 1) { /* global value */
362 if((t=EiC_gettype(sym->type)) == t_array && sym->val.ival >=0)
364 else if ((t== t_union || t == t_struct) && sym->val.ival >=0 )
371 * the conditions for pushing onto the ARgar stack
372 * must be the same as those for stacking as found in
373 * function establish_id
374 * Except for ParseError
376 if( sym->val.ival >=0
378 && EiC_gettype(sym->type) != t_builtin ) {
379 if(! isconst(sym->type)
380 && sym->nspace == stand_tab
381 && sym->sclass != c_typedef) {
382 EiC_eicpush(&EiC_ENV->ARgar,sym->val);
385 EiC_freetype(sym->type);
391 void EiC_UpdateEntry(symentry_t *sym)
393 int t = EiC_gettype(sym->type);
394 if(CurrentFileName() != sym->fname &&
399 sym->entry = _EnTrY_No++;
400 sym->pname = sym->fname;
401 sym->fname = CurrentFileName();
404 void EiC_addoffsettolevel(char nspace,int level,int off)
409 for(i=0;i<HSIZE;i++) {
411 while(sym && sym->level == level && sym->nspace == nspace) {
412 sym->val.ival = -(sym->val.ival + off);
418 void EiC_marktype(type_expr *type, char mark)
422 void EiC_markFunc(type_expr *t,int mark);
426 switch(EiC_gettype(type)) {
428 if(EiC_getInf(type) == NULL)
432 EiC_markFunc(type,mark);
438 s = EiC_getInf(type);
440 * REM must allow for incomplete
448 xmark(s->offset,mark);
451 for(i=0;i<s->n;i++) {
452 xmark(s->id[i],mark);
453 EiC_marktype(s->type[i],mark);
457 for(i=0;i<s->ntags;++i)
458 EiC_marktype(s->tag[i],mark);
462 type = nextType(type);
466 static void marklabel(Label_t *l,char mark)
475 static void markcode(symentry_t *sym,char mark)
480 code = EiC_ENV->AR[sym->val.ival].v.p.p;
482 xmark(code->inst,mark);
483 marklabel(code->labels,mark);
484 marklabel(code->gotos,mark);
487 for(i=0;i<code->nextinst;i++,inst++)
488 if(inst->opcode == jmptab) {
493 } else if(inst->opcode == assigntype)
494 EiC_marktype(inst->val.p.p,mark);
498 void EiC_marksyms(char mark)
500 void EiC_markmacros(char);
501 void EiC_markENV(char);
506 EiC_markmacros(mark);
509 xmark(EiC_ENV->AR,mark);
511 xmark(EiC_ENV->ARgar.val,mark);
513 xmark(EiC_ENV->LAR,mark);
514 if(EiC_ENV->CODE.nextinst)
515 xmark(EiC_ENV->CODE.inst,mark);
520 for(i=0;i<HSIZE;i++) {
523 /*printf("marking %s\n",sym->id);*/
524 if(strcmp(sym->id,"p") == 0)
528 EiC_marktype(sym->type,mark);
529 if(sym->nspace != tag_tab)
530 switch(EiC_gettype(sym->type)) {
531 case t_func: markcode(sym,mark); break;
535 if(isconst(sym->type))
536 xmark(sym->val.p.p,mark);
538 if(sym->sclass != c_typedef && sym->val.ival >= 0)
539 xmark(EiC_ENV->AR[sym->val.ival].v.p.p,mark);
548 char * EiC_strsave(char *s)
553 for(n = 0,p =s; *p != '\0';++p,++n)
556 p = xcalloc(n,sizeof(char));
558 while((*p++ = *s++));
562 void EiC_newsymtype(symentry_t *sym, type_expr *t)
565 if(sym->type && sym->type != t)
566 EiC_freetype(sym->type);
571 int nextstackitem(int level)
573 if(level == 1) { /* static variables */
575 if(!EiC_eicpop(&EiC_ENV->ARgar,&v)) { /* check for spare slots */
576 if(EiC_ENV->sp == EiC_ENV->ARsize) {
578 EiC_ENV->AR = (AR_t*)xcalloc(sizeof(AR_t),1);
580 EiC_ENV->AR = (AR_t*)xrealloc(EiC_ENV->AR,
581 (EiC_ENV->sp+1)*sizeof(AR_t));
584 v.ival = EiC_ENV->sp;
588 } else { /* automatic variables */
589 if(EiC_ENV->lsp == EiC_ENV->LARsize) {
590 if(!EiC_ENV->LARsize)
591 EiC_ENV->LAR = (AR_t*)xcalloc(sizeof(AR_t),1);
593 EiC_ENV->LAR = (AR_t*)xrealloc(EiC_ENV->LAR,(EiC_ENV->lsp+1)*
598 return EiC_ENV->lsp - 1;
602 int EiC_stackit(symentry_t * sym,int level)
607 i = nextstackitem(level);
608 if(level == 1) /* static variables */
610 else /* local variable */
615 ar[i].v.dval = 0; /* NULL it */
616 ar[i].type = sym->type;
621 /*------------------------------------------------*/
622 void EiC_inittoken(token_t * e1)
625 e1->Code.binst = e1->Code.nextinst = 0;
626 e1->Code.labels = e1->Code.gotos = NULL;
627 e1->Typequal = e1->Sclass = 0;
632 void EiC_freetoken(token_t * e1)
634 EiC_freetype(e1->Type);
637 void initcode(code_t * code)
639 code->binst = code->nextinst = 0;
643 void EiC_cleancode(code_t * code)
651 /* printf("Next instr: %d\n", code->nextinst); */
652 /* rem free up other info also */
653 for(i=0;i<code->nextinst;i++,inst++)
654 if(inst->opcode == jmptab) {
659 } else if(inst->opcode == assigntype)
660 EiC_freetype(inst->val.p.p);
664 static void freeCodeLabels(code_t *code)
666 void EiCp_freeLabels(Label_t *lab);
668 EiCp_freeLabels(code->labels);
672 EiCp_freeLabels(code->gotos);
677 void EiC_killcode(symentry_t *sym)
680 code = EiC_ENV->AR[sym->val.ival].v.p.p;
684 freeCodeLabels(code);
688 void EiC_freecode(code_t * code)
691 if(code && code->binst > 0) {
693 code->nextinst = code->binst = 0;
694 freeCodeLabels(code);
700 void EiC_generate(code_t * code, int opcode,val_t *val,int ext)
704 if(code->nextinst == code->binst)
705 if(!(code->binst%ModSize)) {
707 inst = (InsT_t*)xcalloc(1,sizeof(InsT_t)*ModSize);
710 xrealloc(inst,(code->binst+ModSize)*sizeof(InsT_t));
711 code->binst += ModSize;
714 inst[code->nextinst].opcode = opcode;
715 inst[code->nextinst].val = *val;
716 inst[code->nextinst].ext = ext;
717 inst[code->nextinst].line = CurrentLineNo();
722 void copycode(code_t * c1, code_t * c2)
724 /* this function needs to handle label and gotos */
728 for(i=0;i<c2->nextinst;++i,++inst) {
729 EiC_generate(c1,inst->opcode,&inst->val,inst->ext);
730 c1->inst[c1->nextinst-1].line = inst->line;
734 void copycode(code_t * c1, code_t * c2)
736 Label_t * EiCp_addLabel(Label_t *, char *, int, int);
743 /* concatenate labels*/
747 c1->labels = EiCp_addLabel(c1->labels,lab->name,lab->loc+c1->nextinst,1);
751 /* conatenate gotos */
755 c1->gotos = EiCp_addLabel(c1->gotos,lab->name,lab->loc+c1->nextinst,0);
760 Tsize = c1->nextinst + c2->nextinst;
761 /* make memory size a multiple of ModSize */
764 Tsize += ModSize - (Tsize%ModSize);
766 c1->inst = xrealloc(c1->inst,Tsize*sizeof(InsT_t));
768 c1->inst = xcalloc(Tsize,sizeof(InsT_t));
770 memcpy(&inst[c1->nextinst], c2->inst, c2->nextinst * sizeof(InsT_t));
777 void EiC_concode(code_t * c1, code_t * c2)
782 void EiC_contoken(token_t * e1, token_t * e2)
784 EiC_concode(&e1->Code,&e2->Code);
785 e1->Type = EiC_getcontype(e1->Type,e2->Type);
789 void EiC_swaptokens(token_t *e1, token_t * e2)
800 typedef struct list_t {
806 typdef struct llist_t {
811 static llist_t ** includes = NULL, ** included = NULL;
813 static int inllist(llist_t **list, char *fname)
815 /* returns -1 if not in list */
817 for(i=0;i<list->n,++i) {
818 if(fname == list->list[i]->fname == 0)
824 static list_t * add2list(list_t *list, char *fname)
826 list_t n = calloc(sizeof(list_t),1);
833 static void add2includes(char *file, char * includes)
835 int i = inlist(includes,file);
839 includes->list = realloc(includes->list,
840 (includes->n + 1) * sizeof(*includes->list));