tagged release 0.7.1
[parrot.git] / compilers / pge / PGE / Match.pir
bloba1ba2f263a970a402a1d602ff43fc788929bcb54
1 =head1 NAME
3 PGE::Match - implementation of PGE match objects
5 =head1 DESCRIPTION
7 This file implements match objects returned by the Parrot Grammar Engine.
9 =cut
11 .namespace [ 'PGE::Match' ]
13 .sub '__onload' :load
14     load_bytecode 'P6object.pbc'
15     load_bytecode 'Parrot/Capture_PIR.pbc'
16     load_bytecode 'PGE/Dumper.pir'                 # FIXME, XXX, etc.
17     .local pmc p6meta
18     p6meta = new 'P6metaclass'
19     p6meta.'new_class'('PGE::Match', 'parent'=>'Capture_PIR', 'attr'=>'$.target $.from $.pos &!corou')
20     .return ()
21 .end
23 =head2 Methods
25 =over 4
27 =item C<new(PMC src, [ PMC adverbs :slurpy :named ])>
29 Creates a new Match object based on C<src>.  If the C<grammar>
30 adverb is specified, then the new Match object is of the given
31 grammar class, otherwise if C<src> is an instance of C<Match>
32 (or a subclass) then that class is used to create the object,
33 otherwise it uses the class of the invocant.
35 The C<pos>, C<p>, C<continue>, or C<c> adverbs specify where
36 the match object should begin.  If no starting position is
37 given, the current position of C<src> is used if it has one,
38 otherwise the start position is at offset zero.  The C<from>
39 adverb can be used to initialize the Match's C<$.from>
40 attribute to a value other than the starting position.
42 The C<rw> adverb causes the invocant to be modified and
43 returned instead of creating a new Match object.
45 The C<new> method returns several values to the caller: the
46 initialized match object, the target the object is matching against,
47 a reference to its $.from attribute, a reference to its $.pos
48 attribute, the value of C<pos/p/continue/c> used to
49 initialize the object, and whether or not a continue flag
50 is set or implied.
52 =cut
54 .sub 'new' :method
55     .param pmc src
56     .param pmc adverbs         :slurpy :named
58     ##   set values based on src param
59     .local int issrcmatch, pos, iscont
60     .local string grammar
61     .local pmc target
62     issrcmatch = isa src, 'PGE::Match'
63     if issrcmatch goto target_from_src
64     .local pmc target
65     target = new 'String'
66     target = src
67     pos = 0
68     iscont = 1
69     grammar = typeof self
70     goto adverb_pos
71   target_from_src:
72     target = getattribute src, '$.target'
73     $P0 = getattribute src, '$.pos'
74     pos = $P0
75     iscont = 0
76     grammar = typeof src
77     if pos >= 0 goto adverb_pos
78     pos = 0
80   adverb_pos:
81     unless adverbs goto with_adverbs
82     ##   determine the value of pos
83     $I0 = exists adverbs['pos']
84     unless $I0 goto adverb_p
85     pos = adverbs['pos']
86     iscont = 0
87     goto with_pos
88   adverb_p:
89     $I0 = exists adverbs['p']
90     unless $I0 goto adverb_continue
91     pos = adverbs['p']
92     iscont = 0
93     goto with_pos
94   adverb_continue:
95     $I0 = exists adverbs['continue']
96     unless $I0 goto adverb_c
97     pos = adverbs['continue']
98     iscont = 1
99     goto with_pos
100   adverb_c:
101     $I0 = exists adverbs['c']
102     unless $I0 goto with_pos
103     pos = adverbs['c']
104     iscont = 1
105   with_pos:
107     ##   figure out the class of the new object
108     $I0 = exists adverbs['grammar']
109     unless $I0 goto with_grammar
110     grammar = adverbs['grammar']
111   with_grammar:
112   with_adverbs:
114     ##   create the new match object
115     .local pmc mob, mfrom, mpos
116     mob = new grammar
117     setattribute mob, '$.target', target
118     mfrom = new 'Integer'
119     mfrom = pos
120     setattribute mob, '$.from', mfrom
121     mpos = new 'Integer'
122     mpos = -1
123     setattribute mob, '$.pos', mpos
125     .return (mob, pos, target, mfrom, mpos, iscont)
126 .end
129 =item C<next()>
131 Tell a Match object to continue the previous match from where
132 it left off.
134 =cut
136 .sub 'next' :method
137     .local pmc corou
139     corou = getattribute self, '&!corou'
140     if_null corou, next_1
141     goto next_2
142   next_1:
143     $P0 = getattribute self, '$.pos'
144     $P0 = -1
145     goto end
146   next_2:
147     corou()
148   end:
149     .return ()
150 .end
153 =item C<from([int pos])>
155 Returns or sets the offset in the target string of the first item
156 this object matched.
158 =cut
160 .sub 'from' :method
161     .param int from            :optional
162     .param int has_from        :opt_flag
163     $P0 = getattribute self, '$.from'
164     if has_from == 0 goto get
165     $P0 = from
166   get:
167     .return ($P0)
168 .end
171 =item C<to([int pos])>
173 Returns or sets the offset at the end of this match.
175 =cut
177 .sub 'to' :method
178     .param int to              :optional
179     .param int has_to          :opt_flag
180     $P0 = getattribute self, '$.pos'
181     if has_to == 0 goto get
182     $P0 = to
183   get:
184     .return ($P0)
185 .end
188 =item C<chars()>
190 Returns C<.to()> - C<.from()>.
192 =cut
194 .sub 'chars' :method
195     $I0 = self.'to'()
196     $I1 = self.'from'()
197     $I2 = $I0 - $I1
198     unless $I2 < 0 goto done
199     $I2 = 0
200   done:
201     .return ($I2)
202 .end
205 =item C<text()>
207 Returns the portion of the target string matched by this object.
209 =cut
211 .sub 'text' :method
212     $P0 = getattribute self, '$.target'
213     $P1 = getattribute self, '$.from'
214     $P2 = getattribute self, '$.pos'
215     if $P2 < 0 goto false
216     if $P2 <= $P1 goto false
217     $I1 = $P1
218     $I2 = $P2
219     $I2 -= $I1
220     $S1 = substr $P0, $I1, $I2
221     .return ($S1)
222   false:
223     .return ('')
224 .end
227 =item C<item()>
229 Returns the scalar value of this match -- the "result object"
230 if there is one, otherwise the substring matched by this match
231 object.
233 =cut
235 .sub 'item' :method
236     .return self.'result_object'()
237 .end
240 # deprecated RT#54000
241 .sub 'get_scalar' :method
242     .return self.'item'()
243 .end
246 =item C<result_object([pmc obj])>
248 Returns or sets the "result object" for the match object.
250 =cut
252 .sub 'result_object' :method
253     .param pmc obj             :optional
254     .param int has_obj         :opt_flag
255     if has_obj == 0 goto get_obj
256     setattribute self, '$!item', obj
257     goto ret_obj
258   get_obj:
259     obj = getattribute self, '$!item'
260   ret_obj:
261     if null obj goto ret_null
262     .return (obj)
263   ret_null:
264     .return self.'text'()
265 .end
268 =item C<find_key([ key1, key2, ... ])>
270 Find the first of C<key1>, C<key2>, etc. in the current
271 Match object, and return it.  Returns '' if none of
272 the specified keys are found.  If no keys are specified,
273 then simply return the first key found.
275 =cut
277 .sub 'find_key' :method
278     .param pmc keys            :slurpy
279     if null keys goto first_key
280     unless keys goto first_key
281   loop:
282     unless keys goto not_found
283     $S0 = shift keys
284     $I0 = exists self[$S0]
285     unless $I0 goto loop
286     .return ($S0)
287   first_key:
288     $P0 = self.'hash'()
289     $P1 = new 'Iterator', $P0
290     unless $P1 goto not_found
291     $S0 = shift $P1
292     .return ($S0)
293   not_found:
294     .return ('')
295 .end
298 =item C<_failcut(int cutvalue)>
300 Immediately "fail" this Match object, removing any
301 captured entities and coroutine continuation.  Set
302 the position of the match object to C<cutvalue>.
304 =cut
306 .sub '_failcut' :method
307     .param int cutvalue
308     $P0 = getattribute self, '$.pos'
309     $P0 = cutvalue
310     null $P0
311     setattribute self, '$.target', $P0
312     setattribute self, '&!corou', $P0
313     setattribute self, '@!list', $P0
314     setattribute self, '$!item', $P0
315     .local pmc iter
316     iter = new 'Iterator', self
317   iter_loop:
318     unless iter goto iter_end
319     $S0 = shift iter
320     delete self[$S0]
321     goto iter_loop
322   iter_end:
323     .return ()
324 .end
327 =item C<__get_bool()>
329 Returns 1 if this object successfully matched the target string,
330 0 otherwise.
332 =cut
334 .sub 'get_bool' :vtable :method
335     $P1 = getattribute self, '$.pos'
336     $I0 = $P1
337     $I1 = isge $I0, 0
338     .return ($I1)
339 .end
341 =item C<__get_integer()>
343 Returns the integer value of this match.
345 =cut
347 .sub 'get_integer' :vtable :method
348     $I0 = self.'result_object'()
349     .return ($I0)
350 .end
352 =item C<__get_number()>
354 Returns the numeric value of this match.
356 =cut
358 .sub 'get_number' :vtable :method
359     $N0 = self.'result_object'()
360     .return ($N0)
361 .end
363 =item C<__get_string()>
365 Returns the portion of the target string matched by this object.
367 =cut
369 .sub 'get_string' :vtable :method
370     $S0 = self.'result_object'()
371     .return ($S0)
372 .end
374 =back
376 =head1 AUTHOR
378 Patrick Michaud (pmichaud@pobox.com) is the author and maintainer.
379 Patches and suggestions should be sent to the Perl 6 compiler list
380 (perl6-compiler@perl.org).
382 =cut
384 # Local Variables:
385 #   mode: pir
386 #   fill-column: 100
387 # End:
388 # vim: expandtab shiftwidth=4 ft=pir: