from creole import * import unittest import ffi class PushTest(unittest.TestCase): def test_parse_push_reg(self): p = Program() p.parse_asm_line("push r5") b = p() self.assertEqual(b, b'\x01\xC2\x85\x00') ins = ffi.parse_line(b) self.assertEqual(ins[0], Instruction.PUSH.opcode) self.assertEqual(ins[1][0], (1,5)) def test_parse_push_imm(self): p = Program() p.parse_asm_line("push 5") b = p() self.assertEqual(b, b'\x01\xC0\x85\x00') ins = ffi.parse_line(b) self.assertEqual(ins[0], Instruction.PUSH.opcode) self.assertEqual(ins[1][0], (0,5)) def test_parse_push_catch_typecheck_push_lab(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("push l0") self.assertEqual(cm.exception.argtype, ArgType.VAL) self.assertEqual(cm.exception.sarg, 'l0') self.assertEqual(cm.exception.i, 0) self.assertEqual(cm.exception.opcode, 1) def test_parse_push_catch_typecheck_argument_overflow(self): p = Program() with self.assertRaises(TypecheckLenException) as cm: p.parse_asm_line("push r1 r2") self.assertEqual(cm.exception.opcode, 1) self.assertEqual(cm.exception.insargs, ["r1", "r2"]) self.assertEqual(cm.exception.argtypelen, 1) def test_parse_push_catch_typecheck_argument_underflow(self): p = Program() with self.assertRaises(TypecheckLenException) as cm: p.parse_asm_line("push") self.assertEqual(cm.exception.opcode, 1) self.assertEqual(cm.exception.insargs, []) self.assertEqual(cm.exception.argtypelen, 1) def test_large_reg(self): p = Program(reglen=0x8000000) p.parse_asm_line("PUSH r134217727") b = p() self.assertEqual(b, b'\x01\xFC\x87\xbf\xbf\xbf\xbf\x00') def test_compile_push(self): p = Program() p.parse_asm_line("PUSH r0") p.parse_asm_line("PUSH 6") b = p() ex = ffi.Environment() self.assertEqual(ex.load(b), ffi.CompileRet.OK) self.assertEqual(ex.cenv.prgend, 2) self.assertEqual(ex.cenv.prg[0].opcode, 1) self.assertEqual(ex.cenv.prg[0].w_flags[0], 1) self.assertEqual(ex.cenv.prg[0].w_flags[1], 0) self.assertEqual(ex.cenv.prg[0].w_flags[2], 0) self.assertEqual(ex.cenv.prg[0].w[0], 0) self.assertEqual(ex.cenv.prg[0].w[1], 0) self.assertEqual(ex.cenv.prg[0].w[2], 0) self.assertEqual(ex.cenv.prg[1].opcode, 1) self.assertEqual(ex.cenv.prg[1].w_flags[0], 0) self.assertEqual(ex.cenv.prg[1].w_flags[1], 0) self.assertEqual(ex.cenv.prg[1].w_flags[2], 0) self.assertEqual(ex.cenv.prg[1].w[0], 6) self.assertEqual(ex.cenv.prg[1].w[1], 0) self.assertEqual(ex.cenv.prg[1].w[2], 0) def test_push_many(self): p = Program() stklen = 40 for n in range(0,stklen): p.parse_asm_line("PUSH 5") ex = ffi.Environment(stklen=stklen) self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) for n in range(0,stklen): self.assertEqual(ex.cenv.stk[n], 5) def test_push_overflow(self): p = Program() stklen = 40 for n in range(0, stklen + 1): p.parse_asm_line("PUSH 5") ex = ffi.Environment(stklen=stklen) self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STACK_OVERFLOW) class PopTest(unittest.TestCase): def test_compile_pop_reg(self): p = Program() p.parse_asm_line("pop r9") b = p() self.assertEqual(b, b'\x02\xC2\x89\x00') ex = ffi.Environment() self.assertEqual(ex.load(b), ffi.CompileRet.OK) self.assertEqual(ex.cenv.prgend, 1) self.assertEqual(ex.cenv.prg[0].opcode, 2) self.assertEqual(ex.cenv.prg[0].w_flags[0], 1) self.assertEqual(ex.cenv.prg[0].w_flags[1], 0) self.assertEqual(ex.cenv.prg[0].w_flags[2], 0) self.assertEqual(ex.cenv.prg[0].w[0], 9) self.assertEqual(ex.cenv.prg[0].w[1], 0) self.assertEqual(ex.cenv.prg[0].w[2], 0) def test_compile_throw_pop_literal(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("pop 6") self.assertEqual(cm.exception.argtype, ArgType.REG) self.assertEqual(cm.exception.sarg, '6') self.assertEqual(cm.exception.i, 0) self.assertEqual(cm.exception.opcode, 2) def test_compile_throw_pop_label(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("pop l9") self.assertEqual(cm.exception.argtype, ArgType.REG) self.assertEqual(cm.exception.sarg, 'l9') self.assertEqual(cm.exception.i, 0) self.assertEqual(cm.exception.opcode, 2) def test_compile_throw_argument_overflow(self): p = Program() with self.assertRaises(TypecheckLenException) as cm: p.parse_asm_line("pop r1 r2") self.assertEqual(cm.exception.opcode, 2) self.assertEqual(cm.exception.insargs, ["r1", "r2"]) self.assertEqual(cm.exception.argtypelen, 1) def test_catch_typecheck_argument_underflow(self): p = Program() with self.assertRaises(TypecheckLenException) as cm: p.parse_asm_line("pop") self.assertEqual(cm.exception.opcode, 2) self.assertEqual(cm.exception.insargs, []) def test_pop_underflow(self): p = Program() p.parse_asm_line("pop r0") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW) def test_pop_underflow_2(self): p = Program() p.parse_asm_line("push 5") p.parse_asm_line("pop r0") p.parse_asm_line("pop r1") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW) class AddTest(unittest.TestCase): def test_exec_add(self): p = Program() p.parse_asm_line("add r0 1 1") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) self.assertEqual(ex.cenv.reg[0], 2) def test_exec_add_neg(self): p = Program() p.parse_asm_line("add r0 10 20") p.parse_asm_line("add r1 5 0") p.parse_asm_line("add r1 r0 -40") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) self.assertEqual(ex.cenv.reg[0], 30) self.assertEqual(ex.cenv.reg[1], word_2c(10)) def test_exec_add_throw_imm(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("add 5 6 7") self.assertEqual(cm.exception.argtype, ArgType.REG) self.assertEqual(cm.exception.sarg, '5') self.assertEqual(cm.exception.i, 0) self.assertEqual(cm.exception.opcode, 3) def test_exec_add_throw_lab_1(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("add r0 l6 7") self.assertEqual(cm.exception.argtype, ArgType.VAL) self.assertEqual(cm.exception.sarg, 'l6') self.assertEqual(cm.exception.i, 1) self.assertEqual(cm.exception.opcode, 3) def test_exec_add_throw_lab_2(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("add r0 12 l24") self.assertEqual(cm.exception.argtype, ArgType.VAL) self.assertEqual(cm.exception.sarg, 'l24') self.assertEqual(cm.exception.i, 2) self.assertEqual(cm.exception.opcode, 3) class MulTest(unittest.TestCase): def test_exec_mul_imm_imm(self): p = Program() p.parse_asm_line("mul r0 2 2") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) self.assertEqual(ex.cenv.reg[0], 4) def test_exec_mul_imm_neg_imm(self): p = Program() p.parse_asm_line("mul r0 -5 5") p.parse_asm_line("mul r1 r0 -5") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) self.assertEqual(ex.cenv.reg[0], word_2c(25)) self.assertEqual(ex.cenv.reg[1], 125) def test_exec_mul_throw_imm(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("mul 942 6 7") self.assertEqual(cm.exception.argtype, ArgType.REG) self.assertEqual(cm.exception.sarg, '942') self.assertEqual(cm.exception.i, 0) self.assertEqual(cm.exception.opcode, 4) def test_exec_mul_throw_lab_1(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("mul r9 l2 1991") self.assertEqual(cm.exception.argtype, ArgType.VAL) self.assertEqual(cm.exception.sarg, 'l2') self.assertEqual(cm.exception.i, 1) self.assertEqual(cm.exception.opcode, 4) def test_exec_mul_throw_lab_2(self): p = Program() with self.assertRaises(TypecheckException) as cm: p.parse_asm_line("mul r0 -11 l48") self.assertEqual(cm.exception.argtype, ArgType.VAL) self.assertEqual(cm.exception.sarg, 'l48') self.assertEqual(cm.exception.i, 2) self.assertEqual(cm.exception.opcode, 4) class ProgramTest(unittest.TestCase): def test_exec_simple_reg(self): p = Program() p.parse_asm_line("push 5") p.parse_asm_line("push 6") p.parse_asm_line("pop r0") p.parse_asm_line("pop r1") ex = ffi.Environment() self.assertEqual(ex.load(p()), ffi.CompileRet.OK) self.assertEqual(ex(), ffi.RunRet.STOP) self.assertEqual(ex.cenv.reg[0], 6) self.assertEqual(ex.cenv.reg[1], 5) if __name__ == "__main__": unittest.main()