Exemple #1
0
class Parser:
    def __init__(self, assembly_path: str) -> None:
        self.coder = Code()
        self.symbol_table = SymbolTable()
        self.assembly = []
        self.idx = 0

        f = open(assembly_path, 'r')
        while True:
            line = f.readline()
            if not line: break
            if line[:2] == "//": continue
            if [e for e in line if e != " "] == ["\n"]:
                continue
            self.assembly.append(line)
        f.close()

    def reset_idx(self):
        self.idx = 0

    def hasMoreCommands(self) -> bool:
        return self.idx < len(self.assembly)

    def advance(self) -> None:
        if self.hasMoreCommands():
            self.idx += 1

    def commandType(self) -> str:
        if self.hasMoreCommands():
            curr = self.assembly[self.idx]

            if "@" in curr:
                print("A", curr)
                return A
            elif "=" in curr or ";" in curr:
                print("C", curr)
                return C
            elif "(" in curr:
                return L
            else:
                return None

    def symbol(self) -> str:
        symbol = "".join([s for s in self.assembly[self.idx] if s != " "])
        symbol = symbol.split("\n")[0]
        if self.commandType() == A:
            symbol = symbol[1:]
            if not self.symbol_table.contains(symbol):
                try:
                    address = int(symbol)
                    self.symbol_table.addEntry(symbol, str(address))
                except:
                    self.symbol_table.addEntry(symbol,
                                               str(self.symbol_table.idx))
                    self.symbol_table.advance()
            self.assembly[
                self.idx] = "@" + self.symbol_table.getAddress(symbol)
        elif self.commandType() == L:
            symbol = symbol[1:-1]
            if not self.symbol_table.contains(symbol):
                self.symbol_table.addEntry(symbol, str(self.idx))
            self.assembly = self.assembly[:self.idx] + self.assembly[self.idx +
                                                                     1:]
        else:
            return ""

        return self.symbol_table.getAddress(symbol)

    def dest(self) -> str:
        if self.commandType() == C:
            return self.coder.dest(self.assembly[self.idx])
        else:
            raise NotImplementedError

    def comp(self) -> str:
        if self.commandType() == C:
            return self.coder.comp(self.assembly[self.idx])
        else:
            raise NotImplementedError

    def jump(self) -> str:
        if self.commandType() == C:
            return self.coder.jump(self.assembly[self.idx])
        else:
            raise NotImplementedError

    # def address(self) -> str:
    #     if self.commandType() == A:
    #         return self.coder.address(self.assembly[self.idx])
    #     else:
    #         raise NotImplementedError

    def address(self) -> str:
        instruction = self.assembly[self.idx]
        instruction = "".join([i for i in instruction if i != " "])
        instruction = instruction[1:].split("\n")[0]
        if self.symbol_table.contains(instruction):
            address = self.symbol_table.getAddress(instruction)
        else:
            address = instruction

        b = bin(int(address))[2:]
        address = "0" * (16 - len(b)) + b
        return address