Skip to content

Commit

Permalink
Refactor postcircumfix:<[ ]> and Whatever handling -- attempt #2.
Browse files Browse the repository at this point in the history
This reverts commit 290012a.
  • Loading branch information
pmichaud committed Jun 7, 2009
1 parent 290012a commit b776b07
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 156 deletions.
1 change: 1 addition & 0 deletions build/Makefile.in
Expand Up @@ -85,6 +85,7 @@ BUILTINS_PIR = \
src/classes/Nil.pir \
src/classes/Pair.pir \
src/classes/Whatever.pir \
src/classes/WhateverCode.pir \
src/classes/Capture.pir \
src/classes/Match.pir \
src/classes/Grammar.pir \
Expand Down
101 changes: 60 additions & 41 deletions build/gen_whatever_pir.pl
Expand Up @@ -6,57 +6,76 @@
use warnings;

my @ops = qw(
infix:** infix:* infix:/ infix:% infix:div infix:mod infix:+
infix:** infix:* infix:/ infix:% infix:div infix:mod infix:+ infix:-
infix:== infix:!= infix:< infix:> infix:<= infix:>= infix:<=>
infix:.. infix:^.. infix:..^ infix:^..^
);

for (@ops) {
my $gen = '
print qq{
.namespace []
.sub "$_" :multi("Whatever", _)
.sub '$_' :multi('Whatever', _)
.param pmc x
.param pmc y
$P0 = get_hll_global "$_"
.lex "$op", $P0
.lex "$known", y
.const "Sub" $P1 = "!whatever_helper_left"
$P1 = clone $P1
$P2 = interpinfo .INTERPINFO_CURRENT_SUB
$P1."set_outer"($P2)
capture_lex $P1
"!fixup_routine_type"($P1, "Block")
.return ($P1)
.tailcall '!whatever_helper'('$_', x, y)
.end
.sub "$_" :multi(_, "Whatever")
.sub '$_' :multi(_, 'Whatever')
.param pmc x
.param pmc y
$P0 = get_hll_global "$_"
.lex "$op", $P0
.lex "$known", x
.const "Sub" $P1 = "!whatever_helper_right"
$P1 = clone $P1
$P2 = interpinfo .INTERPINFO_CURRENT_SUB
$P1."set_outer"($P2)
capture_lex $P1
"!fixup_routine_type"($P1, "Block")
.return ($P1)
.tailcall '!whatever_helper'('$_', x, y)
.end
';
$gen =~ s/\$_/$_/g;
print $gen;
.sub '$_' :multi('WhateverCode', _)
.param pmc x
.param pmc y
.tailcall '!whatever_helper'('$_', x, y)
.end
.sub '$_' :multi(_, 'WhateverCode')
.param pmc x
.param pmc y
.tailcall '!whatever_helper'('$_', x, y)
.end
};
}

print '
.sub "!whatever_helper_left"
.param pmc left
$P0 = find_lex "$op"
$P1 = find_lex "$known"
.tailcall $P0(left, $P1)
.end
.sub "!whatever_helper_right"
.param pmc right
$P0 = find_lex "$op"
$P1 = find_lex "$known"
.tailcall $P0($P1, right)
.end
';
print q{
.namespace []
.sub '!whatever_helper' :anon
.param string opname
.param pmc left
.param pmc right
.local pmc opfunc
opfunc = find_name opname
.lex '$opfunc', opfunc
.lex '$left', left
.lex '$right', right
.const 'Sub' $P0 = '!whatever_closure'
$P1 = newclosure $P0
'!fixup_routine_type'($P1, 'WhateverCode')
.return ($P1)
.end
.sub '!whatever_closure' :anon :outer('!whatever_helper')
.param pmc arg
.local pmc opfunc, left, right
opfunc = find_lex '$opfunc'
left = find_lex '$left'
right = find_lex '$right'
left = '!whatever_eval'(left, arg)
right = '!whatever_eval'(right, arg)
.tailcall opfunc(left, right)
.end
.sub '!whatever_eval' :multi(_)
.param pmc whatever
.param pmc arg
.return (whatever)
.end
.sub '!whatever_eval' :multi('Whatever')
.param pmc whatever
.param pmc arg
.return (arg)
.end
.sub '!whatever_eval' :multi('WhateverCode')
.param pmc whatever
.param pmc arg
.tailcall whatever(arg)
.end
};
158 changes: 72 additions & 86 deletions src/classes/Positional.pir
Expand Up @@ -13,10 +13,10 @@ src/classes/Positional.pir - Positional Role
.sub '_positional_role_body'
.param pmc type :optional

$P0 = get_hll_global ['Positional[::T]'], 'postcircumfix:[ ]'
capture_lex $P0
$P0 = get_hll_global ['Positional[::T]'], 'of'
.const 'Sub' $P0 = 'Positional::postcircumfix:[Int]'
capture_lex $P0
.const 'Sub' $P1 = 'Positional::of'
capture_lex $P1

# Capture type.
if null type goto no_type
Expand Down Expand Up @@ -48,87 +48,87 @@ src/classes/Positional.pir - Positional Role

=item postcircumfix:<[ ]>

Returns a list element or slice.

=cut

.sub 'postcircumfix:[ ]' :method :outer('_positional_role_body')
.param pmc args :slurpy
.sub 'postcircumfix:[ ]' :method :multi(_, 'Integer') :outer('_positional_role_body') :subid('Positional::postcircumfix:[Int]')
.param int index
.param pmc options :slurpy :named
.local pmc result, type
.local pmc result
if index < 0 goto err_undef
.local pmc type
type = find_lex 'T'
if args goto do_index
## return complete invocant as a list
.tailcall self.'list'()
do_index:
args.'!flatten'()
$I0 = args.'elems'()
if $I0 != 1 goto slice
$P0 = args[0]
$I0 = isa $P0, ['Whatever']
if $I0 goto result_whatever
$I0 = args[0]
if $I0 >= 0 goto result_fetch
.local int count
count = elements self
extend_loop:
unless count < index goto extend_done
result = 'undef'()
goto end
result_fetch:
result = self[$I0]
unless null result goto end
.local int cur_elems
cur_elems = elements self
viv_loop:
if cur_elems > $I0 goto end
setprop result, 'type', type
self[count] = result
inc count
goto extend_loop
extend_done:
result = self[index]
unless null result goto done
result = 'undef'()
setprop result, 'type', type
self[cur_elems] = result
inc cur_elems
goto viv_loop
result_whatever:
result = 'list'(self)
goto end
slice:
self[index] = result
done:
.return (result)
err_undef:
result = 'undef'()
.return (result)
.end

.sub 'postcircumfix:[ ]' :method :multi(_, 'Sub')
.param pmc arg
.param pmc options :slurpy :named
$I0 = elements self
$P0 = arg($I0)
.tailcall 'postcircumfix:[ ]'(self, $P0, options :named :flat)
.end

.sub 'postcircumfix:[ ]' :method :multi(_, 'Whatever')
.param pmc arg
.param pmc options :slurpy :named
.tailcall 'list'(self)
.end

.sub 'postcircumfix:[ ]' :method :multi(_)
.param pmc options :slurpy :named
.tailcall self.'list'()
.end

.sub 'postcircumfix:[ ]' :method :multi(_, _)
.param pmc args :slurpy
.param pmc options :slurpy :named
.local pmc result
args = 'list'(args)
$I0 = elements args
if $I0 == 1 goto arg_slice
result = new ['List']
slice_loop:
unless args goto slice_done
args_loop:
unless args goto args_done
$P0 = shift args
$I0 = isa $P0, ['Whatever']
if $I0 goto slice_whatever
$I0 = $P0
if $I0 >= 0 goto slice_index
slice_negative:
.local pmc elem
elem = 'undef'()
goto slice_elem
slice_index:
elem = self[$I0]
unless null elem goto slice_elem
cur_elems = elements self
viv_loop_slice:
if cur_elems > $I0 goto slice_elem
elem = 'undef'()
setprop elem, 'type', type
self[cur_elems] = elem
inc cur_elems
goto viv_loop_slice
slice_elem:
push result, elem
goto slice_loop
slice_whatever:
## add all of the elements to the result
$P0 = 'postcircumfix:[ ]'(self, $P0, options :named :flat)
$P0 = 'list'($P0)
$I0 = elements result
splice result, self, $I0, 0
goto slice_loop
slice_done:
end:
splice result, $P0, $I0, 0
goto args_loop
args_done:
.return (result)
arg_slice:
$P0 = args[0]
.const 'Sub' $P1 = 'Positional::postcircumfix:[Int]'
.tailcall $P1(self, $P0, options :named :flat)
.end

.sub '' :load :init
.local pmc block, signature
block = get_hll_global ['Positional[::T]'], 'postcircumfix:[ ]'
.const 'Sub' block1 = 'Positional::postcircumfix:[Int]'
signature = new ["Signature"]
setprop block, "$!signature", signature
signature."!add_param"("$args", 0 :named("named"))
signature."!add_param"("$options", 1 :named("named"))
setprop block1, "$!signature", signature
# signature."!add_param"("$args", 0 :named("named"))
# signature."!add_param"("$options", 1 :named("named"))
.end


Expand All @@ -138,20 +138,20 @@ Returns the type constraining what may be stored.

=cut

.sub 'of' :method :outer('_positional_role_body')
.sub 'of' :method :outer('_positional_role_body') :subid('Positional::of')
$P0 = find_lex 'T'
.return ($P0)
.end
.sub '' :load :init
.local pmc block, signature
block = get_hll_global ['Positional[::T]'], 'of'
.const 'Sub' block = 'Positional::of'
signature = new ["Signature"]
setprop block, "$!signature", signature
.end


.namespace []
.sub 'postcircumfix:[ ]' :multi(_)
.sub 'postcircumfix:[ ]'
.param pmc invocant
.param pmc args :slurpy
.param pmc options :slurpy :named
Expand All @@ -166,20 +166,6 @@ Returns the type constraining what may be stored.
.tailcall invocant.'postcircumfix:[ ]'(args :flat, options :flat :named)
.end


.sub 'postcircumfix:[ ]' :multi(_, 'Sub')
.param pmc invocant
.param pmc argsblock
.param pmc options :slurpy :named
$I0 = elements invocant
$P0 = box $I0
set_hll_global ['Whatever'], '$!slice', $P0
.local pmc args
args = argsblock()
args = 'list'(args)
.tailcall 'postcircumfix:[ ]'(invocant, args, options :flat :named)
.end

=back

=cut
Expand Down
8 changes: 4 additions & 4 deletions src/classes/Range.pir
Expand Up @@ -135,15 +135,15 @@ Construct a range from the endpoints.
=cut

.namespace []
.sub 'infix:..'
.sub 'infix:..' :multi()
.param pmc from
.param pmc to
.local pmc proto
proto = get_hll_global 'Range'
.tailcall proto.'new'('from'=>from, 'to'=>to)
.end

.sub 'infix:^..'
.sub 'infix:^..' :multi()
.param pmc from
.param pmc to
.local pmc proto, true
Expand All @@ -152,7 +152,7 @@ Construct a range from the endpoints.
.tailcall proto.'new'('from'=>from, 'to'=>to, 'from_exclusive'=>true)
.end

.sub 'infix:..^'
.sub 'infix:..^' :multi()
.param pmc from
.param pmc to
.local pmc proto, true
Expand All @@ -161,7 +161,7 @@ Construct a range from the endpoints.
.tailcall proto.'new'('from'=>from, 'to'=>to, 'to_exclusive'=>true)
.end

.sub 'infix:^..^'
.sub 'infix:^..^' :multi()
.param pmc from
.param pmc to
.local pmc proto, true
Expand Down
2 changes: 1 addition & 1 deletion src/classes/Role.pir
Expand Up @@ -170,7 +170,7 @@ Selects a role based upon type.

# Need to unwrap the arguments (they are wrapped by postcircumfix:[ ]
# multi), then call !select.
pos_args = pos_args[0]
pos_args.'!flatten'()
.tailcall self.'!select'(pos_args :flat, name_args :flat :named)
.end

Expand Down

0 comments on commit b776b07

Please sign in to comment.