56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
"""Definitions for the semantics segment of the Cretonne language."""
|
|
from cdsl.ti import TypeEnv, ti_rtl, get_type_env
|
|
|
|
try:
|
|
from typing import List, Dict, Tuple # noqa
|
|
from cdsl.ast import Var # noqa
|
|
from cdsl.xform import XForm # noqa
|
|
from cdsl.ti import VarTyping # noqa
|
|
from cdsl.instructions import Instruction, InstructionSemantics # noqa
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
def verify_semantics(inst, sem):
|
|
# type: (Instruction, InstructionSemantics) -> None
|
|
"""
|
|
Verify that the semantics sem correctly describes the instruction inst.
|
|
This involves checking that:
|
|
1) For all XForms x \in sem, x.src consists of a single instance of
|
|
inst
|
|
2) For any possible concrete typing of inst there is exactly 1 XForm x
|
|
in sem that applies.
|
|
"""
|
|
# 1) The source rtl is always a single instance of inst.
|
|
for xform in sem:
|
|
assert len(xform.src.rtl) == 1 and\
|
|
xform.src.rtl[0].expr.inst == inst,\
|
|
"XForm {} doesn't describe instruction {}."\
|
|
.format(xform, inst)
|
|
|
|
# 2) Any possible typing for the instruction should be covered by
|
|
# exactly ONE semantic XForm
|
|
inst_rtl = sem[0].src
|
|
typenv = get_type_env(ti_rtl(inst_rtl, TypeEnv()))
|
|
|
|
# This bit is awkward. Concrete typing is defined in terms of the vars
|
|
# of one Rtl. We arbitrarily picked that Rtl to be sem[0].src. For any
|
|
# other XForms in sem, we must build a substitution form
|
|
# sem[0].src->sem[N].src, before we can check if sem[N] permits one of
|
|
# the concrete typings of our Rtl.
|
|
# TODO: Can this be made cleaner?
|
|
subst = [inst_rtl.substitution(x.src, {}) for x in sem]
|
|
assert not any(x is None for x in subst)
|
|
sub_sem = list(zip(subst, sem)) # type: List[Tuple[Dict[Var, Var], XForm]] # noqa
|
|
|
|
def subst_typing(typing, sub):
|
|
# type: (VarTyping, Dict[Var, Var]) -> VarTyping
|
|
return {sub[v]: tv for (v, tv) in typing.items()}
|
|
|
|
for t in typenv.concrete_typings():
|
|
matching_xforms = [x for (s, x) in sub_sem
|
|
if x.ti.permits(subst_typing(t, s))]
|
|
assert len(matching_xforms) == 1,\
|
|
("Possible typing {} of {} not matched by exactly one case " +
|
|
": {}").format(t, inst, matching_xforms)
|