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
"""
__slots__ = ('name', 'lineno', 'type_var', 'constant', 'data_block', )
__slots__ = ('name', 'lineno', 'type_str', 'type_var', 'constant', 'data_block', )
name: str
lineno: int
type_str: str
type_var: Optional[TypeVar]
constant: Constant
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.lineno = lineno
self.type_str = type_str
self.type_var = None
self.constant = constant
self.data_block = data_block

View File

@ -201,6 +201,7 @@ class OurVisitor:
return ModuleConstantDef(
node.target.id,
node.lineno,
self.visit_type(module, node.annotation),
self.visit_Module_Constant(module, node.value),
None,
)
@ -222,6 +223,7 @@ class OurVisitor:
return ModuleConstantDef(
node.target.id,
node.lineno,
self.visit_type(module, node.annotation),
ConstantTuple(tuple_data),
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:
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
ctx.unify(inp.type_var, inp.constant.type_var)

View File

@ -1,5 +1,7 @@
import pytest
from phasm.exceptions import TypingError
from ..helpers import Suite
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
@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.parametrize('type_', ['u32', 'u64']) # FIXME: Support u8, requires an extra AND operation
def test_logical_left_shift(type_):