コード例 #1
0
    def visit(self, node, scope):
        try:
            node_type = self.context.get_type(node.param_type)
            if node_type.name == 'SELF_TYPE':
                node_type = ErrorType()
                error = ErrorSemantic(INVALID_SELF_TYPE, node.line,
                                      node.column)
                self.errors.append(error)

        except SemanticException as ex:
            node_type = ErrorType()
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)

        if node.name == 'self':
            error = ErrorSemantic(
                "self cannot be the name of a formal parameter", node.line,
                node.column)
            self.errors.append(error)
        elif not scope.is_local(node.name):
            scope.define_variable(node.name, node_type)
        else:
            error = ErrorSemantic(
                PARAM_ALREADY_DEFINED.replace('%s', node.name, 1).replace(
                    '%s', self.current_method.name, 1), node.line, node.column)
            self.errors.append(error)
コード例 #2
0
    def visit(self, node):
        try:
            param_names = []
            param_types = []
            for p in node.params:
                param_names.append(p.name)
                try:
                    param_type = self.context.get_type(p.param_type)
                except SemanticException:
                    param_type = ErrorType()
                    error = ErrorSemantic(
                        "The type of param {} in method {} not exist, in the class {}."
                        .format(p.name, node.name, self.current_type.name),
                        node.line, node.column, 'TypeError')
                    self.errors.append(error)

                param_types.append(param_type)

            try:
                return_type = self.context.get_type(node.return_type)
            except SemanticException:
                return_type = ErrorType()
                error = ErrorSemantic(
                    "The return type {} in method {} not exist, in the class {}."
                    .format(node.return_type, node.name,
                            self.current_type.name), node.line, node.column,
                    'TypeError')
                self.errors.append(error)

            self.current_type.define_method(node.name, param_names,
                                            param_types, return_type)
        except SemanticException as e:
            error = ErrorSemantic(e.text, node.line, node.column)
            self.errors.append(error)
コード例 #3
0
    def visit(self, node, scope):
        self.visit(node.expr, scope)
        node_type = node.expr.computed_type

        if scope.is_defined(node.name):
            var = scope.find_variable(node.name)

            if var.name == 'self':
                error = ErrorSemantic(SELF_IS_READONLY, node.line, node.column)
                self.errors.append(error)
                node_type = ErrorType()
            elif not node_type.conforms_to(var.type):
                error = ErrorSemantic(
                    INCOMPATIBLE_TYPES.replace('%s', node_type.name,
                                               1).replace(
                                                   '%s', var.type.name, 1),
                    node.line, node.column, 'TypeError')
                self.errors.append(error)
                node_type = ErrorType()
        else:
            error = ErrorSemantic(
                VARIABLE_NOT_DEFINED.replace('%s', node.name, 1), node.line,
                node.column, 'NameError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #4
0
    def visit(self, node, scope):
        try:
            self.current_method = self.current_type.get_method(node.name)
        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column,
                                  'AttributeError')
            self.errors.append(error)

        method_scope = scope.create_child()

        for param in node.params:
            self.visit(param, method_scope)

        self.visit(node.expr, method_scope)

        expr_type = node.expr.computed_type

        return_type = self.current_method.return_type

        if expr_type.name == 'SELF_TYPE':
            if not self.current_type.conforms_to(return_type):
                error = ErrorSemantic(
                    INCOMPATIBLE_TYPES.replace('%s', expr_type.name,
                                               1).replace(
                                                   '%s',
                                                   self.current_type.name, 1),
                    node.line, node.column, 'TypeError')
                self.errors.append(error)
        elif not expr_type.conforms_to(return_type):
            error = ErrorSemantic(
                INCOMPATIBLE_TYPES.replace('%s', expr_type.name,
                                           1).replace('%s', return_type.name,
                                                      1), node.line,
                node.column, 'TypeError')
            self.errors.append(error)
コード例 #5
0
    def visit(self, node, scope):
        try:
            node_type = self.context.get_type(node.type)
            if node_type.name == 'SELF_TYPE':
                node_type = scope.find_variable('self').type
        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        self.visit(node.expr, scope)
        expr_type = node.expr.computed_type

        if not expr_type.conforms_to(node_type):
            error = ErrorSemantic(
                INCOMPATIBLE_TYPES.replace('%s', expr_type.name,
                                           1).replace('%s', node_type.name, 1),
                node.line, node.column, 'TypeError')
            self.errors.append(error)

        if node.name == 'self':
            error = ErrorSemantic(
                "'self' cannot be bound in a 'let' expression", node.line,
                node.column)
            self.errors.append(error)
        else:
            if scope.is_local(node.name):
                scope.remove_local(node.name)

            scope.define_variable(node.name, node_type)
コード例 #6
0
    def visit(self, node):
        try:
            self.current_type = self.context.get_type(node.name)
            if node.parent:
                try:
                    parent = self.context.get_type(node.parent)
                except SemanticException as e:
                    error = ErrorSemantic(e.text, node.line, node.column,
                                          'TypeError')
                    self.errors.append(error)
                    parent = ErrorType()
                    self.current_type.set_parent(parent)
                else:
                    if parent.name in ['Int', 'String', 'Bool']:
                        parent = ErrorType()
                        error = ErrorSemantic(
                            "Type {} inherits from a builint type".format(
                                node.name), node.line, node.column)
                        self.errors.append(error)
                    self.current_type.set_parent(parent)

        except SemanticException as e:
            error = ErrorSemantic(e.text, node.line, node.column, 'TypeError')
            self.errors.append(error)

        for f in node.features:
            self.visit(f)
コード例 #7
0
    def visit(self, node, scope):
        self.visit(node.instance, scope)
        instance_type = node.instance.computed_type

        try:
            static_type = self.context.get_type(node.static_type)
        except SemanticException as ex:
            static_type = ErrorType()
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)

        if not instance_type.conforms_to(static_type):
            error = ErrorSemantic(
                INCOMPATIBLE_TYPES.replace('%s', instance_type.name,
                                           1).replace('%s', static_type.name,
                                                      1), node.line,
                node.column, 'TypeError')
            self.errors.append(error)

        try:
            method = static_type.get_method(node.method)

            if len(node.args) == len(method.param_types):
                for arg, param_type in zip(node.args, method.param_types):
                    self.visit(arg, scope)
                    arg_type = arg.computed_type

                    if not arg_type.conforms_to(param_type):
                        error = ErrorSemantic(
                            INCOMPATIBLE_TYPES.replace('%s', arg_type.name,
                                                       1).replace(
                                                           '%s',
                                                           param_type.name, 1),
                            node.line, node.column, 'TypeError')
                        self.errors.append(error)
            else:
                error = ErrorSemantic(
                    f'Method "{method.name}" of "{static_type.name}" only accepts {len(method.param_types)} argument(s)',
                    node.line, node.column)
                self.errors.append(error)

            if method.return_type.name == 'SELF_TYPE':
                node_type = instance_type
            node_type = method.return_type

        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column,
                                  'AttributeError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #8
0
 def visit(self, node):
     try:
         attr_type = self.context.get_type(node.type)
     except SemanticException:
         attr_type = ErrorType()
         error = ErrorSemantic(
             "The type of attr {} in class {} not exist.".format(
                 node.name, self.current_type.name), node.line, node.column,
             'TypeError')
         self.errors.append(error)
     try:
         self.current_type.define_attribute(node.name, attr_type)
     except SemanticException as e:
         error = ErrorSemantic(e.text, node.line, node.column)
         self.errors.append(error)
コード例 #9
0
 def visit(self, node, scope):
     try:
         self.current_type.get_attribute(node.name)
     except SemanticException as ex:
         error = ErrorSemantic(ex.text, node.line, node.column,
                               'AttributeError')
         self.errors.append(error)
コード例 #10
0
    def visit(self, node, scope):
        try:
            node_type = self.current_type.get_attribute(node.name).type
        except SemanticException as ex:
            node_type = ErrorType()
            error = ErrorSemantic(ex.text, node.line, node.column,
                                  'AttributeError')
            self.errors.append(error)

        self.visit(node.expr, scope)
        expr_type = node.expr.computed_type

        if not expr_type.conforms_to(node_type):
            error = ErrorSemantic(
                INCOMPATIBLE_TYPES.replace('%s', expr_type.name,
                                           1).replace('%s', node_type.name, 1),
                node.line, node.column, 'TypeError')
            self.errors.append(error)
コード例 #11
0
 def visit(self, node):
     self.context = Context()
     self.context.create_builtin_types()
     for klass in node.classes:
         if klass.name in BUILTIN_TYPES:
             error = ErrorSemantic("Is an error redefine a builint type",
                                   klass.line, klass.column)
             self.errors.append(error)
         else:
             self.visit(klass)
コード例 #12
0
    def visit(self, node, scope):
        try:
            node_type = self.context.get_type(node.type)
            if node_type.name == 'SELF_TYPE':
                node_type = scope.find_variable('self').type
        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        if node.name == 'self':
            error = ErrorSemantic(
                "'self' cannot be bound in a 'let' expression", node.line,
                node.column)
            self.errors.append(error)
        else:
            if scope.is_local(node.name):
                scope.remove_local(node.name)

            scope.define_variable(node.name, node_type)
コード例 #13
0
    def visit(self, node, scope):
        try:
            node_type = self.context.get_type(node.type)
            if node_type.name == 'SELF_TYPE':
                node_type = scope.find_variable('self').type
        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #14
0
    def visit(self, node, scope):
        if scope.is_defined(node.name):
            node_type = scope.find_variable(node.name).type
        else:
            error = ErrorSemantic(
                VARIABLE_NOT_DEFINED.replace('%s', node.name, 1), node.line,
                node.column, 'NameError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #15
0
    def visit(self, node, scope):
        self.visit(node.predicate, scope)
        predicate_type = node.predicate.computed_type

        if predicate_type.name != 'Bool':
            error = ErrorSemantic(WRONG_TYPE.replace('%s', 'Bool', 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)

        self.visit(node.body, scope)

        node.computed_type = self.context.get_type('Object')
コード例 #16
0
 def visit(self, node):
     self.topologic_sort()
     for t in self.sort:
         if t not in BUILTIN_TYPES:
             try:
                 class_node = self.context.classes[t]
             except KeyError:
                 pass
             else:
                 self.visit(class_node)
     if not self.context.types.__contains__('Main'):
         error = ErrorSemantic("The class Main is not defined", 0, 0,
                               'TypeError')
         self.errors.append(error)
     else:
         if not self.context.types['Main'].methods.__contains__('main'):
             main_node = self.context.classes['Main']
             error = ErrorSemantic(
                 "The main method is not defined in class Main",
                 main_node.line, main_node.column, 'AttributeError')
             self.errors.append(error)
コード例 #17
0
    def visit(self, node, scope):
        try:
            action_type = self.context.get_type(node.action_type)
        except SemanticException as ex:
            error = ErrorSemantic(ex.text, node.line, node.column, 'TypeError')
            self.errors.append(error)
            action_type = ErrorType()

        scope.define_variable(node.name, action_type)

        self.visit(node.body, scope)
        node.computed_type = node.body.computed_type
コード例 #18
0
    def visit(self, node, scope):
        node_type = self.context.get_type('Int')

        self.visit(node.expr, scope)
        expr_type = node.expr.computed_type

        if expr_type.name != 'Int':
            error = ErrorSemantic(WRONG_TYPE.replace('%s', 'Int', 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #19
0
    def visit(self, node, scope):
        node_type = self.context.get_type('Bool')

        self.visit(node.left, scope)
        left_type = node.left.computed_type

        if left_type.name != 'Int':
            error = ErrorSemantic(WRONG_TYPE.replace('%s', 'Int', 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        self.visit(node.right, scope)
        right_type = node.right.computed_type

        if right_type.name != 'Int':
            error = ErrorSemantic(WRONG_TYPE.replace('%s', 'Int', 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #20
0
    def visit(self, node, scope):
        self.visit(node.predicate, scope)
        predicate_type = node.predicate.computed_type

        if predicate_type.name != 'Bool':
            error = ErrorSemantic(WRONG_TYPE.replace('%s', 'Bool', 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)

        self.visit(node.then_body, scope)
        then_type = node.then_body.computed_type
        self.visit(node.else_body, scope)
        else_type = node.else_body.computed_type

        node.computed_type = then_type.join(else_type)
コード例 #21
0
    def visit(self, node, scope):
        node_type = self.context.get_type('Bool')

        self.visit(node.left, scope)
        left_type = node.left.computed_type

        self.visit(node.right, scope)
        right_type = node.right.computed_type

        if (left_type.name in ['Int', 'Bool', 'String'] or right_type.name in [
                'Int', 'Bool', 'String'
        ]) and left_type.name != right_type.name:
            error = ErrorSemantic(WRONG_TYPE.replace('%s', left_type.name, 1),
                                  node.line, node.column, 'TypeError')
            self.errors.append(error)
            node_type = ErrorType()

        node.computed_type = node_type
コード例 #22
0
    def topologic_sort(self):
        indeg = {key: 0 for key in self.context.graph.keys()}
        for u in self.context.graph.keys():
            for v in self.context.graph[u]:
                indeg[v] += 1

        roots = [key for key in indeg.keys() if indeg[key] == 0]

        for v in roots:
            self.visit_component(v)

        visited = [x for x in self.visited]
        visited.reverse()
        for t in visited:
            if not self.visited[t] and not t in BUILTIN_TYPES:
                class_node = self.context.classes[t]
                error = ErrorSemantic(
                    "Exist a cycle that start in type {}".format(t),
                    class_node.line, class_node.column)
                self.errors.append(error)
                break
コード例 #23
0
    def visit(self, node, scope):
        self.visit(node.expr, scope)
        action_expr_types = []
        var_declared = []

        for action in node.actions:
            var_type = action.action_type
            if not var_type in var_declared:
                var_declared.append(var_type)
            else:
                error = ErrorSemantic(
                    "The type {} is declared in another branch".format(
                        var_type), action.line, action.column)
                self.errors.append(error)
            self.visit(action, scope.create_child())
            action_expr_types.append(action.computed_type)

        t_0 = action_expr_types.pop(0)
        node_type = t_0.multiple_join(action_expr_types)

        node.computed_type = node_type
コード例 #24
0
 def visit(self, node):
     try:
         self.context.create_type(node)
     except SemanticException as e:
         error = ErrorSemantic(e.text, node.line, node.column)
         self.errors.append(error)