class Patm::Pattern::Arr

Public Class Methods

new(head, rest = nil, tail = []) click to toggle source
# File lib/patm.rb, line 204
def initialize(head, rest = nil, tail = [])
  @head = head
  @rest = rest
  @tail = tail
end

Public Instance Methods

compile_internal(free_index, target_name = "_obj") click to toggle source
# File lib/patm.rb, line 239
def compile_internal(free_index, target_name = "_obj")
  i = free_index
  srcs = []
  ctxs = []

  srcs << "#{target_name}.is_a?(::Array)"

  i = compile_size_check(target_name, srcs, ctxs, i)

  i = compile_part(target_name, @head, srcs, ctxs, i)

  unless @tail.empty?
    srcs << "#{target_name}_t = #{target_name}[(-#{@tail.size})..-1]; true"
    i = compile_part("#{target_name}_t", @tail, srcs, ctxs, i)
  end

  i = compile_rest(target_name, srcs, ctxs, i)

  [
    srcs.compact.map{|s| "(#{s})"}.join(" &&\n"),
    ctxs.flatten(1),
    i
  ]
end
execute(mmatch, obj) click to toggle source
# File lib/patm.rb, line 210
def execute(mmatch, obj)
  return false unless obj.is_a?(Array)

  size_min = @head.size + @tail.size
  if @rest
    return false if obj.size < size_min
  else
    return false if obj.size != size_min
  end

  return false unless @head.zip(obj[0..(@head.size - 1)]).all? {|pat, o|
    pat.execute(mmatch, o)
  }

  return false unless @tail.zip(obj[(-@tail.size)..-1]).all? {|pat, o|
    pat.execute(mmatch, o)
  }

  !@rest || @rest.execute(mmatch, obj[@head.size..-(@tail.size+1)])
end
inspect() click to toggle source
# File lib/patm.rb, line 231
def inspect
  if @rest
    (@head + [@rest] + @tail).inspect
  else
    (@head + @tail).inspect
  end
end

Private Instance Methods

compile_part(target_name, part, srcs, ctxs, i) click to toggle source
# File lib/patm.rb, line 275
def compile_part(target_name, part, srcs, ctxs, i)
  part.each_with_index do|h, hi|
    if h.is_a?(Obj)
      s, c, i = h.compile_internal(i, "#{target_name}[#{hi}]")
      srcs << "#{s}" if s
      ctxs << c
    else
      elm_target_name = "#{target_name}_elm"
      s, c, i = h.compile_internal(i, elm_target_name)
      srcs << "#{elm_target_name} = #{target_name}[#{hi}]; #{s}" if s
      ctxs << c
    end
  end
  i
end
compile_rest(target_name, srcs, ctxs, i) click to toggle source
# File lib/patm.rb, line 291
def compile_rest(target_name, srcs, ctxs, i)
  return i unless @rest
  tname = "#{target_name}_r"
  s, c, i = @rest.compile_internal(i, tname)
  srcs << "#{tname} = #{target_name}[#{@head.size}..-(#{@tail.size+1})];#{s}" if s
  ctxs << c
  i
end
compile_size_check(target_name, srcs, ctxs, i) click to toggle source
# File lib/patm.rb, line 265
def compile_size_check(target_name, srcs, ctxs, i)
  size_min = @head.size + @tail.size
  if @rest
    srcs << "#{target_name}.size >= #{size_min}"
  else
    srcs << "#{target_name}.size == #{size_min}"
  end
  i
end