def visit(node)
unless node.is_a?(Array)
bug "unexpected node: #{node} at #{current_token}"
end
case node.first
when :program
# Topmost node
#
# [:program, exps]
visit_exps node[1]
when :void_stmt
# Empty statement
#
# [:void_stmt]
skip_space_or_newline
when :@int
# Integer literal
#
# [:@int, "123", [1, 0]]
consume_token :on_int
when :@float
# Float literal
#
# [:@int, "123.45", [1, 0]]
consume_token :on_float
when :@rational
# Rational literal
#
# [:@rational, "123r", [1, 0]]
consume_token :on_rational
when :@imaginary
# Imaginary literal
#
# [:@imaginary, "123i", [1, 0]]
consume_token :on_imaginary
when :@CHAR
# [:@CHAR, "?a", [1, 0]]
consume_token :on_CHAR
when :@gvar
# [:@gvar, "$abc", [1, 0]]
write node[1]
next_token
when :@backref
# [:@backref, "$1", [1, 0]]
write node[1]
next_token
when :@backtick
# [:@backtick, "`", [1, 4]]
consume_token :on_backtick
when :string_literal, :xstring_literal
visit_string_literal node
when :string_concat
visit_string_concat node
when :@tstring_content
# [:@tstring_content, "hello ", [1, 1]]
heredoc, tilde = @current_heredoc
column = node[2][0]
# For heredocs with tilde we sometimes need to align the contents
if heredoc && tilde && @last_was_newline
write_indent(next_indent)
check :on_tstring_content
consume_token_value(current_token_value)
next_token
else
consume_token :on_tstring_content
end
when :string_content
# [:string_content, exp]
visit_exps node[1..-1], with_lines: false
when :string_embexpr
# String interpolation piece ( #{exp} )
visit_string_interpolation node
when :string_dvar
visit_string_dvar(node)
when :symbol_literal
visit_symbol_literal(node)
when :symbol
visit_symbol(node)
when :dyna_symbol
visit_quoted_symbol_literal(node)
when :@ident
consume_token :on_ident
when :var_ref
# [:var_ref, exp]
visit node[1]
when :var_field
# [:var_field, exp]
visit node[1]
when :@kw
# [:@kw, "nil", [1, 0]]
consume_token :on_kw
when :@ivar
# [:@ivar, "@foo", [1, 0]]
consume_token :on_ivar
when :@cvar
# [:@cvar, "@@foo", [1, 0]]
consume_token :on_cvar
when :@const
# [:@const, "FOO", [1, 0]]
consume_token :on_const
when :const_ref
# [:const_ref, [:@const, "Foo", [1, 8]]]
visit node[1]
when :top_const_ref
# [:top_const_ref, [:@const, "Foo", [1, 2]]]
consume_op "::"
skip_space_or_newline
visit node[1]
when :top_const_field
# [:top_const_field, [:@const, "Foo", [1, 2]]]
consume_op "::"
visit node[1]
when :const_path_ref
visit_path(node)
when :const_path_field
visit_path(node)
when :assign
visit_assign(node)
when :opassign
visit_op_assign(node)
when :massign
visit_multiple_assign(node)
when :ifop
visit_ternary_if(node)
when :if_mod
visit_suffix(node, "if")
when :unless_mod
visit_suffix(node, "unless")
when :while_mod
visit_suffix(node, "while")
when :until_mod
visit_suffix(node, "until")
when :rescue_mod
visit_suffix(node, "rescue")
when :vcall
# [:vcall, exp]
visit node[1]
when :fcall
# [:fcall, [:@ident, "foo", [1, 0]]]
visit node[1]
when :command
visit_command(node)
when :command_call
visit_command_call(node)
when :args_add_block
visit_call_args(node)
when :args_add_star
visit_args_add_star(node)
when :bare_assoc_hash
# [:bare_assoc_hash, exps]
# Align hash elements to the first key
indent(@column) do
visit_comma_separated_list node[1]
end
when :method_add_arg
visit_call_without_receiver(node)
when :method_add_block
visit_call_with_block(node)
when :call
visit_call_with_receiver(node)
when :brace_block
visit_brace_block(node)
when :do_block
visit_do_block(node)
when :block_var
visit_block_arguments(node)
when :begin
visit_begin(node)
when :bodystmt
visit_bodystmt(node)
when :if
visit_if(node)
when :unless
visit_unless(node)
when :while
visit_while(node)
when :until
visit_until(node)
when :case
visit_case(node)
when :when
visit_when(node)
when :unary
visit_unary(node)
when :binary
visit_binary(node)
when :class
visit_class(node)
when :module
visit_module(node)
when :mrhs_new_from_args
visit_mrhs_new_from_args(node)
when :mlhs_paren
visit_mlhs_paren(node)
when :mrhs_add_star
visit_mrhs_add_star(node)
when :def
visit_def(node)
when :defs
visit_def_with_receiver(node)
when :paren
visit_paren(node)
when :params
visit_params(node)
when :array
visit_array(node)
when :hash
visit_hash(node)
when :assoc_new
visit_hash_key_value(node)
when :assoc_splat
visit_splat_inside_hash(node)
when :@label
# [:@label, "foo:", [1, 3]]
write node[1]
next_token
when :dot2
visit_range(node, true)
when :dot3
visit_range(node, false)
when :regexp_literal
visit_regexp_literal(node)
when :aref
visit_array_access(node)
when :aref_field
visit_array_setter(node)
when :sclass
visit_sclass(node)
when :field
visit_setter(node)
when :return0
consume_keyword "return"
when :return
visit_return(node)
when :break
visit_break(node)
when :next
visit_next(node)
when :yield0
consume_keyword "yield"
when :yield
visit_yield(node)
when :@op
# [:@op, "*", [1, 1]]
write node[1]
next_token
when :lambda
visit_lambda(node)
when :zsuper
# [:zsuper]
consume_keyword "super"
when :super
visit_super(node)
when :defined
visit_defined(node)
when :alias, :var_alias
visit_alias(node)
when :undef
visit_undef(node)
when :mlhs_add_star
visit_mlhs_add_star(node)
when :retry
# [:retry]
consume_keyword "retry"
when :redo
# [:redo]
consume_keyword "redo"
when :for
visit_for(node)
when :BEGIN
visit_BEGIN(node)
when :END
visit_END(node)
else
bug "Unhandled node: #{node.first}"
end
end