#include #include "c.h" #include "expr.h" #include "gen.h" #include "cglbdec.h" /* *68000 C compiler * *Copyright 1984, 1985, 1986 Matthew Brandt. * all commercial rights reserved. * *This compiler is intended as an instructive tool for personal use. Any *use for profit without the written consent of the author is prohibited. * *This compiler may be distributed freely for non-commercial use as long *as this notice stays intact. Please forward any enhancements or questions *to: * *Matthew Brandt *Box 920337 *Norcross, Ga 30092 */ extern SYM *gsearch(); extern long intexpr(), stringlit(); doinit(sp) SYM *sp; { dseg(); /* initialize into data segment */ nl(); /* start a new line in object */ if(sp->storage_class == sc_static) put_label((long)(sp->value.i)); else gen_strlab(sp->name); if( lastst != assign) genstorage((int)(sp->tp->size)); else { getsym(); inittype(sp->tp); } endinit(); } int inittype(tp) TYP *tp; { int nbytes; switch(tp->type) { case bt_char: nbytes = initchar(); break; case bt_short: case bt_enum: nbytes = initshort(); break; case bt_pointer: if( tp->val_flag) nbytes = initarray(tp); else nbytes = initpointer(); break; case bt_long: nbytes = initlong(); break; case bt_struct: nbytes = initstruct(tp); break; default: error(ERR_NOINIT); nbytes = 0; } return nbytes; } initarray(tp) TYP *tp; { int nbytes; char *p; nbytes = 0; if( lastst == begin) { getsym(); /* skip past the brace */ while(lastst != end) { nbytes += inittype(tp->btp); if( lastst == comma) getsym(); else if( lastst != end) error(ERR_PUNCT); } getsym(); /* skip closing brace */ } else if( lastst == sconst && tp->btp->type == bt_char) { nbytes = strlen(laststr) + 1; p = laststr; while( *p ) genbyte(*p++); genbyte(0); getsym(); } else if( lastst != semicolon) error(ERR_ILLINIT); if( nbytes < tp->size) { genstorage( (int)(tp->size - nbytes)); nbytes = tp->size; } else if( tp->size != 0 && nbytes > tp->size) error(ERR_INITSIZE); /* too many initializers */ return nbytes; } initstruct(tp) TYP *tp; { SYM *sp; int nbytes; needpunc(begin); nbytes = 0; sp = tp->lst.head; /* start at top of symbol table */ while(sp != 0) { while(nbytes < sp->value.i) /* align properly */ nbytes += genbyte(0); nbytes += inittype(sp->tp); if( lastst == comma) getsym(); else if(lastst == end) break; else error(ERR_PUNCT); sp = sp->next; } if( nbytes < tp->size) genstorage( (int)(tp->size - nbytes)); needpunc(end); return tp->size; } initchar() { int i; i = (int)intexpr(); genbyte(i); return 1; } initshort() { genword((long)intexpr()); return 2; } initlong() { genlong((long)intexpr()); return 4; } initpointer() { SYM *sp; if(lastst == and) { /* address of a variable */ getsym(); if( lastst != id) error(ERR_IDEXPECT); else if( (sp = gsearch(lastid)) == 0) error(ERR_UNDEFINED); else { getsym(); if( lastst == plus || lastst == minus) genref(sp,(int)intexpr()); else genref(sp,0); if( sp->storage_class == sc_auto) error(ERR_NOINIT); } } else if(lastst == sconst) { gen_labref((int)stringlit(laststr)); getsym(); } else genlong((long)intexpr()); endinit(); return 4; /* pointers are 4 bytes long */ } endinit() { if( lastst != comma && lastst != semicolon && lastst != end) { error(ERR_PUNCT); while( lastst != comma && lastst != semicolon && lastst != end) getsym(); } }