Class: Patm::Pattern::Arr

Inherits:
Patm::Pattern show all
Defined in:
lib/patm.rb

Instance Method Summary collapse

Methods inherited from Patm::Pattern

#&, build_from, #compile, #rest?

Constructor Details

#initialize(head, rest = nil, tail = []) ⇒ Arr

Returns a new instance of Arr.



73
74
75
76
77
# File 'lib/patm.rb', line 73

def initialize(head, rest = nil, tail = [])
  @head = head
  @rest = rest
  @tail = tail
end

Instance Method Details

#compile_internal(free_index, target_name = "_obj") ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/patm.rb', line 100

def compile_internal(free_index, target_name = "_obj")
  i = free_index
  srcs = []
  ctxs = []

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

  size_min = @head.size + @tail.size
  if @rest
    srcs << "#{target_name}.size >= #{size_min}"
  else
    srcs << "#{target_name}.size == #{size_min}"
  end

  elm_target_name = "#{target_name}_elm"
  @head.each_with_index do|h, hi|
    s, c, i = h.compile_internal(i, elm_target_name)
    srcs << "(#{elm_target_name} = #{target_name}[#{hi}]; #{s})"
    ctxs << c
  end

  srcs << "(#{target_name}_t = #{target_name}[(-#{@tail.size})..-1]; true)"
  @tail.each_with_index do|t, ti|
    s, c, i = t.compile_internal(i, elm_target_name)
    srcs << "(#{elm_target_name} = #{target_name}_t[#{ti}]; #{s})"
    ctxs << c
  end

  if @rest
    tname = "#{target_name}_r"
    s, c, i = @rest.compile_internal(i, tname)
    srcs << "(#{tname} = #{target_name}[#{@head.size}..-(#{@tail.size+1})];#{s})"
    ctxs << c
  end

  [
    srcs.map{|s| "(#{s})"}.join(" &&\n"),
    ctxs.flatten(1),
    i
  ]
end

#execute(mmatch, obj) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/patm.rb', line 79

def execute(mmatch, obj)
  size_min = @head.size + @tail.size
  return false unless obj.is_a?(Array)
  return false unless @rest ? (obj.size >= size_min) :  (obj.size == size_min)
  @head.zip(obj[0..(@head.size - 1)]).all? {|pat, o|
    pat.execute(mmatch, o)
  } &&
  @tail.zip(obj[(-@tail.size)..-1]).all? {|pat, o|
    pat.execute(mmatch, o)
  } &&
  (!@rest || @rest.execute(mmatch, obj[@head.size..-(@tail.size+1)]))
end

#inspectObject



92
93
94
95
96
97
98
# File 'lib/patm.rb', line 92

def inspect
  if @rest
    (@head + [@rest] + @tail).inspect
  else
    (@head + @tail).inspect
  end
end