# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler module Visitor # A visitor base. module Base # The class methods. module ClassMethods def matches @_matches ||= Concurrent::Hash.new end def on(nodes) matches.merge!(nodes) end end # The instance methods. module InstanceMethods def accept(node, *params) visit(node, *params) end def visit(node, *params) return unless node begin action = self.class.matches.fetch(node.class) rescue KeyError visit_missing(node, *params) end public_send(action, node, *params) end def visit_missing(node, *) fail ArgumentError, "Cannot visit #{node.class}" end def visit_ignore(node) node end end def self.included(base) base.include InstanceMethods base.extend ClassMethods end end end end end