예제 #1
0
파일: tree.c 프로젝트: 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 );
	}
}
예제 #2
0
파일: tree.c 프로젝트: lionleaf/compiler
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();
    }
}
예제 #3
0
파일: tree.c 프로젝트: lionleaf/compiler
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();
}
예제 #4
0
파일: tree.c 프로젝트: CheeKinTANG/Skole
//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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
파일: tree.c 프로젝트: CheeKinTANG/Skole
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;
}
예제 #8
0
파일: main.c 프로젝트: swansontec/outline2c
/**
 * 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;
}
예제 #9
0
파일: tree.c 프로젝트: peterhgombos/tdt4205
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]);
    

}
예제 #10
0
파일: tree.c 프로젝트: CheeKinTANG/Skole
//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();
}
예제 #11
0
파일: tree.c 프로젝트: esiqveland/skole
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 );
			}
		}
	}	
}