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
예제 #5
0
    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)