66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
from typing import Any, Generator
|
|
|
|
from .. import ourlang
|
|
from .constraints import (
|
|
ConstraintBase,
|
|
Context,
|
|
LiteralFitsConstraint,
|
|
UnifyTypesConstraint,
|
|
)
|
|
from .typeexpr import TypeVariable
|
|
|
|
ConstraintGenerator = Generator[ConstraintBase, None, None]
|
|
|
|
|
|
def phasm_type5_generate_constraints(ctx: Context, inp: ourlang.Module[Any]) -> list[ConstraintBase]:
|
|
return [*module(ctx, inp)]
|
|
|
|
def constant(ctx: Context, inp: ourlang.Constant, phft: TypeVariable) -> ConstraintGenerator:
|
|
if isinstance(inp, (ourlang.ConstantPrimitive, ourlang.ConstantBytes, ourlang.ConstantTuple, ourlang.ConstantStruct)):
|
|
yield LiteralFitsConstraint(
|
|
ctx, phft, inp,
|
|
comment='The given literal must fit the expected type'
|
|
)
|
|
return
|
|
|
|
raise NotImplementedError(constant, inp)
|
|
|
|
def expression(ctx: Context, inp: ourlang.Expression, phft: TypeVariable) -> ConstraintGenerator:
|
|
raise NotImplementedError(inp)
|
|
|
|
def statement_return(ctx: Context, fun: ourlang.Function, inp: ourlang.StatementReturn) -> ConstraintGenerator:
|
|
phft = ctx.make_placeholder(inp.value)
|
|
|
|
yield from expression(ctx, inp.value, phft)
|
|
|
|
yield UnifyTypesConstraint(ctx, fun.returns_type5, phft)
|
|
|
|
def statement(ctx: Context, fun: ourlang.Function, inp: ourlang.Statement) -> ConstraintGenerator:
|
|
if isinstance(inp, ourlang.StatementReturn):
|
|
yield from statement_return(ctx, fun, inp)
|
|
return
|
|
|
|
raise NotImplementedError(inp)
|
|
|
|
def function(ctx: Context, inp: ourlang.Function) -> ConstraintGenerator:
|
|
for stmt in inp.statements:
|
|
yield from statement(ctx, inp, stmt)
|
|
|
|
def module_constant_def(ctx: Context, inp: ourlang.ModuleConstantDef) -> ConstraintGenerator:
|
|
phft = ctx.make_placeholder(inp.constant)
|
|
|
|
yield from constant(ctx, inp.constant, phft)
|
|
yield UnifyTypesConstraint(ctx, inp.type5, phft)
|
|
|
|
def module(ctx: Context, inp: ourlang.Module[Any]) -> ConstraintGenerator:
|
|
for cdef in inp.constant_defs.values():
|
|
yield from module_constant_def(ctx, cdef)
|
|
|
|
for func in inp.functions.values():
|
|
if func.imported:
|
|
continue
|
|
|
|
yield from function(ctx, func)
|
|
|
|
# TODO: Generalize?
|