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 ); } }
void recurse_tree(node_t* root){ if(root == NULL) return; if(root->type.index == DECLARATION){ declare_tree(root); }else if(root->type.index == BLOCK){ next_stack_offset = -4; scope_add(); }else if(root->type.index == FUNCTION){ next_stack_offset = -4; scope_add(); //function is defined already, but not the parameters. define_parameters(root); }else if(root->type.index == EXPRESSION || root->type.index == ASSIGNMENT_STATEMENT){ for(int i = 0; i< root->n_children;i++){ node_t* child = root->children[i]; if(child == NULL) continue; if(child->type.index == VARIABLE){ symbol_t* symbol = symbol_get((char*)child->data); root->entry = symbol; } } }else if(root->type.index == TEXT){ char* text = (char*) root->data; //For future ease of use, I will not store //the index directly in the pointer. int32_t* intpoint = malloc(sizeof(int32_t)); *intpoint = strings_add(text); //Store the string index instead of the string root->data = intpoint; } for(int i = 0; i < root->n_children; i++){ node_t* child = root->children[i]; recurse_tree(child); } if(root->type.index == BLOCK || root->type.index == FUNCTION){ scope_remove(); } }
void bind_names ( node_t *root ) { //Initial scope for the functions scope_add(); declare_functions(root); recurse_tree(root); //Remove the function scope scope_remove(); }
//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; }
int generate_for_item(Pool *pool, FILE *out, AstFor *p, ListNode *item, int *need_comma) { Scope *scope = scope_new(pool, p->scope); ListBuilder code = list_builder_init(pool); if (dynamic_ok(p->filter) && !test_filter(p->filter, ast_to_outline_item(item->d))) return 1; if (p->list && *need_comma) CHECK(file_putc(out, ',')); *need_comma = 1; scope_add(scope, pool, p->item, item->d); CHECK(parse_code(pool, &p->code, scope, out_list_builder(&code))); CHECK(generate_code(pool, out, code.first)); return 1; }
int generate_macro_call(Pool *pool, FILE *out, AstMacroCall *p) { ListNode *call_input; ListNode *macro_input; Scope *scope = scope_new(pool, p->macro->scope); ListBuilder code = list_builder_init(pool); /* Assign values to all inputs: */ macro_input = p->macro->inputs; call_input = p->inputs; while (macro_input && call_input) { AstCodeText *name = macro_input->d.p; scope_add(scope, pool, name->code, call_input->d); macro_input = macro_input->next; call_input = call_input->next; } CHECK(parse_code(pool, &p->macro->code, scope, out_list_builder(&code))); CHECK(generate_code(pool, out, code.first)); return 1; }
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; }
/** * Program entry point. Constructs and launches the main program object. */ int main(int argc, char *argv[]) { Pool pool = pool_init(0x10000); /* 64K block size */ Options opt = options_init(); Source *in; Scope *scope = scope_new(&pool, 0); ListBuilder code = list_builder_init(&pool); /* Read the options: */ if (!options_parse(&opt, argc, argv)) { options_usage(argv[0]); goto error; } /* Determine output file name: */ if (!string_size(opt.name_out)) { if (string_rmatch(opt.name_in, string_from_k(".ol")) != 3) { fprintf(stderr, "error: If no output file is specified, the input file name must end with \".ol\".\n"); goto error; } opt.name_out = string(opt.name_in.p, opt.name_in.end - 3); } /* Input stream: */ in = source_load(&pool, opt.name_in); if (!in) { fprintf(stderr, "error: Could not open source file \"%s\"\n", opt.name_in.p); goto error; } /* Keywords: */ scope_add(scope, &pool, string_from_k("macro"), dynamic(type_keyword, keyword_new(&pool, parse_macro))); scope_add(scope, &pool, string_from_k("outline"), dynamic(type_keyword, keyword_new(&pool, parse_outline))); scope_add(scope, &pool, string_from_k("union"), dynamic(type_keyword, keyword_new(&pool, parse_union))); scope_add(scope, &pool, string_from_k("map"), dynamic(type_keyword, keyword_new(&pool, parse_map))); scope_add(scope, &pool, string_from_k("for"), dynamic(type_keyword, keyword_new(&pool, parse_for))); scope_add(scope, &pool, string_from_k("include"), dynamic(type_keyword, keyword_new(&pool, parse_include))); /* Do outline2c stuff: */ if (!parse_code(&pool, in, scope, out_list_builder(&code))) goto error; if (opt.debug) { printf("--- AST: ---\n"); dump_code(code.first, 0); printf("\n"); } if (!main_generate(&pool, code.first, &opt)) goto error; /* Clean up: */ pool_free(&pool); return 0; error: pool_free(&pool); return 1; }
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]); }
//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 ); } } } }