[svn:parrot] r48864 - in trunk: compilers/pct/src/PCT t/compilers/pct
pmichaud at svn.parrot.org
pmichaud at svn.parrot.org
Wed Sep 8 19:26:39 UTC 2010
Author: pmichaud
Date: Wed Sep 8 19:26:39 2010
New Revision: 48864
URL: https://trac.parrot.org/parrot/changeset/48864
Log:
[pct]: Migrate 'lineof' method (from deprecated CodeString PMC) into PCT::HLLCompiler.
Modified:
trunk/compilers/pct/src/PCT/HLLCompiler.pir
trunk/t/compilers/pct/pct_hllcompiler.t
Modified: trunk/compilers/pct/src/PCT/HLLCompiler.pir
==============================================================================
--- trunk/compilers/pct/src/PCT/HLLCompiler.pir Wed Sep 8 19:16:05 2010 (r48863)
+++ trunk/compilers/pct/src/PCT/HLLCompiler.pir Wed Sep 8 19:26:39 2010 (r48864)
@@ -955,6 +955,70 @@
.return ($P0)
.end
+=item lineof(target, pos [, cache])
+
+Return the line number of offset C<pos> within C<target>. The return
+value uses zero for the first line. If C<cache> is true, then
+memoize the line offsets as a C<!lineof> property on C<target>.
+
+=cut
+
+.sub 'lineof' :method
+ .param pmc target
+ .param int pos
+ .param int cache :optional
+ .local pmc linepos
+
+ # If we've previously cached C<linepos> for target, we use it.
+ unless cache goto linepos_build
+ linepos = getprop '!linepos', target
+ unless null linepos goto linepos_done
+
+ # calculate a new linepos array.
+ linepos_build:
+ linepos = new ['ResizableIntegerArray']
+ unless cache goto linepos_build_1
+ setprop target, '!linepos', linepos
+ linepos_build_1:
+ .local string s
+ .local int jpos, eos
+ s = target
+ eos = length s
+ jpos = 0
+ # Search for all of the newline markers in C<target>. When we
+ # find one, mark the ending offset of the line in C<linepos>.
+ linepos_loop:
+ jpos = find_cclass .CCLASS_NEWLINE, s, jpos, eos
+ unless jpos < eos goto linepos_done
+ $I0 = ord s, jpos
+ inc jpos
+ push linepos, jpos
+ # Treat \r\n as a single logical newline.
+ if $I0 != 13 goto linepos_loop
+ $I0 = ord s, jpos
+ if $I0 != 10 goto linepos_loop
+ inc jpos
+ goto linepos_loop
+ linepos_done:
+
+ # We have C<linepos>, so now we search the array for the largest
+ # element that is not greater than C<pos>. The index of that
+ # element is the line number to be returned.
+ # (Potential optimization: use a binary search.)
+ .local int line, count
+ count = elements linepos
+ line = 0
+ line_loop:
+ if line >= count goto line_done
+ $I0 = linepos[line]
+ if $I0 > pos goto line_done
+ inc line
+ goto line_loop
+ line_done:
+ .return (line)
+.end
+
+
=item dumper(obj, name, options)
Dump C<obj> with C<name> according to C<options>.
Modified: trunk/t/compilers/pct/pct_hllcompiler.t
==============================================================================
--- trunk/t/compilers/pct/pct_hllcompiler.t Wed Sep 8 19:16:05 2010 (r48863)
+++ trunk/t/compilers/pct/pct_hllcompiler.t Wed Sep 8 19:26:39 2010 (r48864)
@@ -7,7 +7,7 @@
use warnings;
use lib qw(t . lib ../lib ../../lib ../../../lib);
use Test::More;
-use Parrot::Test tests => 5;
+use Parrot::Test tests => 6;
pir_output_is( <<'CODE', <<'OUT', 'some of the auxiliary methods' );
@@ -198,6 +198,72 @@
omgwtf!
OUT
+pir_output_is( <<'CODE', <<'OUT', 'lineof method' );
+.sub 'main' :main
+ load_bytecode 'PCT/HLLCompiler.pbc'
+ 'lineof_tests'()
+.end
+
+.sub 'is'
+ .param int a
+ .param int b
+ .param string message
+ if a == b goto ok
+ print "not "
+ ok:
+ print "ok\n"
+.end
+
+.sub 'lineof_tests'
+ .local pmc hll, target
+ hll = get_hll_global ['PCT'], 'HLLCompiler'
+ target = box "0123\n5678\r0123\r\n678\n"
+ $I0 = hll.'lineof'(target, 0, 1)
+ is($I0, 0, "lineof - beginning of string")
+ $I0 = hll.'lineof'(target, 1, 1)
+ is($I0, 0, "lineof - char on first line")
+ $I0 = hll.'lineof'(target, 4, 1)
+ is($I0, 0, "lineof - immediately before nl")
+ $I0 = hll.'lineof'(target, 5, 1)
+ is($I0, 1, "lineof - immediately after nl")
+ $I0 = hll.'lineof'(target, 8, 1)
+ is($I0, 1, "lineof - char before cr")
+ $I0 = hll.'lineof'(target, 9, 1)
+ is($I0, 1, "lineof - immediately before cr")
+ $I0 = hll.'lineof'(target, 10, 1)
+ is($I0, 2, "lineof - immediately after cr")
+ $I0 = hll.'lineof'(target, 11, 1)
+ is($I0, 2, "lineof - char after cr")
+ $I0 = hll.'lineof'(target, 13, 1)
+ is($I0, 2, "lineof - char before crnl")
+ $I0 = hll.'lineof'(target, 14, 1)
+ is($I0, 2, "lineof - immediately before crnl")
+ $I0 = hll.'lineof'(target, 15, 1)
+ is($I0, 3, "lineof - middle of crnl")
+ $I0 = hll.'lineof'(target, 16, 1)
+ is($I0, 3, "lineof - immediately after crnl")
+ $I0 = hll.'lineof'(target, 19, 1)
+ is($I0, 3, "lineof - immediately before final nl")
+ $I0 = hll.'lineof'(target, 20, 1)
+ is($I0, 4, "lineof - immediately after final nl")
+.end
+CODE
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+ok
+OUT
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
More information about the parrot-commits
mailing list