def visit(self, node, scope):
        self.visit(node.predicate, scope)
        predicate_type = node.predicate.expr_type

        if predicate_type.name != 'Bool':
            error = SemanticError(wrong_type_.replace('%s', 'Bool', 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)

        self.visit(node.expression, scope)

        node.expr_type = self.context.get_type('Object')
    def visit(self, node, scope):
        node_type = self.context.get_type('Int')

        self.visit(node.expression, scope)
        expr_type = node.expression.expr_type

        if expr_type.name != 'Int':
            error = SemanticError(wrong_type_.replace('%s', 'Int', 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)
            node_type = Error_Type()

        node.expr_type = node_type
    def visit(self, node, scope):
        node_type = self.context.get_type('Bool')

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

        if left_type.name != 'Int':
            error = SemanticError(wrong_type_.replace('%s', 'Int', 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)
            node_type = Error_Type()

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

        if right_type.name != 'Int':
            error = SemanticError(wrong_type_.replace('%s', 'Int', 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)
            node_type = Error_Type()

        node.expr_type = node_type
    def visit(self, node, scope):
        self.visit(node.predicate, scope)
        predicate_type = node.predicate.expr_type

        if predicate_type.name != 'Bool':
            error = SemanticError(wrong_type_.replace('%s', 'Bool', 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)

        self.visit(node.then_expr, scope)
        then_type = node.then_expr.expr_type
        self.visit(node.else_expr, scope)
        else_type = node.else_expr.expr_type

        node.expr_type = then_type.join(else_type)
    def visit(self, node, scope):
        node_type = self.context.get_type('Bool')

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

        self.visit(node.right, scope)
        right_type = node.right.expr_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 = SemanticError(wrong_type_.replace('%s', left_type.name, 1),
                                  node.row, node.col, 'TypeError')
            self.errors.append(error)
            node_type = Error_Type()

        node.expr_type = node_type