import os.path

def assemble(inputFile, outputFile):
    opcodes = {
        "NOP": "0000",
        "HLT": "0001",
        "ADD": "0010",
        "SUB": "0011",
        "ORR": "0100",
        "NOR": "0101",
        "AND": "0110",
        "XOR": "0111",
        "INC": "1000",
        "DEC": "1001",
        "RSH": "1010",
        "LDI": "1011",
        "LOD": "1100",
        "STR": "1101",
        "JMP": "1110",
        "BIF": "1111",
        "LSH": "0010"
    }
    registers = {
        "r0": "000",
        "r1": "001",
        "r2": "010",
        "r3": "011",
        "r4": "100",
        "r5": "101",
        "r6": "110",
        "r7": "111",
    }
    
    if not os.path.exists(inputFile):
        print('File does not exist.')
    else:
        with open(inputFile) as f:
            content = f.read().splitlines()

        for line in content:
            words = line.split()
            
            words[0] = words[0].upper()
            
            if words[0] == "LSH":
                words[0] = "ADD"
                words[3] = words[2]
                
            if words[0] == "CMP":
                words[0] = "SUB"
                words.append(words[2])
                words[2] = words[1]
                words[1] = "r0"
                
            if words[0] == "CPY":
                words[0] = "ADD"
                words.append("r0")
                
            if words[0] == "NOT":
                words[0] = "NOR"
                words[3] = "r0"
            
            linia_final = opcodes[words[0]]
            
            if words[0] == "NOP" or words[0] == "HLT":
                linia_final += "000000000000"
            if words[0] in ["ADD", "SUB", "ORR", "NOR", "AND", "XOR"]:
                linia_final += registers[words[1]] + "000" + registers[words[2]] + registers[words[3]]
            if words[0] in ["INC", "DEC", "RSH"]:
                linia_final += registers[words[1]] + "000" + registers[words[2]] + "000"
            if words[0] == "LDI":
                linia_final += registers[words[1]] + "000" + "{0:06b}".format(int(words[2]))
            if words[0] == "LOD":
                linia_final += registers[words[1]] + "000000000"
            if words[0] == "STR":
                linia_final += "000000" + registers[words[1]] + "000"
            if words[0] == "JMP":
                linia_final += "000000" + "{0:06b}".format(int(words[1]))
            if words[0] == "BIF":
                if words[1] == "zero":
                    words[1] = "0"
                elif words[1] == "msb":
                    words[1] = "1"
                else:
                    raise ValueError()
                linia_final += "00000" + words[1] + "{0:06b}".format(int(words[2]))
                
            res = ""
            for i in range(0, len(linia_final), 4): 
                res += linia_final[i:i + 4] + " " 
            
            with open(outputFile, "a") as f:
                f.write(res + "\n")
            

assemble("fib.as", "fib_assembled.as")