Esempio n. 1
0
 def run(self, vm: VM) -> Optional['Break']:
     a_num = vm.belt().get_num(self._a_idx)
     b_num = vm.belt().get_num(self._b_idx)
     a = a_num.to_signed(self._is_signed).to_int()
     b = b_num.to_signed(self._is_signed).to_int()
     if a is None or b is None:
         vm.belt().push(BeltNum(DataType.I8, Integer(None)))
     else:
         result = self._op(a, b)
         vm.belt().push(BeltNum(DataType.I8, Integer(int(result))))
     return None
Esempio n. 2
0
def test_nested_loop():
    vm = VM(
        LoopStack([
            LoopTree.CARTESIAN(3, [
                LoopTree.LEAF(3),
                LoopTree.LEAF(5),
            ]),
        ]),
        num_locals=0,
        ram_size=0,
    )
    ins = InsLoopSpecified(
        Block([
            InsLoopSpecified(
                Block([
                    InsArith([0], True, ArithMode.CHECKED, lambda n: n - 1),
                ])),
            InsLoopSpecified(
                Block([
                    InsArith([0], True, ArithMode.CHECKED, lambda n: n + 1),
                ])),
            InsArith([0], True, ArithMode.CHECKED, lambda n: n * 2),
        ]))
    ins.run(vm)
    result = vm.belt().get_num(0).value.expect_int()
    assert result == 28
Esempio n. 3
0
 def run(self, vm: VM) -> Optional['Break']:
     param_nums = [vm.belt().get_num(idx) for idx in self._param_indices]
     params = [
         num.to_signed(self._is_signed).to_int() for num in param_nums
     ]
     data_type = functools.reduce(DataType.promote,
                                  (param.data_type for param in param_nums))
     if any(param is None for param in params):
         vm.belt().push(BeltNum(data_type, Integer(None)))
     else:
         results = self._op(data_type, *params)
         for result in reversed(results):
             vm.belt().push(
                 BeltNum.from_signed(Integer(result),
                                     data_type,
                                     is_signed=self._is_signed))
     return None
Esempio n. 4
0
 def run(self, vm: VM) -> Optional['Break']:
     a_num = vm.belt().get_num(self._a_idx)
     b_num = vm.belt().get_num(self._b_idx)
     a = a_num.to_signed(self._is_signed).to_int()
     b = b_num.to_signed(self._is_signed).to_int()
     if a is None or b is None or not self._op(a, b):
         raise ValueError('Verify failed')
     return None
Esempio n. 5
0
 def run(self, vm: VM) -> Optional['Break']:
     if vm.belt().get_num(self._condition_idx).value.expect_int():
         block = self._then_block
     else:
         block = self._else_block
     br = block.run(vm)
     if br is not None and br.depth == 0 and br.is_continue:
         raise ValueError('Cannot continue if/else/end block')
     return br
Esempio n. 6
0
 def run(self, vm: VM) -> Optional['Break']:
     for ins in self._instructions:
         br = ins.run(vm)
         print(ins, [
             vm.belt().get_num(i).value.expect_int()
             for i in range(Belt.SIZE)
         ])
         if br is not None and br.depth > 0:
             return Break(br.depth - 1, is_continue=br.is_continue)
Esempio n. 7
0
def test_simple_loop():
    vm = VM(
        LoopStack([
            LoopTree.LEAF(8),
        ]),
        num_locals=0,
        ram_size=0,
    )
    ins = InsLoopSpecified(
        Block([
            InsArith([0], False, ArithMode.CHECKED, lambda n: n + 1),
        ]))
    ins.run(vm)
    result = vm.belt().get_num(0).value.expect_int()
    assert result == 8
Esempio n. 8
0
def test_simple_loop_break():
    vm = VM(
        LoopStack([
            LoopTree.LEAF(8),
        ]),
        num_locals=0,
        ram_size=0,
    )
    ins = InsLoopSpecified(
        Block([
            InsBrIf(condition_idx=0, br_depth=1),
            InsArith([2], False, ArithMode.CHECKED, lambda n: n + 1),
            InsConst(BeltNum(DataType.I8, Integer(3))),
            InsRel(a_idx=0, b_idx=1, is_signed=False, op=lambda a, b: a < b),
        ]))
    ins.run(vm)
    belt = [vm.belt().get_num(i).value.expect_int() for i in range(Belt.SIZE)]
    assert belt == [1, 3, 4, 0, 3, 3, 0, 3, 2, 0, 3, 1, 0, 0, 0, 0]
Esempio n. 9
0
def test_fib_loop():
    vm = VM(
        LoopStack([
            LoopTree.LEAF(16),
        ]),
        num_locals=0,
        ram_size=0,
    )
    ins = Block([
        InsConst(BeltNum(DataType.I64, Integer(1))),
        InsLoopSpecified(
            Block([
                InsArith([0, 1], False, ArithMode.CHECKED, int.__add__),
            ])),
    ])
    ins.run(vm)
    belt = [vm.belt().get_num(i).value.expect_int() for i in range(Belt.SIZE)]
    assert belt == [
        1597, 987, 610, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 2, 1
    ]
Esempio n. 10
0
def test_two_simple_loops_break():
    vm = VM(
        LoopStack([
            LoopTree.LEAF(16),
            LoopTree.LEAF(16),
        ]),
        num_locals=1,
        ram_size=0,
    )
    ins = Block([
        InsLoopSpecified(
            Block([
                InsArith([0], False, ArithMode.CHECKED, lambda n: n + 1),
                InsLocalSet(0),
                InsConst(BeltNum(DataType.I8, Integer(3))),
                InsRel(a_idx=0,
                       b_idx=1,
                       is_signed=False,
                       op=lambda a, b: a < b),
                InsBrIf(condition_idx=0, br_depth=1),
                InsLocalGet(0),
            ])),
        InsLoopSpecified(
            Block([
                InsArith([0], False, ArithMode.CHECKED, lambda n: n + 1),
                InsLocalSet(0),
                InsConst(BeltNum(DataType.I8, Integer(7))),
                InsRel(a_idx=0,
                       b_idx=1,
                       is_signed=False,
                       op=lambda a, b: a < b),
                InsBrIf(condition_idx=0, br_depth=1),
                InsLocalGet(0),
            ])),
    ])
    ins.run(vm)
    belt = [vm.belt().get_num(i).value.expect_int() for i in range(Belt.SIZE)]
    assert belt == [1, 7, 8, 7, 0, 7, 7, 6, 0, 7, 6, 5, 0, 7, 5, 4]
    assert vm.local(0).value.expect_int() == 8
Esempio n. 11
0
 def run(self, vm: VM) -> Optional['Break']:
     vm.belt().push(self._belt_num)
     return None
Esempio n. 12
0
 def run(self, vm: VM) -> Optional['Break']:
     item = vm.belt().get_num(self._item_idx)
     vm.belt().push(self._op(item, self._data_type, self._is_signed))
     return None
Esempio n. 13
0
 def run(self, vm: VM) -> Optional['Break']:
     slc = vm.belt().get_slice(self._slice_idx)
     num = vm.belt().get_num(self._item_idx)
     slc.store(self._offset, num)
     return None
Esempio n. 14
0
def test_nested_loop_break():
    vm = VM(
        LoopStack([
            LoopTree.CARTESIAN(3, [
                LoopTree.LEAF(3),
                LoopTree.LEAF(5),
            ]),
            LoopTree.LEAF(2),
        ]),
        num_locals=1,
        ram_size=0,
    )
    ins = Block([
        InsLoopSpecified(
            Block([
                # decrement 3 times
                InsLoopSpecified(
                    Block([
                        InsArith([0], True, ArithMode.CHECKED,
                                 lambda n: n - 1),
                    ])),
                # increment 5 times; if number reaches 10, terminate outer loop
                InsLoopSpecified(
                    Block([
                        InsArith([0], True, ArithMode.CHECKED,
                                 lambda n: n + 1),
                        InsLocalSet(0),
                        InsConst(BeltNum(DataType.I8, Integer(10))),
                        InsRel(0, 1, True, lambda a, b: a < b),
                        InsBrIf(0, 2),
                        InsLocalGet(0),
                    ])),
                # double
                InsArith([0], True, ArithMode.CHECKED, lambda n: n * 2),
            ])),
        InsLocalGet(0),
        InsLoopSpecified(
            Block([
                InsArith([0], True, ArithMode.CHECKED, lambda n: n + 2),
            ])),
    ])
    ins.run(vm)
    belt = [vm.belt().get_num(i).value.expect_int() for i in range(Belt.SIZE)]
    assert belt == [
        15,
        13,  # 2 times  +2
        11,  # local get
        1,
        10,
        11,  # final loop iteration
        10,
        0,
        10,
        10,  # second to last loop iteration
        9,
        10,
        11,  # decrementing loop
        12,  # *2
        6,
        0
    ]  # local get, rel
Esempio n. 15
0
 def run(self, vm: VM) -> Optional['Break']:
     slc = vm.belt().get_slice(self._slice_idx)
     vm.belt().push(slc.load(self._data_type, self._offset))
     return None
Esempio n. 16
0
 def run(self, vm: VM) -> Optional['Break']:
     vm.belt().push(vm.local(self._local_idx))
     return None
Esempio n. 17
0
 def run(self, vm: VM) -> Optional['Break']:
     vm.set_local(self._local_idx, vm.belt()[0])
     return None
Esempio n. 18
0
 def run(self, vm: VM) -> Optional['Break']:
     slc = vm.belt().get_slice(self._slice_idx)
     num_bytes = vm.belt().get_num(self._num_bytes_idx).value.expect_int()
     vm.belt().push(self._op(slc, num_bytes))
     return None
Esempio n. 19
0
 def run(self, vm: VM) -> Optional['Break']:
     slc = vm.belt().get_slice(self._slice_idx)
     vm.belt().push(BeltNum(DataType.I32, Integer(slc.length)))
     return None
Esempio n. 20
0
 def run(self, vm: VM) -> Optional['Break']:
     num = vm.belt().get_num(self._item_idx)
     if num.value.to_int() is None:
         raise ValueError('Verify failed')
     return None
Esempio n. 21
0
 def run(self, vm: VM) -> Optional['Break']:
     num = vm.belt().get_num(self._item_idx)
     vm.belt().push(
         BeltNum(DataType.I8,
                 Integer(1 if num.value.to_int() is None else 0)))
     return None
Esempio n. 22
0
 def run(self, vm: VM) -> Optional['Break']:
     if vm.belt().get_num(self._condition_idx).value.expect_int():
         return Break(self._br_depth, is_continue=False)
Esempio n. 23
0
 def run(self, vm: VM) -> Optional['Break']:
     slc = vm.belt().get_slice(self._slice_idx)
     start = vm.belt().get_num(self._start_idx).value.expect_int()
     length = vm.belt().get_num(self._length_idx).value.expect_int()
     vm.belt().push(slc.subslice(start, length))
     return None