=head1 NAME PGE::Match - implementation of PGE match objects =head1 DESCRIPTION This file implements match objects returned by the Parrot Grammar Engine. =cut .namespace [ 'PGE';'Match' ] .sub '' :load load_bytecode 'P6object.pbc' load_bytecode 'PGE/Dumper.pir' # FIXME, XXX, etc. .local pmc p6meta p6meta = new 'P6metaclass' $P0 = p6meta.'new_class'('PGE::Match', 'parent'=>'Capture', 'attr'=>'$.target $.from $.pos &!corou $!item') set_hll_global ['PGE'], '$!MATCH', $P0 .return () .end =head2 Methods =over 4 =item C Creates a new Match object based on C. If the C adverb is specified, then the new Match object is of the given grammar class, otherwise if C is an instance of C (or a subclass) then that class is used to create the object, otherwise it uses the class of the invocant. The C, C

, C, or C adverbs specify where the match object should begin. If no starting position is given, the current position of C is used if it has one, otherwise the start position is at offset zero. The C adverb can be used to initialize the Match's C<$.from> attribute to a value other than the starting position. The C adverb causes the invocant to be modified and returned instead of creating a new Match object. The C method returns several values to the caller: the initialized match object, the target the object is matching against, a reference to its $.from attribute, a reference to its $.pos attribute, the value of C used to initialize the object, and whether or not a continue flag is set or implied. =cut .sub 'new' :method .param pmc src .param pmc adverbs :slurpy :named ## set values based on src param .local int issrcmatch, pos, iscont .local pmc grammar .local pmc target, grammar_class issrcmatch = isa src, ['PGE';'Match'] if issrcmatch goto target_from_src .local pmc target target = new 'String' target = src pos = 0 iscont = 1 $P0 = self.'HOW'() grammar_class = getattribute $P0, 'parrotclass' goto adverb_pos target_from_src: target = getattribute src, '$.target' $P0 = getattribute src, '$.pos' pos = $P0 iscont = 0 grammar_class = typeof src if pos >= 0 goto adverb_pos pos = 0 adverb_pos: unless adverbs goto with_adverbs ## determine the value of pos $I0 = exists adverbs['pos'] unless $I0 goto adverb_p pos = adverbs['pos'] iscont = 0 goto with_pos adverb_p: $I0 = exists adverbs['p'] unless $I0 goto adverb_continue pos = adverbs['p'] iscont = 0 goto with_pos adverb_continue: $I0 = exists adverbs['continue'] unless $I0 goto adverb_c pos = adverbs['continue'] iscont = 1 goto with_pos adverb_c: $I0 = exists adverbs['c'] unless $I0 goto with_pos pos = adverbs['c'] iscont = 1 with_pos: ## figure out the class of the new object $I0 = exists adverbs['grammar'] unless $I0 goto with_grammar grammar = adverbs['grammar'] $S0 = typeof grammar eq $S0, 'NameSpace', grammar_namespace ne $S0, 'String', have_grammar $S0 = grammar $P0 = split '::', $S0 grammar_class = get_class $P0 goto with_grammar have_grammar: grammar_class = grammar grammar_namespace: grammar_class = get_class grammar with_grammar: with_adverbs: ## create the new match object .local pmc mob, mfrom, mpos mob = new grammar_class setattribute mob, '$.target', target mfrom = box pos setattribute mob, '$.from', mfrom mpos = box -1 setattribute mob, '$.pos', mpos .return (mob, pos, target, mfrom, mpos, iscont) .end =item C Tell a Match object to continue the previous match from where it left off. =cut .sub 'next' :method .local pmc corou corou = getattribute self, '&!corou' if_null corou, next_1 goto next_2 next_1: $P0 = getattribute self, '$.pos' $P0 = -1 goto end next_2: corou() end: .return () .end =item C Returns or sets the offset in the target string of the first item this object matched. =cut .sub 'from' :method .param int from :optional .param int has_from :opt_flag $P0 = getattribute self, '$.from' if has_from == 0 goto get $P0 = from get: .return ($P0) .end =item C Returns or sets the offset at the end of this match. =cut .sub 'to' :method .param int to :optional .param int has_to :opt_flag $P0 = getattribute self, '$.pos' if has_to == 0 goto get $P0 = to get: .return ($P0) .end =item C Returns C<.to()> - C<.from()>. =cut .sub 'chars' :method $I0 = self.'to'() $I1 = self.'from'() $I2 = $I0 - $I1 unless $I2 < 0 goto done $I2 = 0 done: .return ($I2) .end =item C Returns the portion of the target string matched by this object. =cut .sub 'text' :method $P0 = getattribute self, '$.target' $P1 = getattribute self, '$.from' $P2 = getattribute self, '$.pos' if $P2 < 0 goto false if $P2 <= $P1 goto false $I1 = $P1 $I2 = $P2 $I2 -= $I1 $S1 = substr $P0, $I1, $I2 .return ($S1) false: .return ('') .end =item C Returns the scalar value of this match -- the "result object" if there is one, otherwise the substring matched by this match object. =cut .sub 'item' :method .tailcall self.'result_object'() .end =item C Returns or sets the "result object" for the match object. =cut .sub 'result_object' :method .param pmc obj :optional .param int has_obj :opt_flag if has_obj == 0 goto get_obj setattribute self, '$!item', obj goto ret_obj get_obj: obj = getattribute self, '$!item' ret_obj: if null obj goto ret_null .return (obj) ret_null: .tailcall self.'text'() .end =item C Find the first of C, C, etc. in the current Match object, and return it. Returns '' if none of the specified keys are found. If no keys are specified, then simply return the first key found. =cut .sub 'find_key' :method .param pmc keys :slurpy if null keys goto first_key unless keys goto first_key loop: unless keys goto not_found $S0 = shift keys $I0 = exists self[$S0] unless $I0 goto loop .return ($S0) first_key: $P0 = self.'hash'() $P1 = new 'Iterator', $P0 unless $P1 goto not_found $S0 = shift $P1 .return ($S0) not_found: .return ('') .end =item C<_failcut(int cutvalue)> Immediately "fail" this Match object, removing any captured entities and coroutine continuation. Set the position of the match object to C. =cut .sub '_failcut' :method .param int cutvalue $P0 = getattribute self, '$.pos' $P0 = cutvalue null $P0 setattribute self, '$.target', $P0 setattribute self, '&!corou', $P0 setattribute self, '$!item', $P0 setref self, $P0 .return () .end =item C Returns 1 if this object successfully matched the target string, 0 otherwise. =cut .sub 'get_bool' :vtable :method $P1 = getattribute self, '$.pos' $I0 = $P1 $I1 = isge $I0, 0 .return ($I1) .end =item C Returns the integer value of this match. =cut .sub 'get_integer' :vtable :method $I0 = self.'result_object'() .return ($I0) .end =item C Returns the numeric value of this match. =cut .sub 'get_number' :vtable :method $N0 = self.'result_object'() .return ($N0) .end =item C Returns the portion of the target string matched by this object. =cut .sub 'get_string' :vtable :method $S0 = self.'result_object'() .return ($S0) .end =back =head1 AUTHOR Patrick Michaud (pmichaud@pobox.com) is the author and maintainer. Patches and suggestions should be sent to the Perl 6 compiler list (perl6-compiler@perl.org). =cut # Local Variables: # mode: pir # fill-column: 100 # End: # vim: expandtab shiftwidth=4 ft=pir: