std::vector<instruction::instruction_base*> parser::parse() { std::vector<instruction::instruction_base*> result; int current_line = 0; // Makes first pass to find all labels. while (advance()) { if (instruction_type() == L_INSTRUCTION) { processing.erase(processing.begin()); processing.erase(processing.end()-1); symbolic_table_instance.add(processing, current_line); } else { current_line++; } } // Reset file pointer to begin. commands.clear(); commands.seekg(0, std::ios::beg); // Main pass parsing program while (advance()) { int type = instruction_type(); if (type == C_INSTRUCTION) { instruction::instruction_c* instruction = instruction_c(); result.push_back(instruction); } else if (type == A_INSTRUCTION) { instruction::instruction_a* instruction = instruction_a(); result.push_back(instruction); } } return result; }
static void generate_return(code_block *parent, return_statement *ret) { function *fn = ret->target; bool non_void = !is_void(fn->return_type); if (non_void == !ret->value) { fprintf(stderr, "return from void function with return or non-void without " "return\n"); abort(); } size_t param_count = 1 + non_void; if (non_void) { parent = generate_expression(parent, ret->value); } parent->tail.type = GOTO; parent->tail.parameter_count = param_count; parent->tail.parameters = xmalloc(sizeof(size_t) * param_count); if (non_void) { parent->tail.parameters[1] = last_instruction(parent); } parent->tail.parameters[0] = 0; parent->tail.first_block = next_instruction(parent); size_t return_index = instruction_type(parent, 0)->struct_index; code_struct *return_struct = get_code_struct(parent->system, return_index); type *return_block_type = return_struct->fields[0].field_type; code_instruction *unwrap = new_instruction(parent, 2); unwrap->operation.type = O_GET_FIELD; unwrap->type = copy_type(return_block_type); unwrap->parameters[0] = 0; // return structs are always the first argument unwrap->parameters[1] = 0; // blockref position in all return structs }
void parse_file(FILE *fptr, int pass, char *instructions[], size_t inst_len, hash_table_t *hash_table, FILE *Out) { char line[MAX_LINE_LENGTH + 1]; char *tok_ptr, *ret, *token = NULL; int32_t line_num = 1; int32_t instruction_count = 0x00000000; int data_reached = 0; int i; //FILE *fptr; /*fptr = fopen(src_file, "r"); if (fptr == NULL) { fprintf(Out, "unable to open file %s. aborting ...\n", src_file); exit(-1); }*/ while (1) { if ((ret = fgets(line, MAX_LINE_LENGTH, fptr)) == NULL) break; line[MAX_LINE_LENGTH] = 0; tok_ptr = line; if (strlen(line) == MAX_LINE_LENGTH -1) { fprintf(Out, "line %d: line is too long. ignoring line ...\n", line_num); line_num++; continue; } //手动增加 \n 符。 i = strlen(line); if(line[i-1] != '\n') { line[i] = '\n'; line[i+1] = '\0'; } /* parse the tokens within a line */ while (1) { token = parse_token(tok_ptr, " \n\t$,", &tok_ptr, NULL); /* blank line or comment begins here. go to the next line */ if (token == NULL || *token == '#') { line_num++; if(token != NULL) free(token); break; } printf("token: %s\n", token); /* * If token is "la", increment by 8, otherwise if it exists in instructions[], * increment by 4. */ int x = search(token); //int x = (binarySearch(instructions, 0, inst_len, token)); if (x >= 0) { if (strcmp(token, "la") == 0) instruction_count = instruction_count + 8; else instruction_count = instruction_count + 4; } // If token is ".data", reset instruction to .data starting address else if (strcmp(token, ".data") == 0) { instruction_count = 0x00002000; data_reached = 1; } printf("PC Count: %d\n", instruction_count); // If first pass, then add labels to hash table // 第一遍扫描,检查 标签、数据段变量定义 if (pass == 1) { printf("First pass\n"); // if token has ':', then it is a label so add it to hash table if (strstr(token, ":") && data_reached == 0) { printf("Label\n"); // Strip out ':' //printf("Label: %s at %d with address %d: \n", token, line_num, instruction_count); size_t token_len = strlen(token); token[token_len - 1] = '\0'; // Insert variable to hash table uint32_t *inst_count; inst_count = (uint32_t *)malloc(sizeof(uint32_t)); *inst_count = instruction_count; int32_t insert = hash_insert(hash_table, token, strlen(token)+1, inst_count); if (insert != 1) { fprintf(Out, "Error inserting into hash table\n"); exit(1); } } // If .data has been reached, increment instruction count accordingly // and store to hash table else { char *var_tok = NULL; char *var_tok_ptr = tok_ptr; // If variable is .word if (strstr(tok_ptr, ".word")) { printf(".word\n"); // Variable is array if (strstr(var_tok_ptr, ":")) { printf("array\n"); // Store the number in var_tok and the occurance in var_tok_ptr var_tok = parse_token(var_tok_ptr, ":", &var_tok_ptr, NULL); // Convert char* to int int freq = atoi(var_tok_ptr); int num; sscanf(var_tok, "%*s %d", &num); // Increment instruction count by freq instruction_count = instruction_count + (freq * 4); // Strip out ':' from token size_t token_len = strlen(token); token[token_len - 1] = '\0'; //printf("Key: '%s', len: %zd\n", token, strlen(token)); // Insert variable to hash table uint32_t *inst_count; inst_count = (uint32_t *)malloc(sizeof(uint32_t)); *inst_count = instruction_count; int32_t insert = hash_insert(hash_table, token, strlen(token)+1, inst_count); if (insert == 0) { fprintf(Out, "Error in hash table insertion\n"); exit(1); } printf("End array\n"); } // Variable is a single variable else { instruction_count = instruction_count + 4; // Strip out ':' from token size_t token_len = strlen(token); token[token_len - 1] = '\0'; // Insert variable to hash table uint32_t *inst_count; inst_count = (uint32_t *)malloc(sizeof(uint32_t)); *inst_count = instruction_count; int32_t insert = hash_insert(hash_table, token, strlen(token)+1, inst_count); if (insert == 0) { fprintf(Out, "Error in hash table insertion\n"); exit(1); } printf("end singe var\n"); } } // Variable is a string else if (strstr(tok_ptr, ".asciiz")) { // Store the ascii in var_tok var_tok_ptr+= 8; var_tok = parse_token(var_tok_ptr, "\"", &var_tok_ptr, NULL); // Increment instruction count by string length size_t str_byte_len = strlen(var_tok); instruction_count = instruction_count + str_byte_len; // Strip out ':' from token size_t token_len = strlen(token); token[token_len - 1] = '\0'; // Insert variable to hash table uint32_t *inst_count; inst_count = (uint32_t *)malloc(sizeof(uint32_t)); *inst_count = instruction_count; int32_t insert = hash_insert(hash_table, token, strlen(token)+1, inst_count); if (insert == 0) { fprintf(Out, "Error in hash table insertion\n"); exit(1); } } } } // If second pass, then interpret // 第2遍扫描翻译语句 else if (pass == 2) { printf("############ Pass 2 ##############\n"); // start interpreting here // if j loop --> then instruction is: 000010 then immediate is insturction count in 26 bits?? // If in .text section if (data_reached == 0) { // Check instruction type //检查是否是已支持的指令 int instruction_supported = search(token); char inst_type; // If instruction is supported if (instruction_supported != -1) { // token contains the instruction // tok_ptr points to the rest of the line // Determine instruction type inst_type = instruction_type(token); if (inst_type == 'r') { rtype_parse(token, tok_ptr, Out); } // I-Type else if (inst_type == 'i') { itype_parse(token, tok_ptr, hash_table, instruction_count, Out); } // J-Type else if (inst_type == 'j') { jtype_parse(token, tok_ptr, hash_table, Out); } } if (strcmp(token, "nop") == 0) { if(RADIX == 16) { fprintf(Out,"00000000,\n"); } else { fprintf(Out, "00000000000000000000000000000000,\n"); } } } // If .data part reached else { char *var_tok = NULL; char *var_tok_ptr = tok_ptr; // If variable is .word if (strstr(tok_ptr, ".word")) { int var_value; // Variable is array if (strstr(var_tok_ptr, ":")) { // Store the number in var_tok and the occurance in var_tok_ptr var_tok = parse_token(var_tok_ptr, ":", &var_tok_ptr, NULL); // Extract array size, or variable frequency int freq = atoi(var_tok_ptr); // Extract variable value sscanf(var_tok, "%*s %d", &var_value); // Value var_value is repeated freq times. Send to binary rep function for (i = 0; i < freq; i++) { word_rep(var_value, Out); } } // Variable is a single variable else { // Extract variable value sscanf(var_tok_ptr, "%*s, %d", &var_value); // Variable is in var_value. Send to binary rep function word_rep(var_value, Out); } } // Variable is a string else if (strstr(tok_ptr, ".asciiz")) { printf("tok_ptr '%s'\n", tok_ptr); if (strncmp(".asciiz ", var_tok_ptr, 8) == 0) { // Move var_tok_ptr to beginning of string var_tok_ptr = var_tok_ptr + 9; // Strip out quotation at the end // Place string in var_tok var_tok = parse_token(var_tok_ptr, "\"", &var_tok_ptr, NULL); ascii_rep(var_tok, Out); } } } } free(token); } } }
static void mirror_instruction(code_block *parent, size_t src) { code_instruction *mirror = new_instruction(parent, 1); mirror->operation.type = O_GET_SYMBOL; mirror->type = copy_type(instruction_type(parent, src)); mirror->parameters[0] = src; }