Author: masak
Date: Sat Jan  3 13:23:20 2009
New Revision: 34898

Modified:
   trunk/languages/perl6/src/builtins/any-str.pir

Log:
[rakudo] added C<unpack> implementation that passes szabgab's three original
tests, and very nearly nothing more


Modified: trunk/languages/perl6/src/builtins/any-str.pir
==============================================================================
--- trunk/languages/perl6/src/builtins/any-str.pir      (original)
+++ trunk/languages/perl6/src/builtins/any-str.pir      Sat Jan  3 13:23:20 2009
@@ -21,7 +21,7 @@
 .namespace []
 .sub 'onload' :anon :init :load
     $P0 = get_hll_namespace ['Any']
-    
'!EXPORT'('capitalize,chop,chomp,chars,:e,index,lc,lcfirst,rindex,ord,substr,uc,ucfirst',
 'from'=>$P0)
+    
'!EXPORT'('capitalize,chop,chomp,chars,:e,index,lc,lcfirst,rindex,ord,substr,uc,ucfirst,unpack',
 'from'=>$P0)
 .end
 
 
@@ -1172,6 +1172,75 @@
     .return(retv)
 .end
 
+=item unpack
+
+ our List multi Str::unpack ( Str $template, Str $packval )
+
+Takes a string and expands it out into a list of values.
+
+=cut
+
+.namespace['Any']
+.sub 'unpack' :multi(_, _)
+    .param string template
+    .param string packval
+    .local pmc retv
+    .local int len
+    
+    retv = new 'List'
+
+    len = length template
+    if len == 0 goto done
+
+    .local int pos
+    .local int packpos
+    pos = 0
+    packpos = 0
+
+  next_directive:
+    $S0 = substr template, pos, 1
+    if $S0 == 'A' goto ascii
+    if $S0 == 'x' goto skip
+    if $S0 == ' ' goto space
+    goto fail
+
+  ascii:
+    pos += 1
+    if pos == len goto fail
+    $S0 = substr template, pos, 1
+    $I0 = ord $S0
+    $I0 -= 48
+    $S1 = substr packval, packpos, $I0
+    retv.'push'($S1)
+    packpos += $I0
+    pos += 1
+    if pos == len goto done
+    goto next_directive
+
+  skip:
+    pos += 1
+    if pos == len goto fail
+    $S0 = substr template, pos, 1
+    $I0 = ord $S0
+    $I0 -= 48
+    $S1 = substr packval, packpos, $I0
+    packpos += $I0
+    pos += 1
+    if pos == len goto done
+    goto next_directive
+    
+  space:
+    pos += 1
+    if pos == len goto done
+    goto next_directive
+
+  done:
+    .return(retv)
+
+  fail:
+    $P0 = new 'Failure'
+    .return ($P0)
+.end
 
 # Local Variables:
 #   mode: pir

Reply via email to