class Opal::Nodes::Match3Node

s(:match_with_lvasgn, lhs, rhs)
/regexp/ =~ rhs

def compile

def compile
  sexp = s(:send, lhs, :=~, rhs)
  # Handle named matches like: /(?<abc>b)/ =~ 'b'
  if lhs.type == :regexp && lhs.children.first.type == :str
    re = lhs.children.first.children.first
    names = re.scan(/\(\?<([^>]*)>/).flatten.map(&:to_sym)
    unless names.empty?
      # $m3names = $~ ? $~.named_captures : {}
      names_def = s(:lvasgn, :$m3names,
        s(:if,
          s(:gvar, :$~),
          s(:send, s(:gvar, :$~), :named_captures),
          s(:hash)
        )
      )
      names = names.map do |name|
        # abc = $m3names[:abc]
        s(:lvasgn, name,
          s(:send,
            s(:lvar, :$m3names),
            :[],
            s(:sym, name)
          )
        )
      end
      if stmt?
        # We don't care about a return value of this one, so we
        # ignore it and just assign the local variables.
        #
        # (/(?<abc>b)/ =~ 'f')
        # $m3names = $~ ? $~.named_captures : {}
        # abc = $m3names[:abc]
        sexp = s(:begin, sexp, names_def, *names)
      else
        # We actually do care about a return value, so we must
        # keep it saved.
        #
        # $m3tmp = (/(?<abc>b)/ =~ 'f')
        # $m3names = $~ ? $~.named_captures : {}
        # abc = $m3names[:abc]
        # $m3tmp
        sexp = s(:begin,
          s(:lvasgn, :$m3tmp, sexp),
          names_def,
          *names,
          s(:lvar, :$m3tmp)
        )
      end
    end
  end
  push process(sexp, @level)
end