diff --git a/asm/creole.py b/asm/creole.py index e48d65f..2e323e4 100644 --- a/asm/creole.py +++ b/asm/creole.py @@ -165,18 +165,18 @@ class Line: self.opcode = opcode self.args = args - def check_line(self, labnum, regnum): + def check_line(self, lablen, reglen): for a in self.args: if a[0] == ArgType.REG: - if a[1] < 0 or a[1] >= regnum: + if a[1] < 0 or a[1] >= reglen: raise RangeCheckException(a[0], a[1], - regnum) + reglen) elif a[0] == ArgType.LAB: - if a[1] < 0 or a[1] >= labnum: + if a[1] < 0 or a[1] >= lablen: raise RangeCheckException(a[0], a[1], - regnum) + reglen) def __call__(self): b = bytes([self.opcode]) @@ -193,7 +193,7 @@ class InstructionNotFoundException(Exception): class Program: def asm_push_line(self, ins, args): l = Line(ins, args) - l.check_line(self.labnum, self.regnum) + l.check_line(self.lablen, self.reglen) self.asm.append(l) def parse_asm_line(self, line): @@ -214,8 +214,8 @@ class Program: b = b + line() return b - def __init__(self, labnum=16, regnum=16): + def __init__(self, lablen=16, reglen=16): self.asm = [] - self.labnum = labnum - self.regnum = regnum + self.lablen = lablen + self.reglen = reglen diff --git a/asm/test.py b/asm/test.py index 73568cc..bddf0a3 100644 --- a/asm/test.py +++ b/asm/test.py @@ -47,7 +47,7 @@ class PushTest(unittest.TestCase): self.assertEqual(cm.exception.argtypelen, 1) def test_large_reg(self): - p = Program(regnum=0x8000000) + p = Program(reglen=0x8000000) p.parse_asm_line("PUSH r134217727") b = p() self.assertEqual(b, b'\x01\xFC\x87\xbf\xbf\xbf\xbf\x00') @@ -78,6 +78,26 @@ class PushTest(unittest.TestCase): 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() @@ -117,18 +137,33 @@ class PopTest(unittest.TestCase): def test_compile_throw_argument_overflow(self): p = Program() with self.assertRaises(TypecheckLenException) as cm: - p.parse_asm_line("push r1 r2") - self.assertEqual(cm.exception.opcode, 1) + 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("push") - self.assertEqual(cm.exception.opcode, 1) + p.parse_asm_line("pop") + self.assertEqual(cm.exception.opcode, 2) self.assertEqual(cm.exception.insargs, []) - self.assertEqual(cm.exception.argtypelen, 1) + + 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): @@ -150,7 +185,6 @@ class AddTest(unittest.TestCase): self.assertEqual(ex.cenv.reg[0], 30) self.assertEqual(ex.cenv.reg[1], word_2c(10)) -class AddTest(unittest.TestCase): def test_exec_mul_throw_imm(self): p = Program() with self.assertRaises(TypecheckException) as cm: @@ -187,6 +221,7 @@ class AddTest(unittest.TestCase): 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")