/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ int ParseFunction(SYM *sp) { int poffset, i; int oldglobal; SYM *sp1, *sp2; Statement *stmt; if (sp==NULL) { fatal("Compiler error: ParseFunction: SYM is NULL\r\n"); } sp->stkname = stkname; if (verbose) printf("Parsing function: %s\r\n", sp->name); oldglobal = global_flag; global_flag = 0; poffset = 24; /* size of return block */ nparms = 0; iflevel = 0; // There could be unnamed parameters in a function prototype. if(lastst == id || 1) { /* declare parameters */ //while(lastst == id) { // names[nparms++] = litlate(lastid); // NextToken(); // if( lastst == comma) // NextToken(); // else // break; // } //needpunc(closepa); // dodecl(sc_member); /* declare parameters */ sp->parms = (SYM *)NULL; ParseParameterDeclarations(1); for(i = 0;i < nparms;++i) { if( (sp1 = search(names[i],&lsyms)) == NULL) sp1 = makeint(names[i]); //if( sp1->tp->size < 8 ) //{ // sp1->value.i = poffset;// + (8 - sp1->tp->size); // poffset += 8; //} //else //{ // sp1->value.i = poffset; // poffset += sp1->tp->size; //} sp1->value.i = poffset; // Check for aggregate types passed as parameters. Structs // and unions use the type size. // if (sp1->tp->type==bt_struct || sp1->tp->type==bt_union) { poffset += round8(sp1->tp->size); if (round8(sp1->tp->size) > 8) sp->IsLeaf = FALSE; // } // else // poffset += 8; //sp1->value.i = poffset; //poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = (SYM *)NULL; // record parameter list if (sp->parms == (SYM *)NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } } // Process extra hidden parameter if (sp->tp->btp->type==bt_struct || sp->tp->btp->type==bt_union) { sp1 = makeint(litlate("_pHiddenStructPtr")); sp1->value.i = poffset; poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = (SYM *)NULL; // record parameter list if (sp->parms == (SYM *)NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } nparms++; } } if (lastst == closepa) NextToken(); if (sp->tp->type == bt_pointer) { if (lastst==assign) { doinit(sp); } sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ global_flag = oldglobal; return 1; } if (lastst == semicolon) { // Function prototype sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ goto j1; } else if(lastst != begin) { // NextToken(); ParseParameterDeclarations(2); // for old-style parameter list //needpunc(closepa); if (lastst==semicolon) { sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ } // Check for end of function parameter list. else if (funcdecl==2 && lastst==closepa) { ; } else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nparms; stmt = ParseFunctionBody(sp); funcbottom(stmt); } } // error(ERR_BLOCK); else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nparms; stmt = ParseFunctionBody(sp); funcbottom(stmt); } j1: global_flag = oldglobal; return 0; }
/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ int ParseFunction(SYM *sp) { int i; SYM *sp1, *sp2, *pl, *osp; Statement *stmt; int nump; __int16 *ta; int nn; std::string name; dfs.puts("<ParseFunction>\n"); isFuncBody = true; if (sp==NULL) { fatal("Compiler error: ParseFunction: SYM is NULL\r\n"); } dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); if (sp->parent) dfs.printf("Parent: %s\n", (char *)sp->GetParentPtr()->name->c_str()); dfs.printf("Parsing function: %s\n", (char *)sp->name->c_str()); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); sp->stkname = stkname; if (verbose) printf("Parsing function: %s\r\n", (char *)sp->name->c_str()); nump = nparms; iflevel = 0; // There could be unnamed parameters in a function prototype. dfs.printf("A"); // declare parameters // Building a parameter list here allows both styles of parameter // declarations. the original 'C' style is parsed here. Originally the // parameter types appeared as list after the parenthesis and before the // function body. sp->BuildParameterList(&nump); dfs.printf("B"); sp->mangledName = sp->BuildSignature(1); // build against parameters // If the symbol has a parent then it must be a class // method. Search the parent table(s) for matching // signatures. osp = sp; name = *sp->name; if (sp->parent) { SYM *sp2; dfs.printf("PArent Class:%s|",(char *)sp->GetParentPtr()->name->c_str()); sp2 = sp->GetParentPtr()->Find(name); if (sp2) { dfs.printf("Found at least inexact match"); sp2 = sp->FindExactMatch(TABLE::matchno); } if (sp2 == nullptr) error(ERR_METHOD_NOTFOUND); else sp = sp2; sp->PrintParameterTypes(); } else { if (gsyms[0].Find(name)) { sp = TABLE::match[TABLE::matchno-1]; } } dfs.printf("C"); if (sp != osp) { dfs.printf("ParseFunction: sp changed\n"); osp->params.CopyTo(&sp->params); osp->proto.CopyTo(&sp->proto); sp->derivitives = osp->derivitives; sp->mangledName = osp->mangledName; // Should free osp here. It's not needed anymore } if (lastst == closepa) { NextToken(); } dfs.printf("D"); if (sp->tp->type == bt_pointer) { if (lastst==assign) { doinit(sp); } sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nump; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ return 1; } dfs.printf("E"); if (lastst == semicolon) { // Function prototype dfs.printf("e"); sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; sp->NumParms = nump; sp->params.MoveTo(&sp->proto); isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ goto j1; } else if(lastst != begin) { dfs.printf("F"); // NextToken(); ParameterDeclaration::Parse(2); // for old-style parameter list //needpunc(closepa); if (lastst==semicolon) { sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; sp->NumParms = nump; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ } // Check for end of function parameter list. else if (funcdecl==2 && lastst==closepa) { ; } else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nump; stmt = ParseFunctionBody(sp); funcbottom(stmt); } } // error(ERR_BLOCK); else { dfs.printf("G"); sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nump; stmt = ParseFunctionBody(sp); funcbottom(stmt); } j1: dfs.printf("F"); dfs.puts("</ParseFunction>\n"); return 0; }
/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ void ParseFunction(SYM *sp) { int poffset, i; int oldglobal; SYM *sp1, *sp2, *makeint(); oldglobal = global_flag; global_flag = 0; poffset = 24; /* size of return block */ nparms = 0; if(lastst == id || 1) { /* declare parameters */ //while(lastst == id) { // names[nparms++] = litlate(lastid); // NextToken(); // if( lastst == comma) // NextToken(); // else // break; // } //needpunc(closepa); // dodecl(sc_member); /* declare parameters */ sp->parms = NULL; ParseParameterDeclarations(1); for(i = 0;i < nparms;++i) { if( (sp1 = search(names[i],&lsyms)) == NULL) sp1 = makeint(names[i]); //if( sp1->tp->size < 8 ) //{ // sp1->value.i = poffset;// + (8 - sp1->tp->size); // poffset += 8; //} //else //{ // sp1->value.i = poffset; // poffset += sp1->tp->size; //} sp1->value.i = poffset; poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = NULL; // record parameter list if (sp->parms == NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } } } if (lastst == closepa) NextToken(); if (lastst == semicolon) { // Function prototype sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; isPascal = FALSE; isOscall = FALSE; isInterrupt = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ } else if(lastst != begin) { NextToken(); ParseParameterDeclarations(2); sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; ParseFunctionBody(sp); funcbottom(); } // error(ERR_BLOCK); else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; ParseFunctionBody(sp); funcbottom(); } global_flag = oldglobal; }