3 Tcl::Glob - Parse and compile glob notation expressions.
7 A parser for Tcl-stype glob notation.
13 =item C<compile_glob(PMC source, PMC adverbs :slurpy :named)>
15 Return the result of compiling the glob expression given by
16 C<source>. Normally this function is obtained using
17 C<compreg 'Tcl::Glob'> instead of calling it directly.
19 Returns the compiled regular expression. If a C<target>
20 named parameter is supplied, then it will return the parse tree
21 (target='parse'), the expression tree (target='exp'),
22 or the resulting PIR code (target='PIR').
26 .namespace [ 'Tcl::Glob' ]
30 .param pmc adverbs :slurpy :named
33 target = adverbs['target']
34 target = downcase target
38 if source == '' goto analyze
39 $P0 = get_global 'glob'
41 if target != 'parse' goto check
45 unless match goto check_1
48 if $S0 == $S1 goto analyze
55 exp = new 'PGE::Exp::Concat'
57 $P0 = new 'PGE::Exp::Anchor'
58 $P0.'result_object'('^')
60 if null match goto analyze_1
65 $P0 = new 'PGE::Exp::Anchor'
66 $P0.'result_object'('$')
69 .return exp.'compile'(adverbs :flat :named)
76 load_bytecode 'PGE.pbc'
78 $P0 = compreg 'Tcl::Glob'
79 .return $P0.'command_line'(args)
83 .sub '__onload' :load :init
85 load_bytecode 'PGE.pbc'
86 load_bytecode 'PCT/HLLCompiler.pbc'
88 optable = new 'PGE::OPTable'
89 store_global '$optable', optable
91 $P0 = find_global 'glob_literal'
92 optable.newtok('term:', 'precedence'=>'=', 'nows'=>1, 'parsed'=>$P0)
94 $P0 = find_global 'glob_quest'
95 optable.newtok('term:?', 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
97 $P0 = find_global 'glob_star'
98 optable.newtok('term:*', 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
100 $P0 = find_global 'glob_enum'
101 optable.newtok('term:[', 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
103 optable.newtok('infix:', 'looser'=>'term:', 'assoc'=>'list', 'nows'=>1, 'match'=>'PGE::Exp::Concat')
105 $P2 = newclass [ 'Tcl::Glob::Compiler' ]
106 addattribute $P2, '$!compsub'
108 $P0 = get_global 'compile_glob'
109 $P1 = new [ 'Tcl::Glob::Compiler' ]
110 $P1.'register'('Tcl::Glob', $P0)
116 =item C<glob(PMC mob, PMC adverbs :slurpy :named)>
118 Parses a glob expression, returning the corresponding
119 parse C<PGE::Match> object.
123 .const int GLOB_INF = 2147483647
127 .param pmc adverbs :slurpy :named
129 .local pmc optable, match
130 optable = find_global 'Tcl::Glob', '$optable'
131 match = optable.'parse'(mob)
142 lastpos = length target
143 .local string literal
146 if pos >= lastpos goto literal_end
147 $S0 = substr target, pos, 1
148 $I0 = index delim, $S0
149 if $I0 >= 0 goto literal_end
150 if $S0 != '\' goto literal_add
152 $S0 = substr target, pos, 1
158 .return (literal, pos)
162 =item C<glob_literal(PMC mob, PMC adverbs)>
164 Scan a literal from a string, stopping at any metacharacters such
165 as C<*> or C<[>. Return the matched portion, with the C<result_object>
166 set to the decoded literal.
172 .param pmc adverbs :slurpy :named
176 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Literal')
177 ($S0, $I0) = 'scan_literal'(target, pos, '*?[')
178 if $I0 <= pos goto end
180 mob.'result_object'($S0)
186 =item C<glob_quest(PMC mob, PMC adverbs)>
188 Process a C<?> wildcard character in a glob. For this we just
189 return a CCShortcut that is set to '.'
195 .param pmc adverbs :slurpy :named
197 ## The '?' is already in mob['KEY'], so we don't need to find it here.
198 (mob, pos) = mob.'new'(mob, 'grammar'=>'PGE::Exp::CCShortcut')
200 mob.'result_object'('.')
205 =item C<glob_star(PMC mob, PMC adverbs)>
207 Process a C<*> wildcard character in a glob. This is a little
208 bit more complex, as we have to return a quantified '.'.
214 .param pmc adverbs :slurpy :named
216 ## The '*' is already in mob['KEY'], so we don't need to find it here.
217 ## We create a Quant object, then a CCShortcut inside of it.
218 (mob, pos) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Quant')
221 mob['max'] = GLOB_INF
222 ($P0, $I0) = mob.'new'(mob, 'grammar'=>'PGE::Exp::CCShortcut')
224 $P0.'result_object'('.')
229 =item C<glob_enum(PMC mob, PMC adverbs)>
231 Parse an enumerated character list, such as [abcd],
238 .param pmc adverbs :slurpy :named
241 .local int pos, lastpos
242 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::EnumCharList')
243 lastpos = length target
244 $S0 = substr target, pos, 1
248 .local string charlist
250 $S0 = substr target, pos, 1
251 if $S0 == '-' goto addfirst
252 if $S0 == ']' goto addfirst
258 ($S0, pos) = 'scan_literal'(target, pos, '-]')
259 if pos >= lastpos goto err_noclose
261 $S0 = substr target, pos, 1
262 if $S0 == ']' goto scan_end
264 $S0 = substr target, pos, 1
265 if $S0 == ']' goto scan_endhyphen
268 $I0 = ord charlist, -1
270 if $I0 > $I1 goto scan_loop
280 mob.'result_object'(charlist)
288 =item C<glob_alt(PMC mob, PMC adverbs)>
290 Parse an enumerated character list, such as [abcd],
297 .param pmc adverbs :slurpy :named
300 .local int pos, lastpos
301 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Literal')
302 lastpos = length target
304 ($S0, pos) = 'scan_literal'(target, pos, ',}')
305 mob.'result_object'($S0)
308 if pos >= lastpos goto err_noclose
309 $S0 = substr target, pos, 1
310 if $S0 == '}' goto end
311 $P0 = mob.'new'(mob, 'grammar'=>'PGE::Exp::Alt')
316 $P0 = mob.'new'(mob, 'grammar'=>'PGE::Exp::Literal')
317 ($S0, pos) = 'scan_literal'(target, pos, ',}')
319 $P0.'result_object'($S0)
332 .namespace [ 'Tcl::Glob::Compiler' ]
334 =item register(string name, pmc compsub)
336 Registers this compiler object as C<name> and
337 using C<compsub> as the subroutine to call for performing compilation.
341 .sub 'register' :method
345 setattribute self, '$!compsub', compsub
351 =item compile(pmc code [, "option" => value, ... ])
353 Compile C<source> (possibly modified by any provided options).
357 .sub 'compile' :method
359 .param pmc adverbs :slurpy :named
363 # $!compsub is deprecated
364 compsub = getattribute self, '$!compsub'
366 .return compsub(source, adverbs :flat :named)
371 =head1 BUGS AND LIMITATIONS
373 This is basically a cut and paste of PGE::Glob. There should probably be
374 much less code duplication here.
378 PGE::Glob was originally authored by Jonathan Scott Duff (duff@pobox.com),
379 It has been updated for later versions of PGE by Patrick R. Michaud
380 (pmichaud@pobox.com).
388 # vim: expandtab shiftwidth=4 ft=pir: