void bind_names ( node_t *root ) { if (root == NULL) return; switch (root->type.index) { case FUNCTION_LIST: { add_functions_to_symtab ( root ); traverse_children ( root ); break; } case FUNCTION: { scope_add (); add_parameters_to_scope ( root ); if ( root->children[2]->type.index == BLOCK) { bind_names ( root->children[2]->children[0] ); bind_names ( root->children[2]->children[1] ); } else fprintf(stderr, "Expected BLOCK-statement after FUNCTION \"%s\"\n", (char *) root->data); scope_remove (); break; } case BLOCK: { scope_add (); traverse_children ( root ); scope_remove (); break; } case DECLARATION_LIST: { int stack_offset = -VSL_PTR_SIZE; for ( int i = 0; i < root->n_children; i++ ) { node_t *declaration_n = root->children[i]; stack_offset = add_variables_to_scope ( declaration_n, stack_offset ); } break; } case VARIABLE: { symbol_t *var = symbol_get ( (char *) root->data ); if ( var != NULL ) root->entry = var; else fprintf(stderr, "The variable \"%s\" is not declared.\n", (char *) root->data); traverse_children ( root ); break; } case TEXT: { add_text ( root ); traverse_children ( root ); break; } default: traverse_children ( root ); } }
//Adds a new scope and continues down the tree. void block(node_t *node) { int temp_offset = var_offset; var_offset = -4; scope_add(); if (node != NULL) { for (int i = 0; i < node->n_children; i++) { bind_names(node->children[i]); } } scope_remove(); var_offset = temp_offset; }
void bind_functions(node_t *node) { //Binds all the function names. for (int i = 0; i < node->n_children; i++) { symbol_t *newSymbol = (void*)malloc(sizeof(void)); newSymbol->stack_offset = 0; newSymbol->label = (char*)(node->children[i]->children[0]->data); symbol_insert(newSymbol->label, newSymbol); } //Continues down the tree. for (int i = 0; i < node->n_children; i++) { bind_names(node->children[i]); } }
int main ( int argc, char **argv ) { yyparse(); simplify_tree ( &root, root ); // node_print(root, 0); find_globals(); size_t n_globals = tlhash_size(global_names); symbol_t *global_list[n_globals]; tlhash_values ( global_names, (void **)&global_list ); for ( size_t i=0; i<n_globals; i++ ) if ( global_list[i]->type == SYM_FUNCTION ) bind_names ( global_list[i], global_list[i]->node ); // print_globals(); generate_program (); destroy_subtree ( root ); destroy_symtab(); }
int main ( int argc, char **argv ) { options ( argc, argv ); symtab_init (); yyparse(); #ifdef DUMP_TREES if ( (DUMP_TREES & 1) != 0 ) node_print ( stderr, root, 0 ); #endif simplify_tree ( root ); #ifdef DUMP_TREES if ( (DUMP_TREES & 2) != 0 ) node_print ( stderr, root, 0 ); #endif bind_names ( root ); /* Parsing and semantics are ok, redirect stdout to file (if requested) */ if ( outfile != NULL ) { if ( freopen ( outfile, "w", stdout ) == NULL ) { fprintf ( stderr, "Could not open output file '%s'\n", outfile ); exit ( EXIT_FAILURE ); } free ( outfile ); } generate ( stdout, root ); destroy_subtree ( root ); symtab_finalize(); exit ( EXIT_SUCCESS ); }
void function (node_t *node) { //adds a new scope int temp_offset = var_offset; var_offset = -4; scope_add(); //Skips the first child(name of the function, since it's already been added in bind_functions(node_t). //adds the parameters that lies within the second child. if (node->children[1] != NULL) { int offset = 8 + 4*(node->children[1]->n_children-1); for (int i = 0; i < (node->children[1])->n_children; i++) { symbol_t *new_symbol = (void*)malloc(sizeof(void));; new_symbol->stack_offset = offset; offset = offset - 4; new_symbol->label = NULL; symbol_insert((char*)(node->children[1]->children[i]->data), new_symbol); } } //Skips the block node, which is the third child, and jumps directly to its children, since the scope is already added. for (int i = 0; i < node->children[2]->n_children; i++) { bind_names(node->children[2]->children[i]); } scope_remove(); var_offset = temp_offset; }
void bind_names ( node_t *root ) { symbol_t *symbol = malloc(sizeof(symbol_t)); switch(root->type.index){ case FUNCTION_LIST: scope_add(); current_depth = 0; for(int i = 0; i < root->n_children; i++){ symbol_t *child = malloc(sizeof(symbol_t)); child->label = &root->children[i]->data; symbol_insert(child->label, child); } for(int i = 0; i < root->n_children; i++) if(root->children[i] != NULL) bind_names(root->children[i]); break; case FUNCTION: symbol->label = &root->data; scope_add(); current_depth++; symbol_insert(symbol->label, symbol); for(int i = 0; i < root->n_children; i++){ if(root->children[i] != NULL){ if(root->children[i]->type.index = PARAMETER_LIST){ int32_t local_offset = root->children[i]->n_children*4 + 8; for(int j = 0; j < root->children[i]->n_children; j++){ if(root->children[i]->children[j] != NULL){ symbol_t *parameter = malloc(sizeof(symbol_t*)); parameter->stack_offset = local_offset; local_offset -= 4; parameter->depth = current_depth; root->children[i]->children[j]->entry = ¶meter; symbol_insert(&root->children[i]->children[j]->data, parameter); } } } bind_names(root->children[i]); } } scope_remove(); current_depth--; break; case BLOCK: scope_add(); int local_offset = -4; current_offset = -4; for(int i = 0; i < root->n_children; i++) if(root->children[i] != NULL) bind_names(root->children[i]); scope_remove(); break; } for(int i = 0; i < root->n_children; i++) if(root->children[i] != NULL) bind_names(root->children[i]); }
//Nothing to add at this node, so skip it and continue down the tree. void skipNode(node_t *node) { for (int i = 0; i < node->n_children; i++) { bind_names(node->children[i]); } }
//Adds the first scope to the stack, then continues down the tree. void program (node_t *node) { scope_add(); bind_names(node->children[0]); scope_remove(); }
void bind_names ( node_t* root ) { /* TODO: bind tree nodes to symtab entries */ node_t* child; if(root != NULL) { for(int i = 0; i < root->n_children; i++) { child = root->children[i]; int counter = 0; if(child == NULL) continue; // move along, nothing to see here switch(child->type.index) { case FUNCTION_LIST: // add an upper scope to hold the functions (can functions be defined in a function?) // need this so that the scope in another function can know about all the other functions that are defined. scope_add(); for(int i = 0; i < child->n_children; i++) { // populate symbol table with known functions add_functions(child->children[i]); } bind_names(child); scope_remove(); break; case FUNCTION: ; /* reset depth, reset offset, add arguments */ dybde = 0; local_offset = -4; scope_add(); // add vars in the var list under (arguments) node_t* varlist = child->children[1]; if( varlist != NULL) { int count = 8+(4*(varlist->n_children-1)); for( int i = 0; i < varlist->n_children; i++ ) { char* key = varlist->children[i]->data; symbol_t* s = malloc(sizeof(symbol_t)); s->stack_offset = count; count -= 4; s->n_args = 0; s->depth = dybde; s->label = key; symbol_insert( key, s ); } } // traverse child 2 ( a BLOCK ) bind_names(child->children[2]); scope_remove(); break; case BLOCK: ; /* start new scope, add depth */ scope_add(); dybde++; local_offset = -4; bind_names( child ); dybde--; scope_remove(); break; case DECLARATION_LIST: ; for( int dec = 0; dec < child->n_children; dec++) { node_t* declaration = child->children[dec]; // add vars in the var list under node_t* varlist = declaration->children[0]; for( int i = 0; i < varlist->n_children; i++ ) { char* key = varlist->children[i]->data; symbol_t* s = malloc(sizeof(symbol_t)); s->stack_offset = local_offset; local_offset -= 4; s->n_args = 0; s->depth = dybde; s->label = key; symbol_insert( key, s ); } } //return; // safe to return now ? //bind_names(child); // not needed? break; case VARIABLE: ; char* key = child->data; symbol_t* temp = NULL; symbol_get( &temp, key ); if( temp != NULL ) { child->entry = temp; } else { // symbol not yet declared, do some error ? fprintf( stderr, "Error: Symbol \"%s\" not yet declared\n", key ); } bind_names( child ); break; case TEXT: ; /* set data to index in the table of strings */ uint32_t* index = malloc(sizeof(uint32_t)); *index = strings_add(child->data); child->data = index; break; default: ; bind_names( child ); } } } }
void traverse_children ( node_t *root ) { for ( int i = 0; i < root->n_children; i++ ) bind_names ( root->children[i] ); }