/*create type of a variable*/ struct type_descriptor* create_type(struct tree_node* specifier_node){ assert(specifier_node -> unit_code == Specifier); int type_code = get_type_code_from_specifier(specifier_node); struct struct_descriptor* sd; if(type_code == TYPE_INT || type_code == TYPE_FLOAT){ sd = NULL; } if(type_code == TYPE_STRUCT){ //Specifier -> StructSpecifier struct tree_node* structspecifier_node = specifier_node -> child; if(structspecifier_node -> child -> sibling -> unit_code == Tag){ //exist struct char *struct_name = structspecifier_node -> child -> sibling -> child -> unit_value; sd = find_struct(struct_table_head, struct_name); if(sd == NULL){ printf("Error Type 17 at line %d : Undefined struct %s\n", specifier_node -> lineno, struct_name ); semantic_error_flag = true; return NULL; } } else{ //new struct sd = create_structure(structspecifier_node); } } return create_type_descriptor(type_code, sd); }
/*create a structure and add it into the struct list *structure defined by structspecifier node in syntax tree*/ struct struct_descriptor* create_structure(struct tree_node* structspecifier_node){ assert(structspecifier_node -> unit_code == StructSpecifier); struct tree_node* opttag_node = structspecifier_node -> child -> sibling; char* struct_name; if(structspecifier_node -> child -> sibling -> child != NULL){ //OptTag !-> empty struct_name = opttag_node -> child -> unit_value; //ID node has a value /*check struct name repeat*/ if((find_struct(struct_table_head, struct_name) != NULL) || (find_var(var_table_head, struct_name) != NULL)){ printf("Error type 16 at line %d: Struct name redefine\n", structspecifier_node -> lineno); semantic_error_flag = true; return NULL; } } else struct_name = ""; //empty struct name struct tree_node* deflist_node = opttag_node -> sibling -> sibling; struct struct_descriptor* new_struct_descriptor = create_struct_descriptor(struct_name); new_struct_descriptor -> member_num = init_member_list(new_struct_descriptor -> member_list_head, deflist_node); add_struct(struct_table_head, new_struct_descriptor); return new_struct_descriptor; }
symbol_t * build_struct (int su, symbol_t *tag, symtab_t *symtab, type_t *type) { symbol_t *sym = find_struct (su, tag, type); symbol_t *s; symtab->parent = 0; // disconnect struct's symtab from parent scope if (sym->table == current_symtab && sym->type->t.symtab) { error (0, "%s defined as wrong kind of tag", tag->name); return sym; } for (s = symtab->symbols; s; s = s->next) { if (s->sy_type != sy_var) continue; if (su == 's') { s->s.offset = symtab->size; symtab->size += type_size (s->type); } else { int size = type_size (s->type); if (size > symtab->size) symtab->size = size; } } if (!type) sym->type = find_type (sym->type); // checks the tag, not the symtab sym->type->t.symtab = symtab; if (!type && sym->type->type_def->external) //FIXME should not be necessary sym->type->type_def = qfo_encode_type (sym->type); return sym; }
//! //! Either prints help messages or runs command-specific validator //! //! @param[in] index //! @param[in] this_cmd //! @param[in] params //! @param[in] next_cmd //! //! @return A pointer to the command structure if valid otherwise NULL is returned //! //! @pre //! //! @post //! static imager_command *validate_cmd(int index, char *this_cmd, imager_param * params, char *next_cmd) { int i = 0; char help = '\0'; char *cmd = NULL; const char **p = NULL; imager_command *cmd_struct = NULL; imager_request *req = NULL; if (this_cmd == NULL) return NULL; cmd = this_cmd; // see if it is a help request if (strcmp(cmd, "help") == 0) { help = 1; if (next_cmd == NULL) { // not specific fprintf(stderr, "supported commands:\n"); for (i = 0; i < (sizeof(known_cmds) / sizeof(imager_command)); i++) { fprintf(stderr, "\t%s\n", known_cmds[i].name); } exit(0); } else { // help for a specific command cmd = next_cmd; } } // find the function pointers for the command if ((cmd_struct = find_struct(cmd)) == NULL) err("command '%s' not found", cmd); // print command-specific help if (help) { p = cmd_struct->parameters(); if (p == NULL || *p == NULL) { fprintf(stderr, "command '%s' has no parameters\n", cmd_struct->name); } else { fprintf(stderr, "parameters for '%s' (* - mandatory):\n", cmd_struct->name); while (*p && *(p + 1)) { fprintf(stderr, "%18s - %s\n", *p, *(p + 1)); p += 2; } } exit(0); } // fill out the request struct and pass to the validator req = &reqs[index]; req->cmd = cmd_struct; req->params = params; req->index = index; req->internal = NULL; if (cmd_struct->validate(req)) err("incorrect parameters or missing dependencies for command '%s'", cmd_struct->name); return cmd_struct; }
void sub(t_glob *glob, t_champ *champ, int *args, int *type) { op_t *ins; int first_r; int second_r; glob = glob; type = type; first_r = champ->reg[(args[0] - 1)]; second_r = champ->reg[(args[1] - 1)]; if (champ != NULL) { ins = find_struct(5); champ->cycle_next_ins = ins->nbr_cycles; champ->reg[(args[2] - 1)] = first_r - second_r; champ->carry = '1'; } }
/*create a variable and add it into a var list *var defined by the specifier and vardec nodes in syntax tree*/ struct var_descriptor* create_variable(struct tree_node* specifier_node, struct tree_node* vardec_node, struct var_descriptor* head, bool is_member_var){ struct type_descriptor* var_type = create_type(specifier_node); if(var_type == NULL) return NULL; char* var_name = find_id_node_in_vardec(vardec_node) -> unit_value; struct array_descriptor* var_array = create_array_descriptor_by_vardec(vardec_node); struct var_descriptor* new_var = create_var_descriptor(var_name, var_type, var_array); if(find_var(head, var_name) == NULL && find_struct(struct_table_head, var_name) == NULL){ add_var(head, new_var); return new_var; } else{ if(is_member_var) printf("Error type 15 at line %d: member variable \'%s\' redefine\n", vardec_node -> lineno, var_name); else printf("Error type 3 at line %d: variable \'%s\' redefine\n", vardec_node -> lineno, var_name); semantic_error_flag = true; return NULL; } }
void handle_postfix_expr(node *n) { int prev_lvalue; /* the first child is always grabbed as a reference */ prev_lvalue = LVALUE; LVALUE = 1; handle(n->children[0]); LVALUE = prev_lvalue; if (strcmp(n->children[1]->id, "inc") == 0) { if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { /* post increment */ e("lw $t1, 0($t0)\n"); e("addiu $t2, $t1, 1\n"); e("sw $t2, 0($t0)\n"); e("move $t0, $t1\n"); } } else if (strcmp(n->children[1]->id, "dec") == 0) { if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { /* post deccrement */ e("lw $t1, 0($t0)\n"); e("addiu $t2, $t1, -1\n"); e("sw $t2, 0($t0)\n"); e("move $t0, $t1\n"); } } else if (strcmp(n->children[1]->id, "argument_expr_list") == 0) { /* function call */ handle(n->children[1]); e("call %s\n", n->children[0]->id); e("addiu $sp, $sp, %d\n", params * WORD); e("move $t0, $v0\n"); params = 0; } else if (strcmp(n->children[1]->id, "paren") == 0) { /* function call without arguments */ e("call %s\n", n->children[0]->id); e("move $t0, $v0\n"); } else if (strcmp(n->children[1]->id, "expression") == 0) { /* array index */ if (last_symbol != NULL) { if (last_symbol->attr & ATTR_POINTER) { e("lw $t0, 0($t0)\n"); } } push("$t0"); prev_lvalue = LVALUE; LVALUE = 0; handle(n->children[1]); /* the offset in the array */ LVALUE = prev_lvalue; pop("$t1"); e("sll $t0, $t0, 2\n"); /*TODO: not all array indexes are multiples of 4! */ e("addu $t0, $t0, $t1\n"); if (!LVALUE) { /* dereference it */ e("lw $t0, 0($t0)\n"); } } else if (strcmp(n->children[1]->id, "dot") == 0) { /* puts address of struct member into $t0 */ // offsets of struct and member within struct int member_offset = 0; // struct name char *struct_id = n->children[0]->id; // member name char *member_id = n->children[2]->id; // struct symbol table entry symbol *sym = find_symbol(n->children[0]->t, struct_id); // struct type char *struct_type = sym->type; // struct table entry struct_table *curr = find_struct(struct_type); if(curr == NULL) { lerr(n->line, "[code_gen] could not find struct type: %s\n", struct_type); } // Struct symbol table symbol_table *struct_sym_tbl = curr->s; // Struct member symbol pointer symbol *cur_sym; /* // DEBUG: Print struct identifier and member identifier printf("\t* Struct Name: %s, Member Name: %s\n", struct_id, member_id); // DEBUG: Print member name and type printf("\t\t* Attribute: %X, Type %s\n", sym->attr, sym->type); */ // if struct is a union (ATTR_UNION == 0x2000) then skip offset code if(sym->attr & ATTR_STRUCT) { // Determine member offset in struct cur_sym = struct_sym_tbl->s; while (strcmp(cur_sym->value, member_id) != 0) { if (cur_sym == NULL) lerr(n->line, "[code_gen] could not find member, %s, in struct: %s\n", member_id, struct_type); cur_sym = cur_sym->up; member_offset += 4; } e("addiu $t0, $t0, %d # offset of member: %s\n", member_offset, member_id); } else if(sym->attr & ATTR_UNION) { // No member offset is currently required for unions because all members are the same size and word aligned } else { lerr(n->line, "[code_gen] %s is not a struct or union so '.' cannot be used\n", struct_id); } } else if (strcmp(n->children[1]->id, "ptr") == 0) { /* puts value located in address of struct member into $t0 */ // offsets of struct and member within struct int member_offset = 0; // struct name char *struct_id = n->children[0]->id; // member name char *member_id = n->children[2]->id; // struct symbol table entry symbol *sym = find_symbol(n->children[0]->t, struct_id); // struct type char *struct_type = sym->type; // struct table entry struct_table *curr = find_struct(struct_type); if(curr == NULL) { lerr(n->line, "[code_gen] could not find struct type: %s\n", struct_type); } // Struct symbol table symbol_table *struct_sym_tbl = curr->s; // Struct member symbol pointer symbol *cur_sym; // if struct is a union (ATTR_UNION == 0x2000) then skip offset code if(sym->attr & ATTR_STRUCT) { // Determine member offset in struct cur_sym = struct_sym_tbl->s; while (strcmp(cur_sym->value, member_id) != 0) { if (cur_sym == NULL) lerr(n->line, "[code_gen] could not find member, %s, in struct: %s\n", member_id, struct_type); cur_sym = cur_sym->up; member_offset += 4; } e("addiu $t0, $t0, %d # offset of member: %s\n", member_offset, member_id); e("lw $t0, 0($t0)\t# load value of %s->%s\n", struct_id, member_id); //pop("$t1"); } else if(sym->attr & ATTR_UNION) { // Mask only applicable bits of variable types that don't use full word (i.e. char, short, etc.) e("lw $t0, 0($t0)\t# load value of %s->%s\n", struct_id, member_id); cur_sym = find_symbol(struct_sym_tbl, member_id); if( strcmp(cur_sym->type, "char") == 0 ) { e("andi $t0, $t0, 0xFF # Member is a char, Truncate value to 8 bits\n"); } else if( strcmp(cur_sym->type, "short") == 0 ) { e("andi $t0, $t0, 0xFF # Member is a short, Truncate value to 8 bits\n"); } //pop("$t1"); } else { lerr(n->line, "[code_gen] %s is not a struct or union so '->' cannot be used\n", struct_id); } // Old implementation without union /* // offsets of struct and member within struct int member_offset = 0; // struct name char *struct_id = n->children[0]->id; // struct type char *struct_type = find_symbol(n->children[0]->t, struct_id)->type; // member name char *member_id = n->children[2]->id; // struct symbol table struct_table *curr = find_struct(struct_type); if(curr == NULL) { lerr(n->line, "[code_gen] could not find struct type: %s\n", struct_type); } // Determine member offset in struct symbol *cur_sym = curr->s->s; while (strcmp(cur_sym->value, member_id) != 0) { if (cur_sym == NULL) lerr(n->line, "[code_gen] could not find member, %s, in struct type: %s\n", member_id, struct_type); cur_sym = cur_sym->up; member_offset += 4; } e("addiu $t0, $t0, %d\t# offset of member: %s\n", member_offset, member_id); e("lw $t0, 0($t0)\t# load value of %s->%s", struct_id, member_id); pop("$t1"); */ } else { // Debug: display id of child that is not implemented // printf("id not implemented: %s\n", n->children[1]->id); lerr(n->line, "[code_gen] postfix expressions not fully implemented\n"); } }