Enable use of bytes in constants
Including using them in tuple constants.
This commit is contained in:
parent
20d177e2c5
commit
1536ea0bbb
@ -68,6 +68,9 @@ def expression(inp: ourlang.Expression) -> str:
|
||||
# could not fit in the given float type
|
||||
return str(inp.value)
|
||||
|
||||
if isinstance(inp, ourlang.ConstantBytes):
|
||||
return repr(inp.value)
|
||||
|
||||
if isinstance(inp, ourlang.ConstantTuple):
|
||||
return '(' + ', '.join(
|
||||
expression(x)
|
||||
|
||||
@ -22,6 +22,8 @@ LOAD_STORE_TYPE_MAP = {
|
||||
'u64': 'i64',
|
||||
'f32': 'f32',
|
||||
'f64': 'f64',
|
||||
|
||||
'bytes': 'i32', # Bytes are passed around as pointers
|
||||
}
|
||||
|
||||
def phasm_compile(inp: ourlang.Module) -> wasm.Module:
|
||||
@ -237,7 +239,6 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None:
|
||||
raise NotImplementedError(f'Constants with type {inp.type3:s}')
|
||||
|
||||
if isinstance(inp, ourlang.ConstantBytes):
|
||||
assert inp.data_block is not None, 'Bytes must be memory stored'
|
||||
assert inp.data_block.address is not None, 'Value not allocated'
|
||||
wgn.i32.const(inp.data_block.address)
|
||||
return
|
||||
@ -742,9 +743,18 @@ def module_data(inp: ourlang.ModuleData) -> bytes:
|
||||
continue
|
||||
|
||||
if constant.type3 == type3types.bytes:
|
||||
assert isinstance(constant.value, bytes)
|
||||
data_list.append(module_data_u32(len(constant.value)))
|
||||
data_list.append(constant.value)
|
||||
assert isinstance(constant, ourlang.ConstantBytes)
|
||||
|
||||
if block is not constant.data_block:
|
||||
# It's stored in a different block
|
||||
# We only need to store its address
|
||||
# This happens for example when a tuple refers
|
||||
# to a bytes constant
|
||||
assert constant.data_block.address is not None
|
||||
data_list.append(module_data_u32(constant.data_block.address))
|
||||
else:
|
||||
data_list.append(module_data_u32(len(constant.value)))
|
||||
data_list.append(constant.value)
|
||||
continue
|
||||
|
||||
raise NotImplementedError(constant, constant.type3, constant.value)
|
||||
|
||||
@ -62,6 +62,9 @@ class ConstantBytes(Constant):
|
||||
self.data_block = data_block
|
||||
|
||||
def __repr__(self) -> str:
|
||||
# Do not repr the whole ModuleDataBlock
|
||||
# As this has a reference back to this constant for its data
|
||||
# which it needs to compile the data into the program
|
||||
return f'ConstantBytes({repr(self.value)}, @{repr(self.data_block.address)})'
|
||||
|
||||
class ConstantTuple(Constant):
|
||||
|
||||
@ -42,6 +42,20 @@ def testEntry(f: bytes) -> u8:
|
||||
|
||||
assert 0x61 == result.returned_value
|
||||
|
||||
@pytest.mark.integration_test
|
||||
def test_constant():
|
||||
code_py = """
|
||||
CONSTANT: bytes = b'ABCDEF'
|
||||
|
||||
@exported
|
||||
def testEntry() -> u8:
|
||||
return CONSTANT[0]
|
||||
"""
|
||||
|
||||
result = Suite(code_py).run_code()
|
||||
|
||||
assert 0x41 == result.returned_value
|
||||
|
||||
@pytest.mark.integration_test
|
||||
def test_bytes_index_out_of_bounds():
|
||||
code_py = """
|
||||
|
||||
@ -119,6 +119,26 @@ def testEntry() -> u64:
|
||||
|
||||
assert 128 == result.returned_value
|
||||
|
||||
@pytest.mark.integration_test
|
||||
def test_bytes_as_part_of_tuple():
|
||||
code_py = """
|
||||
CONSTANT: (bytes, u64, ) = (b'ABCDEF', 19, )
|
||||
|
||||
def l0(c: bytes) -> u8:
|
||||
return c[0]
|
||||
|
||||
def l1(c: (bytes, u64, )) -> u8:
|
||||
return l0(c[0])
|
||||
|
||||
@exported
|
||||
def testEntry() -> u8:
|
||||
return l1(CONSTANT)
|
||||
"""
|
||||
|
||||
result = Suite(code_py).run_code()
|
||||
|
||||
assert 0x41 == result.returned_value
|
||||
|
||||
@pytest.mark.integration_test
|
||||
def test_function_call_element_type_mismatch():
|
||||
code_py = """
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user