RAM = {}
ROM = {}
IP = 0
HALT = False
BREAK = False
STEP = False
STACK = []
ERR_UNDERFLOW = ValueError("Stack underflow occured.")

def Get(addr):
	global RAM
	global STACK
	if addr < 0:
		if (-addr - 1) < len(STACK):
			return STACK[-addr - 1]
		else:
			return 0
	elif addr in RAM:
		return RAM[addr]
	else:
		return 0

def Set(addr, value):
	global RAM
	global STACK
	if addr < 0:
		while (-addr - 1) >= len(STACK):
			STACK += [0]
		STACK[-addr - 1] = value
	else:
		RAM[addr] = value

def Execute():
	global ROM
	global IP
	global HALT
	global BREAK
	global STEP

	BREAK = False
	while not HALT:
		if not IP in ROM:
			raise ValueError("Instruction pointer is out of bounds.")
		ROM[IP]()
		IP += 1
		if STEP or BREAK:
			return

SP = 0
R2 = 0
R3 = 0
R4 = 0
R1 = 0
R5 = 0
LABEL__anonlabel_1 = 2
LABEL__anonlabel_3 = 7
LABEL__anonlabel_5 = 19
LABEL__anonlabel_4 = 21
LABEL__anonlabel_6 = 32
LABEL__anonlabel_2 = 36
LABEL__anonlabel_7 = 43
LABEL__anonlabel_0 = 46

def INST_0():
	Set(0, 0)
	return
INST_0.Source = "STR 0 R0"
ROM[0] = INST_0

def INST_1():
	global LABEL__anonlabel_0
	global IP
	IP = LABEL__anonlabel_0 - 1
	return
INST_1.Source = "JMP ._anonlabel_0"
ROM[1] = INST_1

def INST_2():
	global R2
	global SP
	SP -= 1
	Set(SP, R2)
	return
INST_2.Source = "PSH R2"
ROM[2] = INST_2

def INST_3():
	global R3
	global SP
	SP -= 1
	Set(SP, R3)
	return
INST_3.Source = "PSH R3"
ROM[3] = INST_3

def INST_4():
	global R4
	global SP
	SP -= 1
	Set(SP, R4)
	return
INST_4.Source = "PSH R4"
ROM[4] = INST_4

def INST_5():
	global R2
	R2 = 0
	return
INST_5.Source = "IMM R2 0"
ROM[5] = INST_5

def INST_6():
	global R3
	R3 = 0
	return
INST_6.Source = "MOV R3 R0"
ROM[6] = INST_6

def INST_7():
	global R2
	global R2
	global R3
	R2 += R3
	return
INST_7.Source = "ADD R2 R2 R3"
ROM[7] = INST_7

def INST_8():
	global R3
	global R2
	R3 = Get(R2)
	return
INST_8.Source = "LOD R3 R2"
ROM[8] = INST_8

def INST_9():
	global LABEL__anonlabel_4
	global R3
	global IP
	if R3 == 0:
		IP = LABEL__anonlabel_4 - 1
	return
INST_9.Source = "BRZ ._anonlabel_4 R3"
ROM[9] = INST_9

def INST_10():
	global R4
	global R3
	R4 = R3 & 1
	return
INST_10.Source = "AND R4 R3 1"
ROM[10] = INST_10

def INST_11():
	global R3
	global R3
	R3 >>= 1
	return
INST_11.Source = "RSH R3 R3"
ROM[11] = INST_11

def INST_12():
	global LABEL__anonlabel_3
	global R4
	global IP
	if R4 != 0:
		IP = LABEL__anonlabel_3 - 1
	return
INST_12.Source = "BNZ ._anonlabel_3 R4"
ROM[12] = INST_12

def INST_13():
	global LABEL__anonlabel_3
	global R3
	global R1
	if R3 < R1:
		IP = LABEL__anonlabel_3 - 1
	return
INST_13.Source = "BRL ._anonlabel_3 R3 R1"
ROM[13] = INST_13

def INST_14():
	global R3
	global R3
	R3 <<= 1
	return
INST_14.Source = "LSH R3 R3"
ROM[14] = INST_14

def INST_15():
	global R3
	global R3
	R3 |= 1
	return
INST_15.Source = "OR R3 R3 1"
ROM[15] = INST_15

def INST_16():
	global R2
	global R3
	Set(R2, R3)
	return
INST_16.Source = "STR R2 R3"
ROM[16] = INST_16

def INST_17():
	global R1
	global R2
	R1 = R2 + 1
	return
INST_17.Source = "ADD R1 R2 1"
ROM[17] = INST_17

def INST_18():
	global LABEL__anonlabel_6
	global IP
	IP = LABEL__anonlabel_6 - 1
	return
INST_18.Source = "JMP ._anonlabel_6"
ROM[18] = INST_18

def INST_19():
	global R1
	R1 = 0
	return
INST_19.Source = "MOV R1 R0"
ROM[19] = INST_19

def INST_20():
	global LABEL__anonlabel_6
	global IP
	IP = LABEL__anonlabel_6 - 1
	return
INST_20.Source = "JMP ._anonlabel_6"
ROM[20] = INST_20

def INST_21():
	global R3
	global R1
	R3 = R1 + 1
	return
INST_21.Source = "ADD R3 R1 1"
ROM[21] = INST_21

def INST_22():
	global R3
	global SP
	SP -= 1
	Set(SP, R3)
	return
INST_22.Source = "PSH R3"
ROM[22] = INST_22

def INST_23():
	global R4
	global R3
	R4 = 65535 - R3
	return
INST_23.Source = "SUB R4 65535 R3"
ROM[23] = INST_23

def INST_24():
	global LABEL__anonlabel_5
	global R4
	global R2
	if R4 < R2:
		IP = LABEL__anonlabel_5 - 1
	return
INST_24.Source = "BRL ._anonlabel_5 R4 R2"
ROM[24] = INST_24

def INST_25():
	global R3
	global R3
	R3 <<= 1
	return
INST_25.Source = "LSH R3 R3"
ROM[25] = INST_25

def INST_26():
	global R3
	global R3
	R3 |= 1
	return
INST_26.Source = "OR R3 R3 1"
ROM[26] = INST_26

def INST_27():
	global R2
	global R3
	Set(R2, R3)
	return
INST_27.Source = "STR R2 R3"
ROM[27] = INST_27

def INST_28():
	global R1
	global R2
	R1 = R2 + 1
	return
INST_28.Source = "ADD R1 R2 1"
ROM[28] = INST_28

def INST_29():
	global R3
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R3 = Get(SP)
	SP += 1
	return
INST_29.Source = "POP R3"
ROM[29] = INST_29

def INST_30():
	global R2
	global R2
	global R3
	R2 += R3
	return
INST_30.Source = "ADD R2 R2 R3"
ROM[30] = INST_30

def INST_31():
	global R2
	Set(R2, 0)
	return
INST_31.Source = "STR R2 R0"
ROM[31] = INST_31

def INST_32():
	global R4
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R4 = Get(SP)
	SP += 1
	return
INST_32.Source = "POP R4"
ROM[32] = INST_32

def INST_33():
	global R3
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R3 = Get(SP)
	SP += 1
	return
INST_33.Source = "POP R3"
ROM[33] = INST_33

def INST_34():
	global R2
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R2 = Get(SP)
	SP += 1
	return
INST_34.Source = "POP R2"
ROM[34] = INST_34

def INST_35():
	global IP
	global SP
	if SP >= 0:
		raise ERR_UNDERFLOW
	IP = Get(SP)
	SP += 1
	return
INST_35.Source = "RET"
ROM[35] = INST_35

def INST_36():
	global R4
	global SP
	SP -= 1
	Set(SP, R4)
	return
INST_36.Source = "PSH R4"
ROM[36] = INST_36

def INST_37():
	global R3
	global SP
	SP -= 1
	Set(SP, R3)
	return
INST_37.Source = "PSH R3"
ROM[37] = INST_37

def INST_38():
	global LABEL__anonlabel_7
	global R1
	global IP
	if R1 == 0:
		IP = LABEL__anonlabel_7 - 1
	return
INST_38.Source = "BRZ ._anonlabel_7 R1"
ROM[38] = INST_38

def INST_39():
	global R4
	global R1
	R4 = R1 - 1
	return
INST_39.Source = "SUB R4 R1 1"
ROM[39] = INST_39

def INST_40():
	global R3
	global R4
	R3 = Get(R4)
	return
INST_40.Source = "LOD R3 R4"
ROM[40] = INST_40

def INST_41():
	global R3
	global R3
	R3 &= -2
	return
INST_41.Source = "AND R3 R3 -2"
ROM[41] = INST_41

def INST_42():
	global R4
	global R3
	Set(R4, R3)
	return
INST_42.Source = "STR R4 R3"
ROM[42] = INST_42

def INST_43():
	global R3
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R3 = Get(SP)
	SP += 1
	return
INST_43.Source = "POP R3"
ROM[43] = INST_43

def INST_44():
	global R4
	global SP
	global ERR_UNDERFLOW
	if SP >= 0:
		raise ERR_UNDERFLOW
	R4 = Get(SP)
	SP += 1
	return
INST_44.Source = "POP R4"
ROM[44] = INST_44

def INST_45():
	global IP
	global SP
	if SP >= 0:
		raise ERR_UNDERFLOW
	IP = Get(SP)
	SP += 1
	return
INST_45.Source = "RET"
ROM[45] = INST_45

def INST_46():
	global R1
	R1 = 2
	return
INST_46.Source = "IMM R1 2"
ROM[46] = INST_46

def INST_47():
	global LABEL__anonlabel_1
	global IP
	global SP
	SP -= 1
	Set(SP, IP)
	IP = LABEL__anonlabel_1 - 1
	return
INST_47.Source = "CAL ._anonlabel_1"
ROM[47] = INST_47

def INST_48():
	global R3
	global R1
	R3 = R1
	return
INST_48.Source = "MOV R3 R1"
ROM[48] = INST_48

def INST_49():
	global R1
	R1 = 2
	return
INST_49.Source = "IMM R1 2"
ROM[49] = INST_49

def INST_50():
	global LABEL__anonlabel_1
	global IP
	global SP
	SP -= 1
	Set(SP, IP)
	IP = LABEL__anonlabel_1 - 1
	return
INST_50.Source = "CAL ._anonlabel_1"
ROM[50] = INST_50

def INST_51():
	global R4
	global R1
	R4 = R1
	return
INST_51.Source = "MOV R4 R1"
ROM[51] = INST_51

def INST_52():
	global R1
	R1 = 2
	return
INST_52.Source = "IMM R1 2"
ROM[52] = INST_52

def INST_53():
	global LABEL__anonlabel_1
	global IP
	global SP
	SP -= 1
	Set(SP, IP)
	IP = LABEL__anonlabel_1 - 1
	return
INST_53.Source = "CAL ._anonlabel_1"
ROM[53] = INST_53

def INST_54():
	global R2
	global R1
	R2 = R1
	return
INST_54.Source = "MOV R2 R1"
ROM[54] = INST_54

def INST_55():
	global R5
	global R3
	R5 = R3 + 0
	return
INST_55.Source = "ADD R5 R3 0"
ROM[55] = INST_55

def INST_56():
	global R5
	global R4
	Set(R5, R4)
	return
INST_56.Source = "STR R5 R4"
ROM[56] = INST_56

def INST_57():
	global R5
	global R3
	R5 = R3 + 1
	return
INST_57.Source = "ADD R5 R3 1"
ROM[57] = INST_57

def INST_58():
	global R5
	Set(R5, 1)
	return
INST_58.Source = "STR R5 1"
ROM[58] = INST_58

def INST_59():
	global R5
	global R4
	R5 = R4 + 0
	return
INST_59.Source = "ADD R5 R4 0"
ROM[59] = INST_59

def INST_60():
	global R5
	global R2
	Set(R5, R2)
	return
INST_60.Source = "STR R5 R2"
ROM[60] = INST_60

def INST_61():
	global R5
	global R4
	R5 = R4 + 1
	return
INST_61.Source = "ADD R5 R4 1"
ROM[61] = INST_61

def INST_62():
	global R5
	Set(R5, 2)
	return
INST_62.Source = "STR R5 2"
ROM[62] = INST_62

def INST_63():
	global R5
	global R2
	R5 = R2 + 0
	return
INST_63.Source = "ADD R5 R2 0"
ROM[63] = INST_63

def INST_64():
	global R5
	Set(R5, 0)
	return
INST_64.Source = "STR R5 R0"
ROM[64] = INST_64

def INST_65():
	global R5
	global R2
	R5 = R2 + 1
	return
INST_65.Source = "ADD R5 R2 1"
ROM[65] = INST_65

def INST_66():
	global R5
	Set(R5, 3)
	return
INST_66.Source = "STR R5 3"
ROM[66] = INST_66

def INST_67():
	global HALT
	HALT = True
	return
INST_67.Source = "HLT"
ROM[67] = INST_67

