void ParseEnumDeclaration(TABLE *table) { SYM *sp; TYP *tp; if( lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { sp = allocSYM(); sp->tp = allocTYP(); sp->tp->type = bt_enum; sp->tp->size = 2; sp->tp->lst.head = 0; sp->tp->btp = 0; sp->storage_class = sc_type; sp->name = litlate(lastid); sp->tp->sname = sp->name; NextToken(); if( lastst != begin) error(ERR_INCOMPLETE); else { insert(sp,&tagtable); NextToken(); ParseEnumerationList(table); } } else NextToken(); head = sp->tp; } else { tp = allocTYP(); // fix here tp->type = bt_enum; tp->size = 2; if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseEnumerationList(table); } head = tp; } }
TYP *maketype(int bt, int siz) { TYP *tp; tp = allocTYP(); tp->val_flag = 0; tp->size = siz; tp->type = bt; tp->typeno = bt; tp->sname = 0; tp->lst.head = 0; return tp; }
TYP *maketype(int bt, int siz) { TYP *tp; tp = allocTYP(); tp->val_flag = 0; tp->size = siz; tp->type = bt; tp->typeno = bt; tp->sname = 0; tp->lst.head = 0; tp->isUnsigned = FALSE; tp->isVolatile = FALSE; tp->isConst = FALSE; return tp; }
SYM *makeint(char *name) { SYM *sp; TYP *tp; sp = allocSYM(); tp = allocTYP(); tp->type = bt_long; tp->size = 8; tp->btp = 0; tp->lst.head = 0; tp->sname = 0; sp->name = name; sp->storage_class = sc_auto; sp->tp = tp; sp->IsPrototype = FALSE; insert(sp,&lsyms); return sp; }
void ParseEnumDeclaration(TABLE *table) { SYM *sp; TYP *tp; if( lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { sp = allocSYM(); sp->tp = TYP::Make(bt_enum,1); sp->storage_class = sc_type; sp->SetName(*(new std::string(lastid))); sp->tp->sname = new std::string(*sp->name); NextToken(); if( lastst != begin) error(ERR_INCOMPLETE); else { tagtable.insert(sp); NextToken(); ParseEnumerationList(table); } } else NextToken(); head = sp->tp; } else { tp = allocTYP(); // fix here tp->type = bt_enum; tp->size = 1; if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseEnumerationList(table); } head = tp; } }
int ParseStructDeclaration(int ztype) { SYM *sp; TYP *tp; int gblflag; int ret; int psd; ENODE nd; ENODE *pnd = &nd; psd = isStructDecl; isStructDecl = TRUE; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; if(lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { // If we encounted an unknown struct in a parameter list, we want // it to go into the global memory pool, not a local one. if (parsingParameterList) { gblflag = global_flag; global_flag++; sp = allocSYM(); sp->name = litlate(lastid); global_flag = gblflag; } else { sp = allocSYM(); sp->name = litlate(lastid); } sp->tp = allocTYP(); sp->tp->type = ztype; sp->tp->typeno = typeno++; sp->tp->lst.head = 0; sp->storage_class = sc_type; sp->tp->sname = sp->name; sp->tp->alignment = 0; NextToken(); if (lastst == kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { ret = 1; insert(sp,&tagtable); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { insert(sp,&tagtable); } else if(lastst != begin) error(ERR_INCOMPLETE); else { insert(sp,&tagtable); NextToken(); ParseStructMembers(sp->tp,ztype); } } else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); ParseStructMembers(sp->tp,ztype); } } head = sp->tp; } else { tp = allocTYP(); tp->type = ztype; tp->sname = 0; tp->lst.head = 0; if (lastst==kw_align) { NextToken(); tp->alignment = GetIntegerExpression(&pnd); } if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseStructMembers(tp,ztype); } head = tp; } isStructDecl = psd; return ret; }
/* * process ParseSpecifierarations of the form: * * <type> <ParseSpecifier>, <ParseSpecifier>...; * * leaves the ParseSpecifierarations in the symbol table pointed to by * table and returns the number of bytes declared. al is the * allocation type to assign, ilc is the initial location * counter. if al is sc_member then no initialization will * be processed. ztype should be bt_struct for normal and in * structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations. */ int declare(TABLE *table,int al,int ilc,int ztype) { SYM *sp, *sp1, *sp2; TYP *dhead; char stnm[200]; static long old_nbytes; int nbytes; nbytes = 0; ParseSpecifier(table); dhead = head; for(;;) { declid = 0; bit_width = -1; ParseDeclarationPrefix(ztype==bt_union); if( declid != 0) { /* otherwise just struct tag... */ sp = allocSYM(); sp->name = declid; sp->storage_class = al; if (bit_width > 0 && bit_offset > 0) { // share the storage word with the previously defined field nbytes = old_nbytes - ilc; } old_nbytes = ilc + nbytes; if (al != sc_member) { // sp->isTypedef = isTypedef; if (isTypedef) sp->storage_class = sc_typedef; isTypedef = FALSE; } while( (ilc + nbytes) % alignment(head)) { if( al != sc_member && al != sc_external && al != sc_auto) { dseg(); GenerateByte(0); } ++nbytes; } if( al == sc_static) { sp->value.i = nextlabel++; } else if( ztype == bt_union) sp->value.i = ilc; else if( al != sc_auto ) sp->value.i = ilc + nbytes; else sp->value.i = -(ilc + nbytes + head->size); if (bit_width == -1) sp->tp = head; else { sp->tp = allocTYP(); *(sp->tp) = *head; sp->tp->type = bt_bitfield; sp->tp->size = head->size;//tp_int.size; sp->tp->bit_width = bit_width; sp->tp->bit_offset = bit_offset; } if( (sp->tp->type == bt_func) && sp->storage_class == sc_global ) sp->storage_class = sc_external; if(ztype == bt_union) nbytes = imax(nbytes,sp->tp->size); else if(al != sc_external) nbytes += sp->tp->size; if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func ) { sp1->tp = sp->tp; sp1->storage_class = sp->storage_class; // sp1->value.i = sp->value.i; sp1->IsPrototype = sp->IsPrototype; sp = sp1; } else { sp2 = search(sp->name,table); if (sp2 == NULL) insert(sp,table); else { if (funcdecl==2) sp2->tp = sp->tp; //else if (!sp2->IsPrototype) // insert(sp,table); } } if( sp->tp->type == bt_ifunc) { /* function body follows */ ParseFunction(sp); return nbytes; } if( (al == sc_global || al == sc_static) && sp->tp->type != bt_func && sp->storage_class!=sc_typedef) doinit(sp); } if (funcdecl==TRUE) { if (lastst==comma || lastst==semicolon) break; if (lastst==closepa) goto xit1; } else if (catchdecl==TRUE) { if (lastst==closepa) goto xit1; } else if (lastst == semicolon) break; needpunc(comma); if(declbegin(lastst) == 0) break; head = dhead; } NextToken(); xit1: return nbytes; }
void Compiler::AddStandardTypes() { TYP *p, *pchar, *pint; p = TYP::Make(bt_long,8); stdint = *p; pint = p; p = TYP::Make(bt_long,8); p->isUnsigned = true; stduint = *p; p = TYP::Make(bt_long,8); stdlong = *p; p = TYP::Make(bt_long,8); p->isUnsigned = true; stdulong = *p; p = TYP::Make(bt_short,4); stdshort = *p; p = TYP::Make(bt_short,4); p->isUnsigned = true; stdushort = *p; p = TYP::Make(bt_char,2); stdchar = *p; pchar = p; p = TYP::Make(bt_char,2); p->isUnsigned = true; stduchar = *p; p = allocTYP(); p->type = bt_byte; p->typeno = bt_byte; p->size = 1; p->size2 = 1; p->bit_width = -1; stdbyte = *p; p = allocTYP(); p->type = bt_byte; p->typeno = bt_byte; p->size = 1; p->size2 = 1; p->isUnsigned = true; p->bit_width = -1; stdubyte = *p; p = allocTYP(); p->type = bt_pointer; p->typeno = bt_pointer; p->val_flag = 1; p->size = 1; p->size2 = 1; p->btp = pchar->GetIndex(); p->bit_width = -1; stdstring = *p; p = allocTYP(); p->type = bt_double; p->typeno = bt_double; p->size = 8; p->size2 = 8; p->bit_width = -1; stddbl = *p; stddouble = *p; p = allocTYP(); p->type = bt_float; p->typeno = bt_float; p->size = 4; p->size2 = 4; p->bit_width = -1; stdflt = *p; p = TYP::Make(bt_func,0); p->btp = pint->GetIndex(); stdfunc = *p; p = allocTYP(); p->type = bt_exception; p->typeno = bt_exception; p->size = 8; p->size2 = 8; p->isUnsigned = true; p->bit_width = -1; stdexception = *p; p = allocTYP(); p->type = bt_long; p->typeno = bt_long; p->val_flag = 1; p->size = 8; p->size2 = 8; p->bit_width = -1; stdconst = *p; }
/* * process declarations of the form: * * <type> <specifier>, <specifier>...; * * leaves the declarations in the symbol table pointed to by * table and returns the number of bytes declared. al is the * allocation type to assign, ilc is the initial location * counter. if al is sc_member then no initialization will * be processed. ztype should be bt_struct for normal and in * structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations. */ int declare(TABLE *table,int al,int ilc,int ztype) { SYM *sp, *sp1, *sp2; TYP *dhead, *tp1, *tp2; ENODE *ep1, *ep2; char stnm[200]; int op; int fd; int fn_doneinit = 0; int bcnt; static long old_nbytes; int nbytes; nbytes = 0; if (ParseSpecifier(table)) return nbytes; dhead = head; for(;;) { declid = (char *)NULL; bit_width = -1; ParseDeclarationPrefix(ztype==bt_union); // If a function declaration is taking place and just the type is // specified without a parameter name, assign an internal compiler // generated name. if (funcdecl>0 && funcdecl != 10 && declid==(char *)NULL) { sprintf(lastid, "_p%d", nparms); declid = litlate(lastid); names[nparms++] = declid; missingArgumentName = TRUE; } if( declid != NULL) { /* otherwise just struct tag... */ sp = allocSYM(); sp->name = declid; sp->storage_class = al; sp->isConst = isConst; if (bit_width > 0 && bit_offset > 0) { // share the storage word with the previously defined field nbytes = old_nbytes - ilc; } old_nbytes = ilc + nbytes; if (al != sc_member) { // sp->isTypedef = isTypedef; if (isTypedef) sp->storage_class = sc_typedef; isTypedef = FALSE; } if ((ilc + nbytes) % roundAlignment(head)) { if (al==sc_thread) tseg(); else dseg(); } bcnt = 0; while( (ilc + nbytes) % roundAlignment(head)) { ++nbytes; bcnt++; } if( al != sc_member && al != sc_external && al != sc_auto) { if (bcnt > 0) genstorage(bcnt); } // Set the struct member storage offset. if( al == sc_static || al==sc_thread) { sp->value.i = nextlabel++; } else if( ztype == bt_union) sp->value.i = ilc; else if( al != sc_auto ) sp->value.i = ilc + nbytes; // Auto variables are referenced negative to the base pointer // Structs need to be aligned on the boundary of the largest // struct element. If a struct is all chars this will be 2. // If a struct contains a pointer this will be 8. It has to // be the worst case alignment. else { sp->value.i = -(ilc + nbytes + roundSize(head)); } if (bit_width == -1) sp->tp = head; else { sp->tp = allocTYP(); *(sp->tp) = *head; sp->tp->type = bt_bitfield; sp->tp->size = head->size;//tp_int.size; sp->tp->bit_width = bit_width; sp->tp->bit_offset = bit_offset; } if (isConst) sp->tp->isConst = TRUE; if((sp->tp->type == bt_func) && sp->storage_class == sc_global ) sp->storage_class = sc_external; // Increase the storage allocation by the type size. if(ztype == bt_union) nbytes = imax(nbytes,roundSize(sp->tp)); else if(al != sc_external) { // If a pointer to a function is defined in a struct. if (isStructDecl && (sp->tp->type==bt_func || sp->tp->type==bt_ifunc)) nbytes += 8; else nbytes += roundSize(sp->tp); } if (sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func ) { sp1->tp = sp->tp; sp1->storage_class = sp->storage_class; sp1->value.i = sp->value.i; sp1->IsPrototype = sp->IsPrototype; sp = sp1; } else { sp2 = search(sp->name,table); if (sp2 == NULL) insert(sp,table); else { if (funcdecl==2) sp2->tp = sp->tp; //else if (!sp2->IsPrototype) // insert(sp,table); } } if (needParseFunction) { needParseFunction = FALSE; fn_doneinit = ParseFunction(sp); if (sp->tp->type != bt_pointer) return nbytes; } // if(sp->tp->type == bt_ifunc) { /* function body follows */ // ParseFunction(sp); // return nbytes; // } if( (al == sc_global || al == sc_static || al==sc_thread) && !fn_doneinit && sp->tp->type != bt_func && sp->tp->type != bt_ifunc && sp->storage_class!=sc_typedef) doinit(sp); } if (funcdecl>0) { if (lastst==comma || lastst==semicolon) break; if (lastst==closepa) goto xit1; } else if (catchdecl==TRUE) { if (lastst==closepa) goto xit1; } else if (lastst == semicolon) break; else if (lastst == assign) { tp1 = nameref(&ep1); op = en_assign; // NextToken(); tp2 = asnop(&ep2); if( tp2 == 0 || !IsLValue(ep1) ) error(ERR_LVALUE); else { tp1 = forcefit(&ep1,tp1,&ep2,tp2); ep1 = makenode(op,ep1,ep2); } sp->initexp = ep1; if (lastst==semicolon) break; } needpunc(comma); if(declbegin(lastst) == 0) break; head = dhead; } NextToken(); xit1: return nbytes; }
int StructDeclaration::Parse(int ztype) { SYM *sp; TYP *tp; int ret; int psd; ENODE nd; ENODE *pnd = &nd; sp = nullptr; psd = isStructDecl; isStructDecl++; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; if(lastst == id) { if((sp = tagtable.Find(lastid,false)) == NULL) { sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->tp = allocTYP(); sp->tp->type = (e_bt)ztype; sp->tp->typeno = typeno++; sp->tp->lst.Clear(); sp->storage_class = sc_type; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = 0; NextToken(); if (lastst == kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { ret = 1; tagtable.insert(sp); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { tagtable.insert(sp); } else if(lastst != begin) error(ERR_INCOMPLETE); else { tagtable.insert(sp); NextToken(); ParseMembers(sp, sp->tp,ztype); } } // Else it is a known structure else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); ParseMembers(sp,sp->tp,ztype); } } head = sp->tp; } // Else there was no tag identifier else { tp = allocTYP(); tp->type = (e_bt)ztype; tp->typeno = typeno++; tp->sname = new std::string(""); if (lastst==kw_align) { NextToken(); tp->alignment = GetIntegerExpression(&pnd); } if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseMembers(sp,tp,ztype); } head = tp; } isStructDecl = psd; return ret; }
// Class declarations have the form: // // class identifier [: base class] // { // class members // } // // We could also have a forward reference: // // class identifier; // // Or a pointer to a class: // // class *identifier; // int ClassDeclaration::Parse(int ztype) { SYM *sp, *bcsp; int ret; int psd; ENODE nd; ENODE *pnd = &nd; char *idsave; int alignment; SYM *cls; cls = currentClass; dfs.puts("<ParseClassDeclaration>\n"); alignment = 0; isTypedef = TRUE; NextToken(); if (lastst != id) { error(ERR_SYNTAX); goto lxit; } // ws = allocSYM(); idsave = my_strdup(lastid); // ws->name = idsave; // ws->storage_class = sc_typedef; // Passes lastid onto struct parsing psd = isStructDecl; isStructDecl++; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; dfs.printf("---------------------------------"); dfs.printf("Class decl:%s\n", lastid); dfs.printf("---------------------------------"); if((sp = tagtable.Find(std::string(lastid),false)) == NULL) { sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->tp = nullptr; NextToken(); dfs.printf("A"); if (lastst == kw_align) { NextToken(); alignment = GetIntegerExpression(&pnd); } else alignment = AL_STRUCT; // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { dfs.printf("B"); ret = 1; printf("classdecl insert1\r\n"); tagtable.insert(sp); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { dfs.printf("C"); printf("classdecl insert2\r\n"); tagtable.insert(sp); } else if (lastst==colon) { dfs.printf("D"); NextToken(); // Absorb and ignore public/private keywords if (lastst == kw_public || lastst==kw_private) NextToken(); if (lastst != id) { error(ERR_SYNTAX); goto lxit; } bcsp = tagtable.Find(std::string(lastid),false); if (bcsp==nullptr) { error(ERR_UNDEFINED); goto lxit; } dfs.printf("E"); // Copy the type chain of base class //sp->tp = TYP::Copy(bcsp->tp); // Start off at the size of the base. sp->tp = allocTYP(); sp->tp->lst.SetBase(bcsp->GetIndex()); dfs.printf("Set base class: %d\n", sp->tp->lst.base); sp->tp->size = bcsp->tp->size; sp->tp->type = (e_bt)ztype; sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->storage_class = sc_type; NextToken(); if (lastst != begin) { error(ERR_INCOMPLETE); goto lxit; } /* sp->tp = allocTYP(); sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->tp->type = (e_bt)ztype; sp->tp->lst.SetBase(bcsp->GetIndex()); sp->storage_class = sc_type; */ tagtable.insert(sp); NextToken(); currentClass = sp; dfs.printf("f"); ParseMembers(sp,ztype); dfs.printf("G"); } else if(lastst != begin) error(ERR_INCOMPLETE); else { if (sp->tp == nullptr) { sp->tp = allocTYP(); } sp->tp->size = 0; sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->tp->type = (e_bt)ztype; sp->tp->lst.SetBase(0); sp->storage_class = sc_type; tagtable.insert(sp); NextToken(); currentClass = sp; ParseMembers(sp,ztype); } } // Else the class was found in the tag table. else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); currentClass = sp; ParseMembers(sp,ztype); } } head = sp->tp; isStructDecl = psd; lxit: isTypedef = TRUE; if (classname) delete classname; classname = new std::string(idsave); currentClass = cls; dfs.puts("</ParseClassDeclaration>\n"); return ret; }