import symbol_table as st


class Visitor(object):
    def visit(self, tree):
        if not tree.head.startswith("implicit_autogenerated_"):
            val = tree.head
            visit_val = getattr(self, 'visit_' + val)
            return visit_val(tree)

    def visit_children(self, tree):
        for child in tree.get_tail():
            if child.head.islower():  # visit only non-terminals
                self.visit(child)

    def set_type(self, tree, type):
        tree.type = type

    def get_type(self, tree):
        return getattr(tree, 'type', None)

    def set_symbol(self, tree, symbol):
        tree.symbol = symbol

    def get_symbol(self, tree):
        return getattr(tree, 'symbol', None)

    @staticmethod
    def print_tree(tree):
        from prettyprint_visitor import PrintVisitor
        pv = PrintVisitor()
        pv.visit(tree)
        print pv.dump()

    # a visit_* method for each non-terminal in the grammar
    def visit_start(self, tree):
        pass

    # include-nodes are replaced before executing any visitor
    # def visit_include(self, tree):
    #     pass

    def visit_vardecl(self, tree):
        pass

    def visit_assignment(self, tree):
        pass

    def visit_expression(self, tree):
        pass

    def visit_binary_operation(self, tree):
        pass

    def visit_disjunction(self, tree):
        pass

    def visit_conjunction(self, tree):
        pass

    def visit_comparison(self, tree):
        pass

    def visit_relation(self, tree):
        pass

    def visit_sum(self, tree):
        pass

    def visit_term(self, tree):
        pass

    def visit_factor(self, tree):
        pass

    def visit_logical_not(self, tree):
        pass

    def visit_invert_sign(self, tree):
        pass

    def visit_keep_sign(self, tree):
        pass

    def visit_primary(self, tree):
        pass

    def visit_parenthesized(self, tree):
        pass

    def visit_atomvalue(self, tree):
        pass

    def visit_type_specifier(self, tree):
        pass

    def visit_actionname(self, tree):
        pass

    def visit_string(self, tree):
        pass

    def visit_integer(self, tree):
        pass

    def visit_float(self, tree):
        pass

    def visit_rvalue(self, tree):
        pass

    def visit_lvalue(self, tree):
        pass

    def visit_func_call(self, tree):
        pass

    def visit_dictionary(self, tree):
        pass

    def visit_list(self, tree):
        pass

    def visit_dict_item(self, tree):
        pass

    def visit_ifelse(self, tree):
        pass

    def visit_while(self, tree):
        pass

    def visit_block(self, tree):
        pass

    def visit_func_body(self, tree):
        pass

    def visit_funcdecl(self, tree):
        pass

    def visit_func_type(self, tree):
        pass

    def visit_func_name(self, tree):
        pass

    def visit_void(self, tree):
        pass

    def visit_parameter(self, tree):
        pass

    def visit_return(self, tree):
        pass

    def visit_indent(self, tree):
        pass

    def visit_bool(self, tree):
        pass

    def visit_newline(self, tree):
        pass

    def visit_definition(self, tree):
        pass

    def visit_deref(self, tree):
        pass
