コード例 #1
0
 def visit(self, node: ast.StaticDispatch, scope: Scope):
     instance_type = self.visit(node.instance, scope)
     class_type = scope.getType(node.dispatch_type)
     if instance_type.name == 'SELF_TYPE':
         instance_type = scope.getType(scope.classname)
     if not instance_type < class_type:
         raise CheckSemanticError(
             f'type {str(instance_type)} is not a {str(class_type)}')
     if not class_type.is_method(node.method):
         raise CheckSemanticError(f'method {node.method} not defined')
     args_type = class_type.get_method_args(node.method)
     if len(args_type) != len(node.arguments):
         raise CheckSemanticError(
             f'{node.method} require {len(args_type)} arguments')
     for i in range(len(args_type)):
         t = self.visit(node.arguments[i], scope)
         if not t < args_type[i]:
             raise CheckSemanticError(
                 f'{str(t)} doesn\'t conform {str(args_type[i])}')
     method = class_type.get_method(node.method)
     r_type = method[node.method]['return_type']
     if r_type.name == 'SELF_TYPE':
         node.static_type = class_type
         return class_type
     node.static_type = r_type
     return r_type
コード例 #2
0
 def visit(self, node:ast.ClassMethod, scope:Scope, errors):
     for i in node.formal_params:
         try:
             scope.defineSymbol(i.name, scope.getType(i.param_type))
         except Exception as e:
             print(e)
     tb = self.visit(node.body, scope, error)
     if not tb < scope.getType(node.return_type):
         raise CheckSemanticError(f'{tb} doesn\'t conform {node.return_type}')
     return scope.getType(node.return_type)
コード例 #3
0
    def visit(self, node:ast.Program, scope:Scope, errors):
        for classDef in node.classes:
            attribs = filter(lambda x: type(x) is ast.ClassAttribute, classDef)
            attribs = list(attribs)
            newType = ctype(classDef.name, classDef.parent, [], [])
            try:
                scope.createType(newType)
            except Exception as e:
                print(str(e))

        for i in node.classes:
            t = self.visit(i, Scope(i.name, scope), errors)
コード例 #4
0
 def visit(self, node:ast.Case, scope:Scope, errors):
     self.visit(node.expr, scope, errors)
     listType = []
     for item in node.actions:
         try:
             scope.getType(item.action_type)
         except Exception as e:
             print(e)
         listType.append(self.visit(item, scope, errors))
     returnType = listType[0]
     for item in listType[1:]:
         returnType = scope.join(returnType, item)
     return returnType
コード例 #5
0
 def visit(self, node: ast.Equal, scope: Scope):
     left_type = self.visit(node.first, scope)
     right_type = self.visit(node.second, scope)
     if left_type.name == 'SELF_TYPE':
         left_type = scope.getType(scope.classname)
     if right_type.name == 'SELF_TYPE':
         right_type = scope.getType(scope.classname)
     if not left_type.name == right_type.name:
         raise CheckSemanticError(
             f'In equal expressions type must be the same type')
     bool_type = scope.getType('Bool')
     node.static_type = bool_type
     return bool_type
コード例 #6
0
 def visit(self, node: ast.Assignment, scope: Scope):
     instance_type = scope.getTypeFor(node.instance.name)
     expr_type = self.visit(node.expr, scope)
     if expr_type.name == 'SELF_TYPE':
         r_type = scope.getType(scope.classname)
         if r_type < instance_type:
             return r_type
         raise CheckSemanticError(
             f'{r_type} doesn\'t conform {instance_type}')
     if not expr_type < instance_type:
         raise CheckSemanticError(
             f'{expr_type} doesn\'t conform {instance_type}')
     node.static_type = expr_type
     return expr_type
コード例 #7
0
 def visit(self, node:ast.StaticDispatch, scope:Scope, errors):
     instanceType = scope.getTypeFor(node.instance)
     classType = scope.getType(node.dispatch_type)
     if not instanceType < :
         raise CheckSemanticError(f'type {instanceType} is not a {node.dispatch_type}')
     if not classType.is_method(node.method):
        raise CheckSemanticError(f'method {node.method} not defined')
     argsType = classType.get_method_args(node.method)
     if len(argsType) != len(node.arguments):
         raise CheckSemanticError(f'{node.method} require {len(argsType)} arguments')
     for x, y in argsType, node.arguments:
         t = self.visit(y, scope, errors)
         if not t < x:
             raise CheckSemanticError(f'{str(t)} doesn\'t conform {str(x)}')
     method = classType.get_method(node.method)
     return  method.return_type
コード例 #8
0
 def visit(self, node: ast.LessThan, scope: Scope):
     left_type = self.visit(node.first, scope)
     right_type = self.visit(node.second, scope)
     if not left_type.name == 'Int' or not right_type.name == 'Int':
         raise CheckSemanticError(f'expressions type must be Int')
     bool_type = scope.getType('Bool')
     return bool_type
コード例 #9
0
 def visit(self, node: ast.Let, scope: Scope):
     new_scope = Scope(scope.classname, scope)
     for decl in node.declarations:
         self.visit(decl, new_scope)
     b_type = self.visit(node.body, new_scope)
     node.static_type = b_type
     return b_type
コード例 #10
0
 def visit(self, node: ast.IntegerComplement, scope: Scope):
     exp_type = self.visit(node.integer_expr, scope)
     if not exp_type.name == "Int":
         raise CheckSemanticError(f'{exp_type.name} doest\' match with Int')
     int_type = scope.getType('Int')
     node.static_type = int_type
     return int_type
コード例 #11
0
 def visit(self, node: ast.BooleanComplement, scope: Scope):
     exp_type = self.visit(node.boolean_expr, scope)
     if not exp_type.name == 'Bool':
         raise CheckSemanticError(f'{exp_type.name} doest\' match wiht Int')
     bool_type = scope.getType('Bool')
     node.static_type = bool_type
     return bool_type
コード例 #12
0
 def visit(self, node:ast.If, scope:Scope, errors):
     predType = self.visit(node.predicate, scope, errors)
     if not predType.name == "Bool":
         raise CheckSemanticError(f'you can\'t match {predType.name} with Bool')
     ifType = self.visit(node.then_body, scope, errors)
     elseType = self.visit(node.else_body, scope, errors)
     return scope.join(ifType, elseType)
コード例 #13
0
 def visit(self, node: ast.Division, scope: Scope):
     left_type = self.visit(node.first, scope)
     right_type = self.visit(node.second, scope)
     if not left_type.name == 'Int' or not right_type.name == 'Int':
         raise CheckSemanticError(f'expressions type must be Int')
     int_type = scope.getType('Int')
     node.static_type = int_type
     return int_type
コード例 #14
0
 def visit(self, node:ast.Let, scope:Scope, errors):
     newScope = Scope(scope.classname, scope)
     for decl in node.init_expr :
         try:
             self.visit(decl, newScope, errors)
         except Exception as e:
             print(e)
     return self.visit(node.body, newScope, errors)
コード例 #15
0
 def visit(self, node: ast.Action, scope: Scope):
     scope.getType(node.action_type)
     new_scope = Scope(scope.classname, scope)
     new_scope.defineSymbol(node.name, scope.getType(node.action_type))
     return_type = self.visit(node.body, new_scope)
     node.static_type = return_type
     return return_type
コード例 #16
0
 def visit(self, node: ast.ClassAttribute, scope: Scope):
     node.static_type = scope.getType(node.attr_type)
     if node.init_expr:
         t_exp = self.visit(node.init_expr, scope)
         if node.attr_type != 'SELF_TYPE':
             if t_exp.name == 'SELF_TYPE':
                 raise CheckSemanticError(
                     f'You can\'t not assign a SELF_TYPE expression in a non SELF_TYPE'
                     f'attribute')
             if not t_exp < scope.getType(node.attr_type):
                 raise CheckSemanticError(
                     f'{str(t_exp)} doesn\'t conform {str(scope.getType(node.attr_type))}'
                 )
         else:
             if t_exp.name == 'SELF_TYPE':
                 raise CheckSemanticError(
                     f'Attribute {node.name} of type {node.attr_type} must to be instanced'
                     f' by a SELF_type expression.')
コード例 #17
0
 def visit(self, node:ast.Assignment, scope:Scope, errors):
     try:
         instanceType = scope.getTypeFor(node.instance.name)
         exprType = self.visit(node.expr, scope, errors)
         if not instanceType < exprType :
             raise CheckSemanticError(f'{tb} doesn\'t conform {node.return_type}')
         return exprType
     except:
         raise CheckSemanticError(f'Symbol {node.instance.name} not defined in the Scope.')
コード例 #18
0
 def visit(self, node: ast.WhileLoop, scope: Scope):
     pred_type = self.visit(node.predicate, scope)
     if not pred_type.name == "Bool":
         raise CheckSemanticError(
             f'you can\'t match {pred_type.name} with Bool')
     self.visit(node.body, scope)
     object_type = scope.getType('Object')
     node.static_type = object_type
     return object_type
コード例 #19
0
    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
コード例 #20
0
 def visit(self, node: ast.If, scope: Scope):
     pred_type = self.visit(node.predicate, scope)
     if not pred_type.name == "Bool":
         raise CheckSemanticError(
             f'you can\'t match {pred_type.name} with Bool')
     if_type = self.visit(node.then_body, scope)
     else_type = self.visit(node.else_body, scope)
     if if_type.name == 'SELF_TYPE' and if_type.name == 'SELF_TYPE':
         node.static_type = if_type
         return if_type
     elif if_type.name == 'SELF_TYPE':
         return_type = scope.join(else_type, scope.getType(scope.classname))
         node.static_type = return_type
         return return_type
     elif else_type.name == 'SELF_TYPE':
         return_type = scope.join(if_type, scope.getType(scope.classname))
         node.static_type = return_type
         return return_type
     else:
         return_type = scope.join(if_type, else_type)
         node.static_type = return_type
         return return_type
コード例 #21
0
class CheckSemantic:
    @visitor.on('AST')
    def visit(self, node, scope, errors):
        pass

    @visitor.when(ast.Program)
    def visit(self, node:ast.Program, scope:Scope, errors):
        for classDef in node.classes:
            attribs = filter(lambda x: type(x) is ast.ClassAttribute, classDef)
            attribs = list(attribs)
            newType = ctype(classDef.name, classDef.parent, [], [])
            try:
                scope.createType(newType)
            except Exception as e:
                print(str(e))

        for i in node.classes:
            t = self.visit(i, Scope(i.name, scope), errors)

    @visitor.when(ast.Class)
    def visit(self, node:ast.Class, scope:Scope, errors):
        methods = filter(lambda x: type(x) is ast.ClassMethod, classDef)
        methods = list(methods)
        attribs = filter(lambda x: type(x) is ast.ClassAttribute, classDef)
        attribs = list(attribs)
        for i in attribs:
            ta = self.visit(i, scope, errors)
            try:
                scope.getType(node.name).add_attrib({i.name: scope.getType(i.attr_type)})
            except Exception as e:
                print(e)
        for i in methods:
            try:
                scope.getType(node.name).add_method({i.name:{
                    'formal_params':{
                        t.name: scope.getType(t.param_type) for j in i.formal_params
                    },
                    'return_type': scope.getType(i.return_type),
                    'body': i.body
                }})
            exec Exception as e:
                print(e)
        for i in methods:
            tb = self.visit(i, Scope(scope.classname, scope), errors)
コード例 #22
0
 def visit(self, node: ast.ClassMethod, scope: Scope):
     node.static_type = scope.getType(node.return_type)
     for i in node.formal_params:
         scope.defineSymbol(i.name, scope.getType(i.param_type))
     tb = self.visit(node.body, scope)
     if tb.name == 'SELF_TYPE' and node.return_type == 'SELF_TYPE':
         return scope.classname
     elif tb.name == 'SELF_TYPE':
         if scope.getType(scope.classname) < node.static_type:
             return node.static_type
         else:
             raise CheckSemanticError(
                 f'{scope.getType(scope.classname)} doesn\'t conform {node.static_type}'
             )
     elif node.return_type == 'SELF_TYPE':
         raise CheckSemanticError(
             f'Method {node.name} returns SELF_TYPE and body doesn\'t')
     if not tb < scope.getType(node.return_type):
         raise CheckSemanticError(
             f'{tb} doesn\'t conform {node.return_type}')
     return scope.getType(node.return_type)
コード例 #23
0
 def visit(self, node:ast.Class, scope:Scope, errors):
     methods = filter(lambda x: type(x) is ast.ClassMethod, classDef)
     methods = list(methods)
     attribs = filter(lambda x: type(x) is ast.ClassAttribute, classDef)
     attribs = list(attribs)
     for i in attribs:
         ta = self.visit(i, scope, errors)
         try:
             scope.getType(node.name).add_attrib({i.name: scope.getType(i.attr_type)})
         except Exception as e:
             print(e)
     for i in methods:
         try:
             scope.getType(node.name).add_method({i.name:{
                 'formal_params':{
                     t.name: scope.getType(t.param_type) for j in i.formal_params
                 },
                 'return_type': scope.getType(i.return_type),
                 'body': i.body
             }})
         exec Exception as e:
             print(e)
コード例 #24
0
 def visit(self, node: ast.Formal, scope: Scope):
     scope.defineSymbol(node.name, scope.getType(node.param_type), True)
     t = self.visit(node.init_expr, scope)
     if not t:
         node.static_type = scope.getType(
             node.param_type
         ) if node.param_type != 'SELF_TYPE' else scope.getType(
             scope.classname)
         return
     if node.param_type == 'SELF_TYPE' and t.name == 'SELF_TYPE':
         return
     elif t.name == 'SELF_TYPE':
         if t < scope.getType(scope.classname):
             return
         else:
             raise CheckSemanticError(
                 f'{node.name} doesn\'t conform {scope.classname}')
     elif node.param_type == 'SELF_TYPE':
         raise CheckSemanticError(
             f'Only can assign SELF_TYPE in a SELF_TYPE variable.')
     if not t < scope.getType(node.param_type):
         raise CheckSemanticError(
             f'{str(t)} doesn\'t conform {str(node.param_type)}')
コード例 #25
0
 def visit(self, node: ast.NewObject, scope: Scope):
     node.static_type = scope.getType(node.type)
     return scope.getType(node.type)
コード例 #26
0
 def visit(self, node: ast.Boolean, scope: Scope):
     node.static_type = scope.getType('Bool')
     return scope.getType("Bool")
コード例 #27
0
 def visit(self, node: ast.Object, scope: Scope):
     node.static_type = scope.getTypeFor(node.name)
     return scope.getTypeFor(node.name)
コード例 #28
0
 def visit(self, node: ast.Self, scope: Scope):
     node.static_type = scope.getType(scope.classname)
     return scope.getType('SELF_TYPE')
コード例 #29
0
    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
コード例 #30
0
 def visit(self, node: ast.IsVoid, scope: Scope):
     node.static_type = scope.getType('Bool')
     self.visit(node.expr, scope)
     return scope.getType("Bool")