Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Temporarily backport PCT::HLLCompiler's 'lineof' method
from Parrot r48866 into HLL::Compiler, so that nqp-rx can
continue to build from an older Parrot until parrot's trunk
is working again.  When we're able to bump PARROT_REVISION,
this code can go away to fall back to Parrot's version of
'lineof' (DRY).
  • Loading branch information
pmichaud committed Sep 8, 2010
1 parent c83336f commit ce60da8
Showing 1 changed file with 70 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/cheats/hll-compiler.pir
@@ -1,5 +1,6 @@
# we have to overload PCT::HLLCompiler's parse method to support P6Regex grammars

.include 'cclass.pasm'

.namespace ['HLL';'Compiler']

Expand Down Expand Up @@ -105,6 +106,75 @@
.end


# Temporarily backport PCT::HLLCompiler's 'lineof' method
# from Parrot r48866 into HLL::Compiler, so that nqp-rx can
# continue to build from an older Parrot until parrot's trunk
# is working again. When we're able to bump PARROT_REVISION,
# this code can go away to fall back to Parrot's version (DRY).
=item lineof(target, pos [, cache :named('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 :named('cache')
.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


# This sub serves as a cumulative "outer context" for code
# executed in HLL::Compiler's interactive REPL. It's invoked
# exactly once upon load/init to obtain a context, and its
Expand Down

0 comments on commit ce60da8

Please sign in to comment.