Example #1
0
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;
}
Example #2
0
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);
		}
	}
}
Example #4
0
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;
}