diff --git a/phasm/compiler.py b/phasm/compiler.py index 669c8cd..faed2e7 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -194,7 +194,7 @@ def tuple_instantiation(wgn: WasmGenerator, inp: ourlang.TupleInstantiation) -> assert element.type3 == exp_type3 - if isinstance(exp_type3, type3types.AppliedType3) and exp_type3.base is type3types.tuple: + if isinstance(exp_type3, type3types.StructType3) or isinstance(exp_type3, type3types.AppliedType3): mtyp = 'i32' else: assert isinstance(exp_type3, type3types.PrimitiveType3), NotImplementedError('Tuple of applied types / structs') @@ -859,7 +859,7 @@ def _generate_struct_constructor(wgn: WasmGenerator, inp: ourlang.StructConstruc # Store each member individually for memname, mtyp3 in inp.struct_type3.members.items(): mtyp: Optional[str] - if isinstance(mtyp3, type3types.StructType3): + if isinstance(mtyp3, type3types.StructType3) or isinstance(mtyp3, type3types.AppliedType3): mtyp = 'i32' else: mtyp = LOAD_STORE_TYPE_MAP.get(mtyp3.name) diff --git a/phasm/parser.py b/phasm/parser.py index fc1d28f..c6595f8 100644 --- a/phasm/parser.py +++ b/phasm/parser.py @@ -431,7 +431,7 @@ class OurVisitor: arguments = [ self.visit_Module_FunctionDef_expr(module, function, our_locals, arg_node) for arg_node in node.elts - if isinstance(arg_node, (ast.Constant, ast.Tuple, )) + if isinstance(arg_node, (ast.Constant, ast.Tuple, ast.Call, )) ] if len(arguments) != len(node.elts): @@ -655,7 +655,9 @@ class OurVisitor: if not isinstance(node.ctx, ast.Load): _raise_static_error(node, 'Must be load context') - if node.value.id not in type3types.LOOKUP_TABLE: # FIXME: Tuple of tuples? + if ( + node.value.id not in type3types.LOOKUP_TABLE + and node.value.id not in module.struct_definitions): # FIXME: Tuple of tuples? _raise_static_error(node, f'Unrecognized type {node.value.id}') return type3types.AppliedType3( diff --git a/tests/integration/test_lang/generator.py b/tests/integration/test_lang/generator.py index 872dacf..0d9982e 100644 --- a/tests/integration/test_lang/generator.py +++ b/tests/integration/test_lang/generator.py @@ -47,22 +47,26 @@ def generate_assertion_expect_type_error(result, error_msg, error_comment = None result.append(f'assert {repr(error_msg)} == exc_info.value.args[0][0].msg') result.append(f'assert {repr(error_comment)} == exc_info.value.args[0][0].comment') -def json_does_not_support_byte_values_fix(inp: Dict[Any, Any]): - key_names = list(inp) - for key in key_names: - value = inp[key] +def json_does_not_support_byte_or_tuple_values_fix(inp: Any): + if isinstance(inp, (int, float, )): + return inp - if isinstance(value, str): - if value.startswith('bytes:'): - inp[key] = value[6:].encode() - continue + if isinstance(inp, str): + if inp.startswith('bytes:'): + return inp[6:].encode() + return inp - if isinstance(value, dict): - json_does_not_support_byte_values_fix(value) - continue + if isinstance(inp, list): + return tuple(map(json_does_not_support_byte_or_tuple_values_fix, inp)) - if isinstance(value, list): - raise NotImplementedError + if isinstance(inp, dict): + key_names = list(inp) + return { + key: json_does_not_support_byte_or_tuple_values_fix(val) + for key, val in inp.items() + } + + raise NotImplementedError(inp) def generate_assertions(settings, result_code): result = [] @@ -75,13 +79,11 @@ def generate_assertions(settings, result_code): } if 'PYTHON' in settings: - locals_.update(settings['PYTHON']) + locals_.update(json_does_not_support_byte_or_tuple_values_fix(settings['PYTHON'])) if 'VAL0' not in locals_: locals_['VAL0'] = eval(settings['VAL0']) - json_does_not_support_byte_values_fix(locals_) - exec(result_code, {}, locals_) return ' ' + '\n '.join(result) + '\n' diff --git a/tests/integration/test_lang/generator_static_array_with_structs.json b/tests/integration/test_lang/generator_static_array_with_structs.json new file mode 100644 index 0000000..3fff78c --- /dev/null +++ b/tests/integration/test_lang/generator_static_array_with_structs.json @@ -0,0 +1,33 @@ +{ + "TYPE_NAME": "static_array_with_structs", + "TYPE": "StructMain[3]", + "VAL0": "(StructMain(1, (StructCode(-4), 4, 4.0, ), (StructCode(-1), StructCode(-2), )), StructMain(2, (StructCode(-16), 16, 16.0, ), (StructCode(3), StructCode(14), )), StructMain(3, (StructCode(-256), 256, 256.0, ), (StructCode(-9), StructCode(-98), )), )", + "CODE_HEADER": [ + "class StructCode:", + " code: i32", + "", + "class StructMain:", + " val00: u8", + " val01: (StructCode, u64, f32, )", + " val02: StructCode[2]" + ], + "PYTHON": { + "VAL0": [ + { + "val00": 1, + "val01": [{"code": -4}, 4, 4.0], + "val02": [{"code": -1}, {"code": -2}] + }, + { + "val00": 2, + "val01": [{"code": -16}, 16, 16.0], + "val02": [{"code": 3}, {"code": 14}] + }, + { + "val00": 3, + "val01": [{"code": -256}, 256, 256.0], + "val02": [{"code": -9}, {"code": -98}] + } + ] + } +}