Ejemplo n.º 1
0
Archivo: tree.c Proyecto: sondrele/NTNU
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 );
	}
}
Ejemplo n.º 2
0
//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;
}
Ejemplo n.º 3
0
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]);
	}
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
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 );
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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 = &parameter;
                                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]);
    

}
Ejemplo n.º 8
0
//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]);
	}
}
Ejemplo n.º 9
0
//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();
}
Ejemplo n.º 10
0
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 );
			}
		}
	}	
}
Ejemplo n.º 11
0
Archivo: tree.c Proyecto: sondrele/NTNU
void traverse_children ( node_t *root ) {
	for ( int i = 0; i < root->n_children; i++ )
		bind_names ( root->children[i] );
}