int main( int argc, char * argv[] ){ int i; char pgm[120]; /* source code file name */ if (argc != 3){ fprintf(stderr,"usage: %s <input> <output>\n",argv[0]); exit(1); } strcpy(pgm,argv[1]); if (strchr (pgm, '.') == NULL) strcat(pgm,".pas"); source = fopen(pgm,"r"); if (source == NULL){ fprintf(stderr,"File %s not found\n",pgm); exit(1); } yyin = source; listing = stdout; /* send listing to screen */ fprintf(listing,"\nPASCAL COMPILATION: %s\n",pgm); //scan begin #ifdef SCAN_DEBUG yy_flex_debug = 1; #endif #ifdef PARSE_DEBUG yydebug = 1; #endif auto syntaxTree = dynamic_cast<Program_Node*>(do_parse()); st->global = 1; syntaxTree->build_symbol_table(""); // puts("=========symtab debug============"); // for (i=0; i<SIZE; i++) { // if (st->units[i].use == 1) { // puts("======================="); // printf("name: %s", st->units[i].name.c_str()); puts(""); // printf("type: %s", st->units[i].type.c_str()); puts(""); // printf("array_start: %d", st->units[i].array_start); puts(""); // printf("volumn: %d", st->units[i].volumn); puts(""); // printf("isrecord: %d", st->units[i].volumn); puts(""); // printf("volumn: %d", st->units[i].volumn); puts(""); // printf("printer: %p\n", &(st->units[i])); // } // } // puts("=========symtab debug end========"); /* code generation */ CodeGenerator* cg = new CodeGenerator(syntaxTree, argv[2]); cg->generate(); fclose(source); return 0; }
void isetprofile() { nialptr z; int tv, oldprofile = profile; /* old value of profiling switch */ z = apop(); if (kind(z) == inttype) tv = intval(z); else if (kind(z) == booltype) tv = boolval(z); else { buildfault("invalid arg to setprofile"); return; } if (tv && !oldprofile) { /* turning on profiling */ profile = true; if (newprofile) { inittime(); calltree = make_node(); current_node = calltree; /* initialize first node */ set_opid(calltree, 0); /* doesn't correspond to a defn */ set_start_time(calltree, profile_time()); /* nprintf(OF_DEBUG,"start time for call tree%f\n",calltree->start_time); */ swplace = 0; #ifdef OLD_BUILD_SYMBOL_TABLE build_symbol_table(); #endif newprofile = false; } } else if (oldprofile != false) { double lasttime = profile_time(); profile = false; if (current_node != calltree) { exit_cover(NC_PROFILE_SYNCH_W); } set_end_time(calltree, lasttime); add_time(calltree); } apush(createbool(oldprofile)); }
int main(int argc, char* argv[]) { if (argc != 2) { printf("Bad argument! Just give me a filename of a compiled assembly program.\n"); return -EINVAL; } enable_udiv = 1; FILE* program; if (!(program = fopen(argv[1], "r"))) { printf("Bad argument! File not found.\n"); return -EINVAL; } build_symbol_table(argv[1]); pc = 0x3000; running = 1; read_program(program); int ch; initialize(); while(ch != KEY_F(1)) { ch = getch(); switch (ch) { case KEY_F(2): reset_program(program); break; case KEY_F(3): dbgwin_state = 1; break; case KEY_F(4): break; case KEY_F(5): step_forward(); break; case KEY_F(6): run_program(); break; case KEY_F(7): memwin_state = (memwin_state == 2 ? 0 : 2); mem_cursor = mem_index; break; case KEY_F(8): dbgwin_state = 2; break; case KEY_UP: if (memwin_state == 2) mem_cursor--; break; case KEY_DOWN: if (memwin_state == 2) mem_cursor++; break; case KEY_NPAGE: if (memwin_state == 2) mem_cursor += (LINES-DEBUGWIN_HEIGHT); break; case KEY_PPAGE: if (memwin_state == 2) mem_cursor -= (LINES-DEBUGWIN_HEIGHT); break; case 0xA: if (memwin_state ==2) brk[(unsigned short)mem_cursor] ^= 1; break; } refreshall(); } quit: curs_set(1); endwin(); return 0; }
void iprofiletable() { nialptr result; /* result to be returned */ int c1, c2; int num_funs = 0; /* total number of used functions */ int pos = 0; /* current count of used fucntions */ if (newprofile) { buildfault("no profile available"); return; } #ifndef OLD_BUILD_SYMBOL_TABLE if (symtab) free_symtab(); symtab = NULL; build_symbol_table(); #endif /* If profiling is still on, then turn it off */ if (profile == true) { apush(createbool(0)); isetprofile(); apop(); } /* traverse the call tree placing nodes in the symbol table entries */ if (!traversed) { traverse_tree(calltree); traversed = true; } /* count the number of called functions so we know how big to make the container array. Funcitons in the symbol table that are not called at all are excluded */ for (c1 = 0; c1 < symtabsize; c1++) if ((symtab[c1]->num_locs > 0) || (symtab[c1]->num_rcalls > 0)) num_funs++; /* create the outer most container to hold the table */ result = new_create_array(atype, 1, 0, &num_funs); for (c1 = 0; c1 < symtabsize; c1++) { if ((symtab[c1]->num_locs > 0) || (symtab[c1]->num_rcalls > 0)) { double totaloptime = 0; int totalopcalls = 0; int totalropcalls; int len = 5; /* create the table entry */ nialptr table_entry = new_create_array(atype, 1, 0, &len); /* store it in the outer table */ store_array(result, pos, table_entry); for (c2 = 0; c2 < symtab[c1]->num_locs; c2++) { if (symtab[c1]->id != symtab[c1]->locations[c2]->parent->opid) /* omit adding calls and time for direct recursions */ { totaloptime += symtab[c1]->locations[c2]->total_time; totalopcalls += symtab[c1]->locations[c2]->total_calls; } } totalropcalls = symtab[c1]->num_rcalls; /* fill in the cells in the table entry */ store_array(table_entry, 0, makephrase(symtab[c1]->name)); store_array(table_entry, 1, createint(totalopcalls)); store_array(table_entry, 2, createint(totalropcalls)); store_array(table_entry, 3, createreal(totaloptime)); { struct node **chlist; nialptr child_array; int c, used, cpos = 0; int children = 0; chlist = merge_children(symtab[c1], &used); for (c = 0; c < used; c++) if (chlist[c]->opid != symtab[c1]->id) /* recursions only counted */ children++; child_array = new_create_array(atype, 1, 0, &children); store_array(table_entry, 4, child_array); for (c = 0; c < used; c++) { nialptr child_entry; int len = 5; if (chlist[c]->opid == symtab[c1]->id) /* recursions only counted */ break; /* create each child entry and place it in the child list */ child_entry = new_create_array(atype, 1, 0, &len); store_array(child_array, cpos, child_entry); /* fill in the information about the child entry */ store_array(child_entry, 0, makephrase(num_to_name(chlist[c]->opid))); store_array(child_entry, 1, createint(chlist[c]->total_calls)); store_array(child_entry, 2, createint(0)); store_array(child_entry, 3, createreal(chlist[c]->total_time)); store_array(child_entry, 4, Null); cpos++; } free_merge_list(chlist, used); } } pos++; } apush(result); }
void iprofile() { char sbuf[1000]; nialptr z; FILE *prf = STDOUT; int c1, c2; int i; double real_total_time = 0; double profile_duration_time; int NMWIDTH = 30; /* grab the argument */ z = apop(); if (newprofile) { buildfault("no profile available"); freeup(z); return; } /* handle input argument */ if (kind(z) == phrasetype) { apush(z); istring(); z = apop(); } if (tally(z) != 0) { if (!istext(z)) { buildfault("profile file name arg is not text"); freeup(z); return; } else { prf = openfile(pfirstchar(z), 'w', 't'); if (prf == OPENFAILED) { buildfault("unable to open specified file to write profile to"); freeup(z); return; /* exit_cover(NC_PROFILE_FILE_W); removed Nov 22/95 because this * cleared profile information */ } } } freeup(z); /* If profiling is still on, then turn it off */ if (profile == true) { apush(createbool(0)); isetprofile(); apop(); } #ifndef OLD_BUILD_SYMBOL_TABLE if (symtab) free_symtab(); symtab = NULL; build_symbol_table(); #endif profile_duration_time = (calltree->total_time); for (i = 0;i <calltree->num_children;i++) { real_total_time += calltree->children[i]->total_time; } /* traverse the call tree placing nodes in the symbol table entries */ if (!traversed) { traverse_tree(calltree); traversed = true; } /* generate the output and place it in the output file or stdout */ /* if a filename has been specified then write that out */ if (tally(z)) { sprintf(sbuf,"Profile output file: \"%s\"\n\n",pfirstchar(z)); writechars(prf, sbuf, strlen(sbuf), false); } sprintf(sbuf, "\nTotal execution time of profile session: \t%f\n", profile_duration_time); writechars(prf, sbuf, strlen(sbuf), false); sprintf(sbuf, "Total execution time in top level calls: \t%f\n\n",real_total_time); writechars(prf, sbuf, strlen(sbuf), false); /* header line for all data */ sprintf(sbuf, "op name[.tr arg] calls[rec] "); writechars(prf, sbuf, strlen(sbuf), false); sprintf(sbuf, "time time/call %% time\n"); writechars(prf, sbuf, strlen(sbuf), false); for (c1 = 0; c1 < symtabsize; c1++) { if ((symtab[c1]->num_locs > 0) || (symtab[c1]->num_rcalls > 0)) { double totaloptime = 0; int totalopcalls = 0; int totalropcalls; char *tmp; for (c2 = 0; c2 < symtab[c1]->num_locs; c2++) { if (symtab[c1]->id != symtab[c1]->locations[c2]->parent->opid) /* omit adding calls and time for direct recursions */ { totaloptime += symtab[c1]->locations[c2]->total_time; totalopcalls += symtab[c1]->locations[c2]->total_calls; } } totalropcalls = symtab[c1]->num_rcalls; sprintf(sbuf, "%s%5d", (tmp = padright(NMWIDTH, (char *) symtab[c1]->name)), totalopcalls); writechars(prf, sbuf, strlen(sbuf), false); free(tmp); if (totalropcalls != 0) { sprintf(sbuf, "[%5d]", totalropcalls); writechars(prf, sbuf, strlen(sbuf), false); } else { sprintf(sbuf, " "); writechars(prf, sbuf, strlen(sbuf), false); } /* details for each definition */ sprintf(sbuf, "%8.2f %8.4f %8.1f%s\n", totaloptime, (totaloptime / totalopcalls), 100 * (totaloptime / real_total_time), ((symtab[c1]->toplevel_call == true)?"<":"")); writechars(prf, sbuf, strlen(sbuf), false); { struct node **chlist; int c, used; char tname[40]; chlist = merge_children(symtab[c1], &used); for (c = 0; c < used; c++) { char *tmp; if (chlist[c]->opid == symtab[c1]->id) /* recursions only counted */ break; strcpy(tname, num_to_name(chlist[c]->opid)); /* details for each definition it calls */ if (chlist[c]->total_time > 0.0) sprintf(sbuf, " %s%5d %8.2f %8.4f %8.2f\n", (tmp = padright(NMWIDTH - 1, tname)), chlist[c]->total_calls, chlist[c]->total_time, chlist[c]->total_time / chlist[c]->total_calls, 100 * (chlist[c]->total_time / totaloptime)); else sprintf(sbuf, " %s%5d %8.2f %8.4f %8.2f\n", (tmp = padright(NMWIDTH - 1, tname)), chlist[c]->total_calls, chlist[c]->total_time, 0.0, 0.0); writechars(prf, sbuf, strlen(sbuf), false); free(tmp); } free_merge_list(chlist, used); } sprintf(sbuf, "\n"); writechars(prf, sbuf, strlen(sbuf), false); } } if (prf != STDOUT) closefile(prf); apush(Nullexpr); return; }
/* * Builds the symbol table, creating scopes as needed, and linking them together. * Adds variable and function identifiers to scopes appropriately. */ void build_symbol_table(ast_node root, int level, int sibno, symboltable_t *symtab) { //calculate the scope for the variable/func declaration //calculate the parent for that variable/func declaration //need function to take as input //printf("here \n"); symhashtable_t *hash; /* Depending on node types, go deeper, create sibling scopes, add to hashtable, * or take other appropriate action. */ switch (root->node_type) { ast_node param; int param_offset = 4; int param_count = 0; case SEQ_N: // change main level when see a new sequence level++; break; case FORMAL_PARAMS_N: level++; param_count = 0; insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); // for(param = root->left_child; param != NULL; param = param->right_sibling){ // if(param->node_type == ARRAY_TYPE_N || param->return_type == ARRAY_TYPE_N){ // param_count += DEFAULT_ARRAY_PARAM_SIZE; // } // else{ // param_count++; // } // } // printf("PARAM COUNT!!!!! = %d\n", param_count); // // for(param = root->left_child; param != NULL; param = param->right_sibling){ // if(param->node_type == ARRAY_TYPE_N || param->return_type == ARRAY_TYPE_N){ // param->snode->offset = param_count * 4; // param->snode->offset -= DEFAULT_ARRAY_PARAM_SIZE; // } // else{ // param->snode->offset = param_count-- * 4; // } // } break; case FUNC_DECLARATION_N: // function declaraions //does hashtable exist with given lvl, siblvl (use find_hashtable) check_if_redef(root, symtab ,level, sibno); hash = find_hashtable(symtab->root, level, sibno); if(hash == NULL) { hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) ); } insert_into_symhashtable(hash, root); // will only insert if it is empty. insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); break; case FUNCTION_N: check_if_declared(root, symtab ,level, sibno); insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); break; case ID_N: /* print the id */ check_if_redef(root, symtab ,level, sibno); //if(root->return_type != 0) { // a non-zero value means that it is a declaration, since only declarations // are assigned a return type when building the abstract syntax tree. if(root->isDecl){ hash = find_hashtable(symtab->root, level, sibno); if(hash == NULL) { hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) ); } insert_into_symhashtable(hash, root); } else { // don't know if previously declared check_if_declared(root, symtab , level, sibno); } insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); break; case ARRAY_TYPE_N: // check for return types! check_if_redef(root, symtab ,level, sibno); //cif(root->return_type != 0) { if(root->isDecl){ hash = find_hashtable(symtab->root, level, sibno); if(hash == NULL) { hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) ); } insert_into_symhashtable(hash, root); } else { check_if_declared(root, symtab , level, sibno); } insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); break; case RETURN_N: insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) ); break; default: // printf("at default of switch\n"); assert(symtab->root != NULL); hash = find_hashtable(symtab->root, level, sibno); if(hash == NULL) { hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) ); } //note: cannot use insert_scope_info here because siblings[level - 1] causes invalid read as level-1 can go negative break; } if(arraylen == level) { arraylen = arraylen + DELTA; siblings = realloc(siblings, sizeof(int) * arraylen); assert(siblings != NULL); for(int k=0; k < DELTA; k++) { siblings[arraylen - (DELTA-k)] = 0; } } /* Recurse on each child of the subtree root, with a depth one greater than the root's depth. */ ast_node child; for (child = root->left_child; child != NULL; child = child->right_sibling) build_symbol_table(child, level, siblings[level], symtab); if(root->node_type == SEQ_N){//} || root->node_type == FORMAL_PARAMS_N){ siblings[level]++; // change sibling level after you're done printing all // subtrees, i.e., after done recursing. } }