class Opal::Rewriters::PatternMatching

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/opal/rewriters/pattern_matching.rb, line 8
def initialize
  @depth = 0
  super
end

Public Instance Methods

on_case_match(node) click to toggle source

case a; in b; end

# File lib/opal/rewriters/pattern_matching.rb, line 39
def on_case_match(node)
  @depth += 1

  cmvar = :"$cmvar#{@depth}"

  from, *cases, els = *node

  if els
    process els
  else
    els = raise_no_matching_pattern_error(cmvar)
  end

  s(:begin,
    s(:lvasgn, cmvar, from),
    single_case_match(cmvar, *cases, els)
  )
end
on_match_pattern(node) click to toggle source

a => b

# File lib/opal/rewriters/pattern_matching.rb, line 14
def on_match_pattern(node)
  from, pat = *node

  s(:begin,
    s(:lvasgn, :"$pmvar", from),
    s(:if,
      convert_full_pattern(from, pat),
      nil,
      raise_no_matching_pattern_error(:"$pmvar")
    )
  )
end
on_match_pattern_p(node) click to toggle source

a in b

# File lib/opal/rewriters/pattern_matching.rb, line 28
def on_match_pattern_p(node)
  from, pat = *node

  s(:if,
    convert_full_pattern(from, pat),
    s(:true),
    s(:false)
  )
end

Private Instance Methods

convert_full_pattern(from, pat) click to toggle source
# File lib/opal/rewriters/pattern_matching.rb, line 95
def convert_full_pattern(from, pat)
  if from.class == Symbol
    from = s(:lvar, from)
  end

  converter = PatternConverter.new(pat)
  converter.run!

  # a, b, c = ::PatternMatching.(from, [...])
  s(:masgn,
    s(:mlhs,
      *converter.variables
    ),
    s(:send,
      s(:const, s(:cbase), :PatternMatching),
      :call,
      from,
      converter.pattern,
    )
  )
end
raise_no_matching_pattern_error(from) click to toggle source

raise NoMatchingPatternError, from

# File lib/opal/rewriters/pattern_matching.rb, line 61
def raise_no_matching_pattern_error(from)
  s(:send, nil, :raise,
    s(:const, s(:cbase), :NoMatchingPatternError),
    s(:lvar, from)
  )
end
single_case_match(from, *cases, els) click to toggle source

in b

# File lib/opal/rewriters/pattern_matching.rb, line 69
def single_case_match(from, *cases, els)
  cas = cases.shift
  pat, if_guard, body = *cas

  pat = convert_full_pattern(from, pat)
  if if_guard
    guard, = *if_guard
    case if_guard.type
    when :if_guard
      pat = s(:and, pat, guard)
    when :unless_guard
      pat = s(:and, pat, s(:send, guard, :!))
    end
  end

  s(:if,
    pat,
    process(body),
    if !cases.empty?
      single_case_match(from, *cases, els)
    elsif els != s(:empty_else)
      els
    end
  )
end