void print_subprogram_head(subprogram_head_t * node, int spaces) { print_spaces(spaces); fprintf(stderr, "SUBPROGRAM HEAD:\n"); print_identifier(node->ident, spaces + SP_INDENT); print_parameter_list(node->params, spaces + SP_INDENT); print_type(node->type, spaces + SP_INDENT); }
/*----------------------------------------------- | generate_ir +---------------------------------------------*/ void generate_ir(struct ast *parse_tree) { struct decl *tdecl; struct function_def *funcdef; struct declarator *d; struct ast *decostat; char genstr[TMPSTRSZ]; struct symtabl *curr_symtab= global_top_level; struct irnode *irlist; char symtab_name[100]; /* initialize ircodenames +--------------------------*/ { ircodenames[0] = "UNINITIALIZED"; ircodenames[100]= "BEGINPROC"; ircodenames[101]= "LOADADDRESS"; ircodenames[102]= "LOADCONSTANT"; ircodenames[103]= "STOREWORDINDIRECT"; ircodenames[104]= "LOADWORDINDIRECT"; ircodenames[105]= "ENDPROC"; ircodenames[106]= "PRINTINT"; ircodenames[107]= "SYSCALL"; ircodenames[108]= "LOADWORD"; ircodenames[109]= "MIPSLABEL"; ircodenames[110]= "BRANCH_GT"; ircodenames[111]= "BRANCH_LT"; ircodenames[112]= "JUMP"; ircodenames[113]= "COMMENT"; ircodenames[114]= "ADD"; ircodenames[115]= "ADD1"; ircodenames[116]= "PRINTSTRING"; ircodenames[117]= "CREATE_STRINGVAR"; ircodenames[118]= "READINT"; ircodenames[119]= "BRANCH_GTE"; ircodenames[120]= "BRANCH_LTE"; ircodenames[121]= "BRANCH_EQ"; ircodenames[122]= "REMAINDER"; ircodenames[123]= "SUBTRACT"; ircodenames[124]= "SUB1"; ircodenames[125]= "FUNCTIONCALL"; }; /* initialize irlist_front and irlist. +---------------------------------------*/ irlist_front= emalloc(sizeof(struct irnode)); irlist_front->prev=NULL; irlist_front->next=NULL; irlist_front->sid= ++irnodenum; irlist= irlist_front; /* initialize label num, used to avoid label name | collisions. +------------------------------------------------*/ labelnum=0; /* Open IR output file +-------------------------*/ strcpy(irfname,"out.ir"); /* update later to create an IR file based on input filename. */ irout= fopen(irfname,"w+"); if(irout == NULL) { printf("Error opening IR output file: %s\n", irfname); } /* generate_ir() accepts the root of parse tree as its param. | The root of the parse tree is a *tld_list so we'll cast the param | into a *tld_list. +--------------------------------------------------------------------*/ struct tld_list *tldlist= (struct tld_list *)parse_tree; /* A tld_list has a series of tld nodes; each node pointing to either | a decl or a funcdef. We'll create and populate symtabs as We cycle | through all of the TLD's in a do-while loop. +---------------------------------------------------------------------*/ do { curr_symtab= global_top_level; /* always start with the global symtab */ /*--------------------------------------------+ | if TLD is a DECL +---------------------------------------------*/ if(tldlist->tld->datatype == DECL) { tdecl= (struct decl *)tldlist->tld->d; print_expr((struct ast *)tdecl,genstr); fprintf(irout,"# %s\n", genstr); clearstr(genstr); } /*--------------------------------------------+ | if TLD is a FUNCTION_DEFINITION +---------------------------------------------*/ if(tldlist->tld->datatype == FUNCTION_DEFINITION) { /* retrieve function definition */ struct function_def *funcdef= (struct function_def *)tldlist->tld->f; /* a function defintion is composed of a | fuction_defspec and a compound statement. | A compound statement has a decostat_list. +---------------------------------------------*/ struct function_defspec *fdspec= funcdef->fdspec; struct ast *cstmt= funcdef->cstmt; struct decostat_list *dlist; /* | fdspec contains the function declarator. +-------------------------------------------*/ struct declarator *d= fdspec->d; printf("\n\n\nDEBUG: generate_mips() encountered a function definition: %s\n", print_declarator_id(d)); /* print function return type */ fprintf(irout,"\n\n# %s ", print_type(fdspec->typespec)); /* Retrieve and print function name from this declarator, | considering that pointers may be present. Also grab | the parameter_list. +------------------------------------------------------------*/ struct parameter_list *plist; if(d->nodetype == POINTER_DECLARATOR) { while(d->next) { d= d->next; sprintf(&genstr[strlen(genstr)],"*"); } plist= d->plist; if(!d->id) { d= d->adeclarator; } } else { d= d->adeclarator; plist= fdspec->d->plist; } char *funcname= d->id; strcpy(symtab_name,funcname); strcat(symtab_name,"_funcdef"); /* Generate IR node for function +----------------------------------*/ irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } if(irnodenum != 1) { irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; } printf("\tDEBUG: current irnode sid: %d\n", irlist->sid); irlist->ircode= BEGINPROC; irlist->symptr= fdspec->d; irlist->sid= (irnodenum == 1) ? 1 : ++irnodenum; sprintf(&genstr[strlen(genstr)]," %s(", funcname); fprintf(irout,"%s", genstr); clearstr(genstr); /* print parameter list +-------------------------*/ print_parameter_list(plist,genstr); sprintf(&genstr[strlen(genstr)],")"); sprintf(&genstr[strlen(genstr)],"\n"); fprintf(irout,"%s",genstr); clearstr(genstr); /* print IR for entering function +----------------------------------*/ statement_begin_sid= irnodenum + 1; print_irnode_sids(irlist->sid,irlist->sid); /* DEBUG */ fprintf(irout,"\n\n"); /* Generate IR for compound statement block +-------------------------------------------*/ compound_to_ir(cstmt); /* Generate endproc node for function. +---------------------------------------*/ printf("DEBUG: about to add ENDPROC node for function '%s'\n", print_declarator_id(irlist->symptr)); irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= ENDPROC; irlist->symptr= fdspec->d; print_irnode_sids(irlist->sid,irlist->sid); /* DEBUG */ } }while( (tldlist= tldlist->next) != NULL ); fclose(irout); printf("EXITING\n"); print_irnodes(); }