From de925043944df21dab2f7fa5cbb2f2ad32963ec9 Mon Sep 17 00:00:00 2001 From: "Johan B.W. de Vries" Date: Fri, 10 Nov 2023 15:02:07 +0100 Subject: [PATCH] Cleanup: DataBlock as part of the constants As they can refer to other constants which are stored in memory. --- phasm/compiler.py | 41 +++++++++++++++++++++++++---------------- phasm/ourlang.py | 32 ++++++++++++++++++++------------ phasm/parser.py | 12 ++---------- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/phasm/compiler.py b/phasm/compiler.py index b4ebd20..127f779 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -251,37 +251,46 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None: if isinstance(inp.variable, ourlang.ModuleConstantDef): assert isinstance(inp.type3, type3types.Type3), type3types.TYPE3_ASSERTION_ERROR + if isinstance(inp.type3, type3types.PrimitiveType3): + expression(wgn, inp.variable.constant) + return + if inp.type3 is type3types.bytes: - assert inp.variable.data_block is not None, 'Bytes must be memory stored' - assert inp.variable.data_block.address is not None, 'Value not allocated' - wgn.i32.const(inp.variable.data_block.address) + assert isinstance(inp.variable.constant, ourlang.ConstantBytes) + + address = inp.variable.constant.data_block.address + assert address is not None, 'Value not allocated' + wgn.i32.const(address) return if isinstance(inp.type3, type3types.StructType3): - assert inp.variable.data_block is not None, 'Structs must be memory stored' - assert inp.variable.data_block.address is not None, 'Value not allocated' - wgn.i32.const(inp.variable.data_block.address) + assert isinstance(inp.variable.constant, ourlang.ConstantStruct) + + address = inp.variable.constant.data_block.address + assert address is not None, 'Value not allocated' + wgn.i32.const(address) return if isinstance(inp.type3, type3types.AppliedType3): if inp.type3.base == type3types.static_array: - assert inp.variable.data_block is not None, 'Static arrays must be memory stored' - assert inp.variable.data_block.address is not None, 'Value not allocated' - wgn.i32.const(inp.variable.data_block.address) + assert isinstance(inp.variable.constant, ourlang.ConstantTuple) + + address = inp.variable.constant.data_block.address + assert address is not None, 'Value not allocated' + wgn.i32.const(address) return if inp.type3.base == type3types.tuple: - assert inp.variable.data_block is not None, 'Tuples must be memory stored' - assert inp.variable.data_block.address is not None, 'Value not allocated' - wgn.i32.const(inp.variable.data_block.address) + assert isinstance(inp.variable.constant, ourlang.ConstantTuple) + + address = inp.variable.constant.data_block.address + assert address is not None, 'Value not allocated' + wgn.i32.const(address) return raise NotImplementedError(expression, inp.variable, inp.type3.base) - assert inp.variable.data_block is None, 'Primitives are not memory stored' - - expression(wgn, inp.variable.constant) - return + raise NotImplementedError(expression, inp) raise NotImplementedError(expression, inp.variable) diff --git a/phasm/ourlang.py b/phasm/ourlang.py index d3ca565..a301450 100644 --- a/phasm/ourlang.py +++ b/phasm/ourlang.py @@ -71,33 +71,43 @@ class ConstantTuple(Constant): """ A Tuple constant value expression within a statement """ - __slots__ = ('value', ) + __slots__ = ('value', 'data_block', ) - value: List[Union[ConstantPrimitive, ConstantBytes]] + value: List[Union[ConstantPrimitive, ConstantBytes]] # FIXME: Tuple of tuples? + data_block: 'ModuleDataBlock' - def __init__(self, value: List[Union[ConstantPrimitive, ConstantBytes]]) -> None: # FIXME: Tuple of tuples? + def __init__(self, value: List[Union[ConstantPrimitive, ConstantBytes]], data_block: 'ModuleDataBlock') -> None: super().__init__() self.value = value + self.data_block = data_block def __repr__(self) -> str: - return f'ConstantTuple({repr(self.value)})' + # 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'ConstantTuple({repr(self.value)}, @{repr(self.data_block.address)})' class ConstantStruct(Constant): """ A Struct constant value expression within a statement """ - __slots__ = ('struct_name', 'value', ) + __slots__ = ('struct_name', 'value', 'data_block', ) struct_name: str - value: List[Union[ConstantPrimitive, ConstantBytes]] + value: List[Union[ConstantPrimitive, ConstantBytes]] # FIXME: Struct of structs? + data_block: 'ModuleDataBlock' - def __init__(self, struct_name: str, value: List[Union[ConstantPrimitive, ConstantBytes]]) -> None: # FIXME: Struct of structs? + def __init__(self, struct_name: str, value: List[Union[ConstantPrimitive, ConstantBytes]], data_block: 'ModuleDataBlock') -> None: super().__init__() self.struct_name = struct_name self.value = value + self.data_block = data_block def __repr__(self) -> str: - return f'ConstantStruct({repr(self.struct_name)}, {repr(self.value)})' + # 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'ConstantStruct({repr(self.struct_name)}, {repr(self.value)}, @{repr(self.data_block.address)})' class VariableReference(Expression): """ @@ -347,20 +357,18 @@ class ModuleConstantDef: """ A constant definition within a module """ - __slots__ = ('name', 'lineno', 'type3', 'constant', 'data_block', ) + __slots__ = ('name', 'lineno', 'type3', 'constant', ) name: str lineno: int type3: Type3 constant: Constant - data_block: Optional['ModuleDataBlock'] - def __init__(self, name: str, lineno: int, type3: Type3, constant: Constant, data_block: Optional['ModuleDataBlock']) -> None: + def __init__(self, name: str, lineno: int, type3: Type3, constant: Constant) -> None: self.name = name self.lineno = lineno self.type3 = type3 self.constant = constant - self.data_block = data_block class ModuleDataBlock: """ diff --git a/phasm/parser.py b/phasm/parser.py index 6e38628..1d6b0a0 100644 --- a/phasm/parser.py +++ b/phasm/parser.py @@ -211,17 +211,11 @@ class OurVisitor: value_data = self.visit_Module_Constant(module, node.value) - if isinstance(value_data, ConstantBytes): - data_block = value_data.data_block - else: - data_block = None - return ModuleConstantDef( node.target.id, node.lineno, type3, value_data, - data_block, ) if isinstance(node.value, ast.Tuple): @@ -242,8 +236,7 @@ class OurVisitor: node.target.id, node.lineno, self.visit_type(module, node.annotation), - ConstantTuple(tuple_data), - data_block, + ConstantTuple(tuple_data, data_block), ) if isinstance(node.value, ast.Call): @@ -281,8 +274,7 @@ class OurVisitor: node.target.id, node.lineno, self.visit_type(module, node.annotation), - ConstantStruct(node.value.func.id, struct_data), - data_block, + ConstantStruct(node.value.func.id, struct_data, data_block), ) raise NotImplementedError(f'{node} on Module AnnAssign')