def semantic(ast, iNES=False, cart=None): if cart == None: cart = Cartridge() labels = get_labels(ast) address = 0 # translate statments to opcode for leaf in ast: if leaf["type"] == "S_RS": labels[leaf["children"][0]["value"]] = cart.rs cart.rs += get_value(leaf["children"][2]) elif leaf["type"] == "S_DIRECTIVE": directive = leaf["children"][0]["value"] if len(leaf["children"]) == 2: argument = get_value(leaf["children"][1], labels) else: argument = leaf["children"][1:] if directive in directive_list: directive_list[directive](argument, cart) else: raise Exception("UNKNOW DIRECTIVE") else: if leaf["type"] in ["S_IMPLIED", "S_ACCUMULATOR"]: instruction = leaf["children"][0]["value"] address = False elif leaf["type"] == "S_RELATIVE": instruction = leaf["children"][0]["value"] address = get_value(leaf["children"][1], labels) elif leaf["type"] == "S_IMMEDIATE_WITH_MODIFIER": instruction = leaf["children"][0]["value"] modifier = leaf["children"][1]["value"] address = get_value(leaf["children"][3], labels) if modifier == "#LOW": address = address & 0x00FF elif modifier == "#HIGH": address = (address & 0xFF00) >> 8 elif leaf["type"] in [ "S_RELATIVE", "S_IMMEDIATE", "S_ZEROPAGE", "S_ABSOLUTE", "S_ZEROPAGE_X", "S_ZEROPAGE_Y", "S_ABSOLUTE_X", "S_ABSOLUTE_Y", ]: instruction = leaf["children"][0]["value"] address = get_value(leaf["children"][1], labels) elif leaf["type"] in ["S_INDIRECT_X", "S_INDIRECT_Y"]: instruction = leaf["children"][0]["value"] address = get_value(leaf["children"][2], labels) address_mode = address_mode_def[leaf["type"]]["short"] opcode = opcodes[instruction][address_mode] if address_mode != "sngl": if "rel" == address_mode: address = 126 + (address - cart.pc) if address == 128: address = 0 elif address < 128: address = address | 0b10000000 elif address > 128: address = address & 0b01111111 if address_mode_def[leaf["type"]]["size"] == 2: cart.append_code([opcode, address]) else: arg1 = address & 0x00FF arg2 = (address & 0xFF00) >> 8 cart.append_code([opcode, arg1, arg2]) else: cart.append_code([opcode]) nes_code = [] if iNES: return cart.get_ines_code() else: return cart.get_code()