Skip to content

Commit bd369a5

Browse files
committed
Turn EXPR_reduce from PIR to NQP.
Most of the work was done by kboga++. Added some native types and did some changes for the sake of performance.
1 parent 7fc8127 commit bd369a5

File tree

1 file changed

+41
-84
lines changed

1 file changed

+41
-84
lines changed

src/HLL/Grammar.pm

Lines changed: 41 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -613,90 +613,47 @@ An operator precedence parser.
613613
};
614614
}
615615

616-
method EXPR_reduce($termstack, $opstack) {
617-
Q:PIR {
618-
.local pmc self, termstack, opstack
619-
self = find_lex 'self'
620-
termstack = find_lex '$termstack'
621-
opstack = find_lex '$opstack'
622-
623-
.local pmc op, opOPER, opO
624-
.local string opassoc
625-
op = pop opstack
626-
627-
# Give it a fresh capture list, since we'll have assumed it has
628-
# no positional captures and not taken them.
629-
.local pmc cap_class
630-
cap_class = find_lex 'NQPCapture'
631-
$P0 = new ['ResizablePMCArray']
632-
setattribute op, cap_class, '@!array', $P0
633-
634-
opOPER = op['OPER']
635-
opO = opOPER['O']
636-
$P0 = opO['assoc']
637-
opassoc = $P0
638-
if opassoc == 'unary' goto op_unary
639-
if opassoc == 'list' goto op_list
640-
op_infix:
641-
.local pmc right, left
642-
right = pop termstack
643-
left = pop termstack
644-
op[0] = left
645-
op[1] = right
646-
$P0 = opO['reducecheck']
647-
if null $P0 goto op_infix_1
648-
$S0 = $P0
649-
self.$S0(op)
650-
op_infix_1:
651-
self.'!reduce_with_match'('EXPR', 'INFIX', op)
652-
goto done
653-
654-
op_unary:
655-
.local pmc arg, afrom, ofrom
656-
arg = pop termstack
657-
op[0] = arg
658-
afrom = arg.'from'()
659-
ofrom = op.'from'()
660-
if afrom < ofrom goto op_postfix
661-
op_prefix:
662-
self.'!reduce_with_match'('EXPR', 'PREFIX', op)
663-
goto done
664-
op_postfix:
665-
self.'!reduce_with_match'('EXPR', 'POSTFIX', op)
666-
goto done
667-
668-
op_list:
669-
.local string sym
670-
sym = ''
671-
$P0 = opOPER['sym']
672-
if null $P0 goto op_list_1
673-
sym = $P0
674-
op_list_1:
675-
arg = pop termstack
676-
unshift op, arg
677-
op_sym_loop:
678-
unless opstack goto op_sym_done
679-
$S0 = ''
680-
$P0 = opstack[-1]
681-
$P0 = $P0['OPER']
682-
$P0 = $P0['sym']
683-
if null $P0 goto op_sym_1
684-
$S0 = $P0
685-
op_sym_1:
686-
if sym != $S0 goto op_sym_done
687-
arg = pop termstack
688-
unshift op, arg
689-
$P0 = pop opstack
690-
goto op_sym_loop
691-
op_sym_done:
692-
arg = pop termstack
693-
unshift op, arg
694-
self.'!reduce_with_match'('EXPR', 'LIST', op)
695-
goto done
696-
697-
done:
698-
push termstack, op
699-
};
616+
method EXPR_reduce(@termstack, @opstack) {
617+
my $op := nqp::pop(@opstack);
618+
619+
# Give it a fresh capture list, since we'll have assumed it has
620+
# no positional captures and not taken them.
621+
nqp::bindattr($op, NQPCapture, '@!array', nqp::list());
622+
my %opOPER := nqp::atkey($op, 'OPER');
623+
my %opO := nqp::atkey(%opOPER, 'O');
624+
my str $opassoc := ~nqp::atkey(%opO, 'assoc');
625+
my str $key;
626+
my str $sym;
627+
my $reducecheck;
628+
my $arg;
629+
630+
if $opassoc eq 'unary' {
631+
$arg := nqp::pop(@termstack);
632+
$op[0] := $arg;
633+
$key := $arg.from() < $op.from() ?? 'POSTFIX' !! 'PREFIX';
634+
}
635+
elsif $opassoc eq 'list' {
636+
$sym := nqp::ifnull(nqp::atkey(%opOPER, 'sym'), '');
637+
nqp::unshift($op, nqp::pop(@termstack));
638+
while @opstack {
639+
last if $sym ne nqp::ifnull(
640+
nqp::atkey(nqp::atkey(nqp::atpos(@opstack,
641+
nqp::elems(@opstack) - 1), 'OPER'), 'sym'), '');
642+
nqp::unshift($op, nqp::pop(@termstack));
643+
nqp::pop(@opstack);
644+
}
645+
nqp::unshift($op, nqp::pop(@termstack));
646+
$key := 'LIST';
647+
}
648+
else { # infix op assoc: left|right|ternary|...
649+
$op[1] := nqp::pop(@termstack); # right
650+
$op[0] := nqp::pop(@termstack); # left
651+
$reducecheck := nqp::atkey(%opO, 'reducecheck');
652+
self."$reducecheck"($op) unless nqp::isnull($reducecheck);
653+
$key := 'INFIX';
654+
}
655+
self.'!reduce_with_match'('EXPR', $key, $op);
656+
nqp::push(@termstack, $op);
700657
}
701658

702659
method EXPR_nonassoc($cur, $op1, $op2) {

0 commit comments

Comments
 (0)