def visit(self, node: ast.Case, scope: Scope): t = list(scope.get_types().keys()) t.reverse() def get_by_(tp, l: ast.Action): for i in l: if tp == i.action_type: return i k = [] for i in t: n = get_by_(i, node.actions) if n: k.append(n) node.actions = k self.visit(node.expr, scope) list_type = [] for item in node.actions: list_type.append(self.visit(item, scope)) return_type = list_type[0] for item in list_type[1:]: if return_type.name == 'SELF_TYPE' and item.name == 'SELF_TYPE': continue elif return_type.name == 'SELF_TYPE': return_type = scope.join(scope.getType(scope.classname), item) elif item.name == 'SELF_TYPE': return_type = scope.join(scope.getType(scope.classname), return_type) else: return_type = scope.join(return_type, item) node.static_type = return_type return return_type
def visit(self, node: ast.Program, _): scope_root = Scope(None, None) for classDef in node.classes: new_type = ctype(classDef.name) scope_root.createType(new_type) for classDef in node.classes: a = scope_root.getType(classDef.name) a.parent = scope_root.getType(classDef.parent) new_types = self.sort_type(scope_root.get_types()) node.classes = list( map(lambda x: self.get_node_by_type(x, node.classes), list(new_types.keys())[6:])) scope_root.set_types(new_types) self.check_ciclic_inheritance(scope_root.get_types()) scopes = [] for j in node.classes: scope = Scope(j.name, scope_root) methods = filter(lambda x: type(x) is ast.ClassMethod, j.features) methods = list(methods) attribs = filter(lambda x: type(x) is ast.ClassAttribute, j.features) attribs = list(attribs) p_type = scope.getType(j.parent) if p_type.name in ['Int', 'Bool', 'String']: raise CheckSemanticError( f'Any type can\'t inheriths from {p_type}') for i in p_type.attributes: try: scope.getType(j.name).add_attrib(i) except Exception as e: raise e try: scope.defineAttrib(list(i.keys())[0], list(i.values())[0]) except Exception as e: raise e for i in attribs: try: scope.getType(j.name).add_attrib( {i.name: scope.getType(i.attr_type)}) except Exception as e: raise e try: scope.defineAttrib(i.name, scope.getType(i.attr_type)) except Exception as e: raise e for i in methods: try: scope.getType(j.name).add_method({ i.name: { 'formal_params': { t.name: scope.getType(t.param_type) for t in i.formal_params }, 'return_type': scope.getType(i.return_type), 'body': i.body } }) except Exception as e: raise e scopes.append(scope) for i in range(len(node.classes)): self.visit(node.classes[i], scopes[i]) return scope_root