コード例 #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
コード例 #2
0
ファイル: vm.py プロジェクト: mitra-labs/mitra-lab
 def __init__(self, loop_stack: LoopStack, num_locals: int, ram_size: int):
     self._belt = Belt()
     self._loop_stack = loop_stack
     self._locals = [BeltNum(data_type=DataType.I8, value=Integer(0))
                     ] * num_locals
     self._ram = BeltSlice(bytearray(ram_size), 0, ram_size)
     self._alignment = 0
コード例 #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
コード例 #4
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
コード例 #5
0
ファイル: parse.py プロジェクト: mitra-labs/mitra-lab
 def _handle_lit(self, names: List[str], lit: Tree) -> List[Instruction]:
     assigned_name, = names
     lit, = lit.children
     lit = lit.replace('_', '')
     if assigned_name.startswith('$'):
         raise ValueError('Cannot assign literals to locals (yet?)')
     m = self.REG_LIT.match(lit)
     num = int(m.group(1))
     is_signed = m.group(2) == 'i'
     bit_size = int(m.group(3))
     self._push(CompilerBeltItem(assigned_name, is_signed, False))
     return [
         InsConst(
             BeltNum.from_signed(Integer(num), DataType(bit_size),
                                 is_signed))
     ]
コード例 #6
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]
コード例 #7
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
    ]
コード例 #8
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
コード例 #9
0
ファイル: parse.py プロジェクト: mitra-labs/mitra-lab
 def func(num: BeltNum, _data_type: DataType,
          _: bool) -> BeltNum:
     return num.wrap(_data_type)
コード例 #10
0
ファイル: misc.py プロジェクト: mitra-labs/mitra-lab
 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
コード例 #11
0
ファイル: misc.py プロジェクト: mitra-labs/mitra-lab
 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