def save_fun_line_address_and_save_line(self, current_token: IdInfo): var_end_of_func = self.get_temp() var_end_of_func.addressing_mode = cs.INDIRECT var_end_of_func.line = self.current_line self.nested_func_stack.push(var_end_of_func) self.program_block.append((0, 0, 0, 0)) self.current_line += 1 func_id_info = self.ss.top() func_id_info.size += 8 # for return line address and return line and start line func_id_info.address = self.memory_manager.get_temp(func_id_info) func_id_info.addressing_mode = cs.DIRECT func_id_info.params_count = 0 line_num = IdInfo(str(self.current_line), type=cs.INT, addressing_mode=cs.IMMEDIATE) self.ss.pop(1) self.ss.push(line_num) self.program_block.append((0, 0, 0, 0)) self.current_line += 1 func_id_info.starting_line = self.current_line if func_id_info.token == "main": self.set_main_address(func_id_info.starting_line) self.ss.push(func_id_info)
def save_line(self, current_token: IdInfo): line_num = IdInfo(str(self.current_line), type=cs.INT, addressing_mode=cs.IMMEDIATE) self.ss.push(line_num) self.program_block.append((0, 0, 0, 0)) self.current_line += 1
def output_func_declare(self, current_id: IdInfo): # type - specifier ID # push_function_id #new_scope ( #save_fun_line_address_and_save_line params ) compound-stmt #delete_scope", ### type_info = IdInfo("void", type=cs.TYPE) self.ss.push(type_info) func_id_info = IdInfo("output") self.push_function_id(func_id_info) self.new_scope(current_id) self.save_fun_line_address_and_save_line(current_id) param_type_info = IdInfo("int", type=cs.TYPE) self.ss.push(param_type_info) param_info = IdInfo("s") self.ss.push(param_info) self.declare_param_int(current_id) self.push_param_in_func(current_id) s = self.symbol_table.find("s") self.program_block.append(("PRINT", s.address_in_program(), "", "")) self.current_line += 1 # self.jp_to_caller(current_id) self.jp_to_caller_final(current_id) self.delete_scope(current_id)
def compare_save_for_jpf(self, current_token: IdInfo): tmp_var = self.get_temp() self.program_block.append(("EQ", self.ss.list[-1].address_in_program(), self.ss.list[-2].address_in_program(), tmp_var.address_in_program())) self.current_line += 1 self.ss.pop() self.ss.push(tmp_var) line_num = IdInfo(str(self.current_line), type=cs.INT, addressing_mode=cs.IMMEDIATE) self.ss.push(line_num) self.program_block.append((0, 0, 0, 0)) self.current_line += 1
def look_ahead(self): if self.prev_token == "EOF": self.prev_token = "$" return "$", "$" if self.prev_token == "$": print("Scanner: Reached end of file", self.current_location) return self.token_beginning = self.current_location char = self.get_char() # ------ handle equal == or = ----- if char == "=": next_char = self.get_char() if (next_char == -1): print("error in input") if (next_char == "="): token = "==" self.prev_token = token return IdInfo(token,type="op"), token else: token = "=" self.get_back() self.prev_token = token return token, token # ------ handle + - ----- if char == "+" or char == "-": if self.prev_token in cs.operators or self.prev_token in cs.opening_tokens or self.prev_token in cs.separator_tokens: number = char last_char = char while last_char.isdigit() or last_char == "+" or last_char == "-": next_char = self.get_char() if (next_char == -1): self.prev_token = int(number) return IdInfo(str(int(number)),type=cs.INT, addressing_mode=cs.IMMEDIATE), NUM if (next_char.isdigit()): number += next_char elif next_char in cs.Terminals or next_char in cs.whitespace: self.get_back() self.prev_token = int(number) return IdInfo(str(int(number)),type=cs.INT, addressing_mode=cs.IMMEDIATE), NUM else: print("Scanner Error: Invalid character in number") print("Panic Mode: Ignore character in Number ", next_char) return self.look_ahead() else: self.prev_token = char return IdInfo(char, type=cs.OPERATION), char # ------ handle numbers ------ elif char.isdigit(): number = char last_char = char while last_char.isdigit() or last_char == "+" or last_char == "-": next_char = self.get_char() last_char = next_char if (next_char == -1): self.prev_token = int(number) return IdInfo(str(int(number)),type=cs.INT, addressing_mode=cs.IMMEDIATE), NUM if (next_char.isdigit()): number += next_char elif next_char in cs.Terminals or next_char in cs.whitespace: self.get_back() self.prev_token = int(number) return IdInfo(str(int(number)),type=cs.INT, addressing_mode=cs.IMMEDIATE), NUM else: print("Scanner Error: Invalid character in number") print("Panic Mode: Ignore character in Number ", next_char) return self.look_ahead() # ----- handle one char cs.Terminals ----- elif char in cs.Terminals: self.prev_token = char if char in cs.operators: return IdInfo(char,type=cs.OPERATION), char return char, char # ----- handle ID or keywords ------ elif char.isalpha(): current_ID = char last_char = char while last_char.isdigit() or last_char.isalpha(): next_char = self.get_char() last_char = next_char if next_char == -1: self.prev_token = current_ID if (current_ID in cs.key_words): return IdInfo(current_ID,type=current_ID), current_ID else: return self.symbol_table.find(current_ID), ID # returns an IdInfo object # return current_ID, ID if next_char.isdigit() or next_char.isalpha(): current_ID += next_char elif next_char in cs.Terminals or next_char in cs.whitespace: self.get_back() self.prev_token = current_ID if (current_ID in cs.key_words): return IdInfo(current_ID,type=current_ID), current_ID else: return self.symbol_table.find(current_ID), ID # returns an IdInfo object else: print("Scanner Error: Invalid character in identifier") print("Panic Mode: Ignore character in ID ", next_char) return self.look_ahead() # ----- handle comments ---- elif char == "/": next_char = self.get_char() if next_char != "*": print("Scanner Error: Invalid character") print("Panic Mode: Ignore character / ") return self.look_ahead() next_char = self.get_char() while next_char != "*" and next_char != -1: next_char = self.get_char() if next_char == -1: print("Scanner Error: Unexpected end of file") return # print("Panic Mode: Ignore character in Number ", next_char) # return self.look_ahead() elif next_char == "*": next_char = self.get_char() if next_char == "/": return self.look_ahead() elif next_char == -1: print("Scanner Error: Unexpected end of file", self.current_location - 1) return else: print("Scanner Error: Invalid character") print("Panic Mode: Ignore character in * ", next_char) return self.look_ahead() # ------- handle cs.whitespace ------- elif char in cs.whitespace: return self.look_ahead() else: print("Scanner Error: Invalid character", self.current_location) print("Panic Mode: Ignore character ", char) return self.look_ahead()
def p_type(self, current_token: IdInfo): if current_token.token not in [cs.INT, cs.VOID]: print("Error: type is unknown") current_token.type = cs.TYPE self.ss.push(current_token)
def push_constant(self, current_token: IdInfo): current_token.addressing_mode = cs.IMMEDIATE current_token.type = cs.INT self.ss.push(current_token)
def get_temp(self): tmp_var = IdInfo("tmp", type="int", size=4, addressing_mode=cs.DIRECT) tmp_var.address = self.memory_manager.get_temp(tmp_var) return tmp_var
def push_continue_stack(self, current_token: IdInfo): line_num = IdInfo(str(self.current_line), type=cs.INT, addressing_mode=cs.IMMEDIATE) self.while_starts.push(line_num)