Fix: ModuleConstantDef type annotation was ignored

This commit is contained in:
Johan B.W. de Vries 2022-09-19 12:29:48 +02:00
parent 0097ce782d
commit 4f7608a601
4 changed files with 25 additions and 3 deletions

View File

@ -296,17 +296,19 @@ class ModuleConstantDef:
""" """
A constant definition within a module A constant definition within a module
""" """
__slots__ = ('name', 'lineno', 'type_var', 'constant', 'data_block', ) __slots__ = ('name', 'lineno', 'type_str', 'type_var', 'constant', 'data_block', )
name: str name: str
lineno: int lineno: int
type_str: str
type_var: Optional[TypeVar] type_var: Optional[TypeVar]
constant: Constant constant: Constant
data_block: Optional['ModuleDataBlock'] data_block: Optional['ModuleDataBlock']
def __init__(self, name: str, lineno: int, constant: Constant, data_block: Optional['ModuleDataBlock']) -> None: def __init__(self, name: str, lineno: int, type_str: str, constant: Constant, data_block: Optional['ModuleDataBlock']) -> None:
self.name = name self.name = name
self.lineno = lineno self.lineno = lineno
self.type_str = type_str
self.type_var = None self.type_var = None
self.constant = constant self.constant = constant
self.data_block = data_block self.data_block = data_block

View File

@ -201,6 +201,7 @@ class OurVisitor:
return ModuleConstantDef( return ModuleConstantDef(
node.target.id, node.target.id,
node.lineno, node.lineno,
self.visit_type(module, node.annotation),
self.visit_Module_Constant(module, node.value), self.visit_Module_Constant(module, node.value),
None, None,
) )
@ -222,6 +223,7 @@ class OurVisitor:
return ModuleConstantDef( return ModuleConstantDef(
node.target.id, node.target.id,
node.lineno, node.lineno,
self.visit_type(module, node.annotation),
ConstantTuple(tuple_data), ConstantTuple(tuple_data),
data_block, data_block,
) )

View File

@ -125,7 +125,10 @@ def function(ctx: Context, inp: ourlang.Function) -> None:
def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> None: def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> None:
constant(ctx, inp.constant) constant(ctx, inp.constant)
inp.type_var = ctx.new_var() if inp.type_str is None:
inp.type_var = ctx.new_var()
else:
inp.type_var = from_str(ctx, inp.type_str, inp.type_str)
assert inp.constant.type_var is not None assert inp.constant.type_var is not None
ctx.unify(inp.type_var, inp.constant.type_var) ctx.unify(inp.type_var, inp.constant.type_var)

View File

@ -1,5 +1,7 @@
import pytest import pytest
from phasm.exceptions import TypingError
from ..helpers import Suite from ..helpers import Suite
from ..constants import ALL_INT_TYPES, ALL_FLOAT_TYPES, COMPLETE_INT_TYPES, TYPE_MAP from ..constants import ALL_INT_TYPES, ALL_FLOAT_TYPES, COMPLETE_INT_TYPES, TYPE_MAP
@ -61,6 +63,19 @@ def testEntry() -> {type_}:
assert 32.125 == result.returned_value assert 32.125 == result.returned_value
@pytest.mark.integration_test
def test_module_constant_entanglement():
code_py = """
CONSTANT: u8 = 1000
@exported
def testEntry() -> u32:
return 14
"""
with pytest.raises(TypingError, match='u8.*1000'):
Suite(code_py).run_code()
@pytest.mark.integration_test @pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['u32', 'u64']) # FIXME: Support u8, requires an extra AND operation @pytest.mark.parametrize('type_', ['u32', 'u64']) # FIXME: Support u8, requires an extra AND operation
def test_logical_left_shift(type_): def test_logical_left_shift(type_):