def _check_kind(node, expected): """ Verify that the kind of node is as expected (a subtype of one of them). Returns the first kind from expected fitting node. """ loc = node._location actual = node._kind #No approximation first if actual in expected: return actual for k in expected: if is_sub(actual, k): return k #Actual is not correct if len(expected) == 0: internal_error("No expected type.") if isinstance(node, Alias): msg1 = "This value, resolved to {},".format(node._is_alias_of._qname) elif isinstance(node, Ident): msg1 = "This value, resolved to {},".format(node._qname) else: msg1 = "This value" if len(expected) == 1: error(msg1+" is of type {},\nwhen a value of type {} is expected." "".format(actual, expected[0]), loc) else: error(msg1+" is of type {},\n" "when a value of type among the following set is expected\n" "{{{}}}".format(actual, ', '.join(expected)), loc)
def publication(visitor, pub, acc): """ Publication are not recursives """ node, maping = acc top = pub['TOPIC'] if top._qname in maping: error("Topic {} has multiple publisher.".format(top), top._location) maping[top._qname] = Ident.of(node) return pub, (node, maping)
def f(value, loc): try: if not fun(value, size): error("The value {} doesn't fit in the {}bits of {}." "".format(str(value), size, t), loc) except ValueError: error("A value of type {} is expected." "".format(t), loc)
def _type_term(node, mk, expected): """ Compute and check the type of a rast term (node, ident, alias, None). If the node was user annotated, do not change the type, only check it. """ if not node: pass #checking the type of a phantom node (None is a valid leaf). #Check the kind to be expected kind = _check_kind(node, expected) #Compute the type if mk == 'type': # Use the language checkers if it exists. check = language.check_type.get(kind, None) if check: check(node._val, node._location) t = kind elif mk == 'class' and node._kind == 'array': def check_el(el, ex_t): elt = of(el) if not is_sub(elt, ex_t): error("This array element has type {} when {} is expected." "".format(str(elt), str(ex_t)), el._location) expected_t = node['TYPE'] expected_size = node['SIZE'] values = node['VALUES'] # check size if expected_size and len(values) != int(expected_size._val): error("This array is of size {} when {} is expected." "".format(len(values), expected_size._val), node._location) # use first element if no expected_elem_t is found if not expected_t: expected_t = of(values[0]) else: expected_t = expected_t._val check_el(values[0], expected_t) for el in values[1:]: check_el(el, expected_t) t = ArrayType(len(values), expected_t) elif mk == 'class' and (node._kind in ('struct', 'topic')): fields = (((f._name, of(f)) for f in node['FIELDS'])) t = StructType(False, tuple(fields)) else: """ Generic class of the AST, we are doing type 2 (see ASTdump), so we flatten the node and doesn't keep 'False' (None) nodes. """ l = flatten_children(node) l_noident = [c for c in l if c and not isinstance(c, Ident)] if l_noident: t = StructType(True, ((c._name, of(c)) for c in l_noident)) else: t = EmptyType() #Store the computed type node._type = t
def check_el(el, ex_t): elt = of(el) if not is_sub(elt, ex_t): error("This array element has type {} when {} is expected." "".format(str(elt), str(ex_t)), el._location)
def mark_term(term, deps): qn = term._qname if qn in deps: error("The term {} depends on itself.".format(qn), term._location) else: return deps + [qn]