Bit shifting
This commit is contained in:
parent
75d7e05519
commit
d051160244
@ -82,7 +82,7 @@ _CRC32_Table: u32[256] = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
def _crc32_f(crc: u32, byt: u8) -> u32:
|
def _crc32_f(crc: u32, byt: u8) -> u32:
|
||||||
return (crc >> 8) ^ _CRC32_Table[(crc & 0xFF) ^ byt]
|
return (crc >> 8) ^ _CRC32_Table[(crc & 0xFF) ^ u32(byt)]
|
||||||
|
|
||||||
@exported
|
@exported
|
||||||
def crc32(data: bytes) -> u32:
|
def crc32(data: bytes) -> u32:
|
||||||
|
|||||||
@ -77,8 +77,11 @@ OPERATOR_MAP = {
|
|||||||
|
|
||||||
U8_OPERATOR_MAP = {
|
U8_OPERATOR_MAP = {
|
||||||
# Under the hood, this is an i32
|
# Under the hood, this is an i32
|
||||||
# Implementing XOR, OR, AND is fine since the 3 remaining
|
# Implementing Right Shift XOR, OR, AND is fine since the 3 remaining
|
||||||
# bytes stay zero after this operation
|
# bytes stay zero after this operation
|
||||||
|
# Since it's unsigned an unsigned value, Logical or Arithmetic shift right
|
||||||
|
# are the same operation
|
||||||
|
'>>': 'shr_u',
|
||||||
'^': 'xor',
|
'^': 'xor',
|
||||||
'|': 'or',
|
'|': 'or',
|
||||||
'&': 'and',
|
'&': 'and',
|
||||||
@ -89,6 +92,8 @@ U32_OPERATOR_MAP = {
|
|||||||
'>': 'gt_u',
|
'>': 'gt_u',
|
||||||
'<=': 'le_u',
|
'<=': 'le_u',
|
||||||
'>=': 'ge_u',
|
'>=': 'ge_u',
|
||||||
|
'<<': 'shl',
|
||||||
|
'>>': 'shr_u',
|
||||||
'^': 'xor',
|
'^': 'xor',
|
||||||
'|': 'or',
|
'|': 'or',
|
||||||
'&': 'and',
|
'&': 'and',
|
||||||
@ -99,6 +104,8 @@ U64_OPERATOR_MAP = {
|
|||||||
'>': 'gt_u',
|
'>': 'gt_u',
|
||||||
'<=': 'le_u',
|
'<=': 'le_u',
|
||||||
'>=': 'ge_u',
|
'>=': 'ge_u',
|
||||||
|
'<<': 'shl',
|
||||||
|
'>>': 'shr_u',
|
||||||
'^': 'xor',
|
'^': 'xor',
|
||||||
'|': 'or',
|
'|': 'or',
|
||||||
'&': 'and',
|
'&': 'and',
|
||||||
|
|||||||
@ -244,6 +244,10 @@ class OurVisitor:
|
|||||||
operator = '-'
|
operator = '-'
|
||||||
elif isinstance(node.op, ast.Mult):
|
elif isinstance(node.op, ast.Mult):
|
||||||
operator = '*'
|
operator = '*'
|
||||||
|
elif isinstance(node.op, ast.LShift):
|
||||||
|
operator = '<<'
|
||||||
|
elif isinstance(node.op, ast.RShift):
|
||||||
|
operator = '>>'
|
||||||
elif isinstance(node.op, ast.BitOr):
|
elif isinstance(node.op, ast.BitOr):
|
||||||
operator = '|'
|
operator = '|'
|
||||||
elif isinstance(node.op, ast.BitXor):
|
elif isinstance(node.op, ast.BitXor):
|
||||||
@ -433,16 +437,14 @@ class OurVisitor:
|
|||||||
if func.returns.__class__ != func.posonlyargs[0][1].__class__:
|
if func.returns.__class__ != func.posonlyargs[0][1].__class__:
|
||||||
_raise_static_error(node, f'Expected a foldable function, {func.name} returns a {codestyle.type_(func.returns)} but expects a {codestyle.type_(func.posonlyargs[0][1])}')
|
_raise_static_error(node, f'Expected a foldable function, {func.name} returns a {codestyle.type_(func.returns)} but expects a {codestyle.type_(func.posonlyargs[0][1])}')
|
||||||
|
|
||||||
t_u8 = module.types['u8']
|
if module.types['u8'].__class__ != func.posonlyargs[1][1].__class__:
|
||||||
|
|
||||||
if t_u8.__class__ != func.posonlyargs[1][1].__class__:
|
|
||||||
_raise_static_error(node, 'Only folding over bytes (u8) is supported at this time')
|
_raise_static_error(node, 'Only folding over bytes (u8) is supported at this time')
|
||||||
|
|
||||||
return Fold(
|
return Fold(
|
||||||
exp_type,
|
exp_type,
|
||||||
Fold.Direction.LEFT,
|
Fold.Direction.LEFT,
|
||||||
func,
|
func,
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, t_u8, node.args[1]),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, func.returns, node.args[1]),
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, module.types['bytes'], node.args[2]),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, module.types['bytes'], node.args[2]),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -550,7 +552,7 @@ class OurVisitor:
|
|||||||
_raise_static_error(node, 'Expected integer value')
|
_raise_static_error(node, 'Expected integer value')
|
||||||
|
|
||||||
if node.value < 0 or node.value > 255:
|
if node.value < 0 or node.value > 255:
|
||||||
_raise_static_error(node, 'Integer value out of range')
|
_raise_static_error(node, f'Integer value out of range; expected 0..255, actual {node.value}')
|
||||||
|
|
||||||
return ConstantUInt8(exp_type, node.value)
|
return ConstantUInt8(exp_type, node.value)
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,34 @@ def testEntry() -> {type_}:
|
|||||||
assert 7 == result.returned_value
|
assert 7 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
@pytest.mark.parametrize('type_', ['u32', 'u64']) # FIXME: Support u8, requires an extra AND operation
|
||||||
|
def test_logical_left_shift(type_):
|
||||||
|
code_py = f"""
|
||||||
|
@exported
|
||||||
|
def testEntry() -> {type_}:
|
||||||
|
return 10 << 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
|
assert 80 == result.returned_value
|
||||||
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
||||||
|
def test_logical_right_shift(type_):
|
||||||
|
code_py = f"""
|
||||||
|
@exported
|
||||||
|
def testEntry() -> {type_}:
|
||||||
|
return 10 >> 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
|
assert 1 == result.returned_value
|
||||||
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
||||||
def test_bitwise_or(type_):
|
def test_bitwise_or(type_):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user