@@ -613,90 +613,47 @@ An operator precedence parser.
613
613
};
614
614
}
615
615
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 );
700
657
}
701
658
702
659
method EXPR_nonassoc ($ cur , $ op1 , $ op2 ) {
0 commit comments