tagged release 0.6.4
[parrot.git] / languages / tcl / runtime / builtin / array.pir
blobf7c0ea0e59b7333ebc68d84e19fbf0b64b196a1c
1 ###
2 # [array]
4 .HLL 'Tcl', 'tcl_group'
5 .namespace []
8 # similar to but not exactly like [string]'s subcommand dispatch
9 #   - we pass in a boolean (array or not), the array itself, and the name
10 #   - we know we need an array name for *all* args, so we test for it here.
12 .sub '&array'
13   .param pmc argv :slurpy
15   .local int argc
16   argc = argv
18   if argc < 2 goto few_args  # subcommand *and* array name
20   .local string subcommand_name
21   subcommand_name = shift argv
23   .local pmc options
24   options = new 'ResizablePMCArray'
25   options[0] = 'anymore'
26   options[1] = 'donesearch'
27   options[2] = 'exists'
28   options[3] = 'get'
29   options[4] = 'names'
30   options[5] = 'nextelement'
31   options[6] = 'set'
32   options[7] = 'size'
33   options[8] = 'startsearch'
34   options[9] = 'statistics'
35   options[10] = 'unset'
37   .local pmc select_option
38   select_option  = get_root_global ['_tcl'], 'select_option'
39   .local string canonical_subcommand
40   canonical_subcommand = select_option(options, subcommand_name)
42   .local pmc subcommand_proc
43   null subcommand_proc
45   subcommand_proc = get_root_global ['_tcl'; 'helpers'; 'array'], canonical_subcommand
46   if null subcommand_proc goto bad_args
48   .local int is_array
49   .local string array_name
50   .local pmc the_array
52   array_name = shift argv
54   null the_array
56   .local pmc __find_var
57   __find_var = get_root_global ['_tcl'], '__find_var'
58   the_array  = __find_var(array_name)
60   if_null the_array, array_no
62   $I99 = does the_array, 'hash'
63   if $I99==0 goto array_no
65   is_array = 1
66   goto scommand
68 array_no:
69   is_array = 0
71 scommand:
72   .return subcommand_proc(is_array,the_array,array_name,argv)
74 bad_args:
75   .return ('') # once all commands are implemented, remove this...
77 few_args:
78   tcl_error 'wrong # args: should be "array option arrayName ?arg ...?"'
80 .end
82 .HLL '_Tcl', ''
84 .namespace [ 'helpers' ; 'array' ]
86 .sub 'exists'
87   .param int is_array
88   .param pmc the_array
89   .param string array_name
90   .param pmc argv
92   .local int argc
93   argc = argv
94   if argc goto bad_args
96   .return (is_array)
98 bad_args:
99   tcl_error 'wrong # args: should be "array exists arrayName"'
100 .end
102 .sub 'size'
103   .param int is_array
104   .param pmc the_array
105   .param string array_name
106   .param pmc argv
108   .local int argc
109   argc = argv
110   if argc goto bad_args
112   if is_array == 0 goto size_none
113   $I0 = the_array
114   .return ($I0)
116 size_none:
117   .return (0)
119 bad_args:
120   tcl_error 'wrong # args: should be "array size arrayName"'
121 .end
123 .sub 'set'
124   .param int is_array
125   .param pmc the_array
126   .param string array_name
127   .param pmc argv
129   .local int argc
130   argc = argv
131   if argc != 1 goto bad_args
133   .local pmc elems
134   elems = argv[0]
136   .local pmc __list
137   __list = get_root_global ['_tcl'], '__list'
138   elems  = __list(elems)
140 pre_loop:
141   .local int count
142   count = elems
143   $I0 = count % 2
144   if $I0 == 1 goto odd_args
146   # pull out all the key/value pairs and set them.
147   .local int loop
148   loop = 0
149   .local string key
150   .local pmc    val
152   .local pmc set
153   set = get_root_global ['_tcl'], '__set'
155   if_null the_array, new_array # create a new array if no var
156   goto set_loop
158 new_array:
159   the_array = new 'TclArray'
160   set(array_name,the_array) # create an empty named array...
162 set_loop:
163   if loop >= count goto done
164   key = elems[loop]
165   inc loop
166   val = elems[loop]
167   inc loop
169   # Do this just as if were were calling each set manually, as tcl's
170   # error messages indicate it seems to.
172   # equals creates an alias, so use assign.
173   .local string subvar
174   subvar = '' # why is this necessary, if we're doing an assign ???
175   assign subvar, array_name
176   subvar .= '('
177   subvar .= key
178   subvar .= ')'
179   set(subvar, val)
181   goto set_loop
183 done:
184   .return ('')
186 bad_args:
187   tcl_error 'wrong # args: should be "array set arrayName list"'
189 odd_args:
190   tcl_error 'list must have an even number of elements'
191 .end
194 .include 'iterator.pasm'
195 .sub 'get'
196   .param int is_array
197   .param pmc the_array
198   .param string array_name
199   .param pmc argv
201   .local int argc
202   argc = argv
203   if argc > 1 goto bad_args
205   .local string match_str
206   # ?pattern? defaults to matching everything.
207   match_str = '*'
209   # if it's there, get it from the arglist
210   if argc == 0 goto no_args
211   match_str = shift argv
213 no_args:
214   if is_array == 0 goto not_array
216   .local pmc retval
218   .local pmc iter, val
219   .local string str
221   .local pmc globber
222   globber = compreg 'Tcl::Glob'
223   .local pmc rule
224   rule = globber.'compile'(match_str)
226   iter = new 'Iterator', the_array
228   retval = new 'TclList'
230   .local int count
231   count = 0
233 push_loop:
234   unless iter goto push_end
235   str = shift iter
237   # check for match
238   $P2 = rule(str)
239   unless $P2 goto push_loop
241   inc count
242   push retval, str
243   val = the_array[str]
244   val = clone val
245   push retval, val
247   branch push_loop
249 push_end:
250   .return(retval)
252 bad_args:
253   tcl_error 'wrong # args: should be "array get arrayName ?pattern?"'
255 not_array:
256   .return ('')
257 .end
259 .sub 'unset'
260   .param int is_array
261   .param pmc the_array
262   .param string array_name
263   .param pmc argv
265   .local int argc
266   argc = argv
267   if argc > 1 goto bad_args
270   .local string match_str
271   # ?pattern? defaults to matching everything.
272   match_str = '*'
274   # if it's there, get it from the arglist
275   if argc == 0 goto no_args
276   match_str = shift argv
278 no_args:
279   if is_array == 0 goto not_array
281   .local pmc retval
283   .local pmc iter, val
284   .local string str
286   .local pmc globber
287   globber = compreg 'Tcl::Glob'
288   .local pmc rule
289   (rule, $P0, $P1) = globber.'compile'(match_str)
291   iter = new 'Iterator', the_array
293 push_loop:
294   unless iter goto push_end
295   str = shift iter
297  # check for match
298   $P2 = rule(str)
299   unless $P2 goto push_loop
301   delete the_array[str]
303   branch push_loop
304 push_end:
305   .return ('')
308 bad_args:
309    tcl_error 'wrong # args: should be "array unset arrayName ?pattern?"'
311 not_array:
312    .return ('')
313 .end
315 .sub 'names'
316   .param int is_array
317   .param pmc the_array
318   .param string array_name
319   .param pmc argv
321   .local pmc retval
323   .local int argc
324   argc = argv
325   if argc > 2 goto bad_args
327   .local string mode, pattern
328   mode = '-glob'
329   pattern = '*'
330   if argc == 0 goto skip_args
331   if argc == 1 goto skip_mode
333   mode = shift argv
334 skip_mode:
335   pattern = shift argv
336 skip_args:
338   .local pmc match_proc
339   null match_proc
341   match_proc = get_hll_global [ 'helpers'; 'array'; 'names_helper' ], mode
342   if null match_proc goto bad_mode
344   if is_array == 0 goto not_array
346   .return match_proc(the_array, pattern)
348 bad_args:
349   tcl_error 'wrong # args: should be "array names arrayName ?mode? ?pattern?"'
351 bad_mode:
352   $S0 = 'bad option "'
353   $S0 .= mode
354   $S0 .= '": must be -exact, -glob, or -regexp'
355   tcl_error $S0
357 not_array:
358   tcl_error '' # is this right? -Coke
359 .end
361 .namespace [ 'helpers' ; 'array'; 'names_helper' ]
363 .sub '-glob'
364   .param pmc the_array
365   .param string pattern
367   .local pmc iter
368   .local string name
370   .local pmc globber, retval
371   globber = compreg 'Tcl::Glob'
372   .local pmc rule
373   rule = globber.'compile'(pattern)
375   iter = new 'Iterator', the_array
377   retval = new 'TclList'
379   .local int count
380   count = 0
382 check_loop:
383   unless iter goto check_end
384   name = shift iter
385   $P0 = rule(name)
386   unless $P0 goto check_loop
388   inc count
389   push retval, name
391   branch check_loop
392 check_end:
394   .return (retval)
395 .end
397 .sub '-exact'
398   .param pmc the_array
399   .param string match
401   .local pmc iter, retval
402   .local string name
404   iter = new 'Iterator', the_array
406   retval = new 'String'
407   retval = ''
409 check_loop:
410   unless iter goto check_end
411   name = shift iter
413   if name == match goto found_match
414   branch check_loop
415 check_end:
416   .return (retval)
418 found_match:
419   retval = name
420   .return (retval)
421 .end
423 .sub '-regexp'
424   .param pmc the_array
425   .param string pattern
427   .local pmc iter
428   .local string name
430   .local pmc tclARE, retval
431   tclARE = compreg 'PGE::P5Regex'
432   .local pmc rule
433   rule = tclARE(pattern)
435   iter = new 'Iterator', the_array
437   retval = new 'TclList'
439   .local int count
440   count = 0
442 check_loop:
443   unless iter goto check_end
444   name = shift iter
445   $P0 = rule(name)
446   unless $P0 goto check_loop
448   inc count
449   push retval, name
451   branch check_loop
452 check_end:
454   .return (retval)
455 .end
457 # Local Variables:
458 #   mode: pir
459 #   fill-column: 100
460 # End:
461 # vim: expandtab shiftwidth=4 ft=pir: