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

Commit

Permalink
Add prefix: and postfix: processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmichaud committed Oct 19, 2009
1 parent 2188043 commit 2d1ddd7
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 8 deletions.
24 changes: 19 additions & 5 deletions src/HLL/Actions.pm
Expand Up @@ -2,21 +2,35 @@ class HLL::Actions;

method EXPR($/, $key?) {
unless $key { return 0; }
my $past;
my $past := PAST::Op.new( :node($/) );
for $/.list { $past.push($_.ast); }
if $key eq 'INFIX' {
$past := PAST::Op.new(
$/[0].ast, $/[1].ast,
:name( 'infix:<' ~ $<sym> ~ '>' )
);
$past.name( 'infix:<' ~ $<sym> ~ '>' );
}
elsif $key eq 'PREFIX' {
$past.name( 'prefix:<' ~ $<sym> ~ '>' );
}
elsif $key eq 'POSTFIX' {
$past.name( 'postfix:<' ~ $<sym> ~ '>' );
}
make $past;
}

method prefixish($/) {
$<O> := $<prefix><O>;
$<sym> := $<prefix><sym>;
}

method infixish($/) {
$<O> := $<infix><O>;
$<sym> := $<infix><sym>;
}

method postfixish($/) {
$<O> := $<postfix><O>;
$<sym> := $<postfix><sym>;
}

method termish($/) {
make $<noun>.ast;
}
Expand Down
12 changes: 9 additions & 3 deletions src/HLL/Grammar.pm
@@ -1,15 +1,21 @@
grammar HLL::Grammar;

token termish {
<prefixish>*
<noun>
<postfixish>*
}

proto token noun { <...> }
proto token infix { <...> }
proto token prefix { <...> }
proto token postfix { <...> }

token noun:sym<term> { <term> }

token infixish {
<infix>
}
token infixish { <infix> }
token prefixish { <prefix> }
token postfixish { <postfix> }

token quote_delimited {
<starter> <quote_atom>* <stopper>
Expand Down
2 changes: 2 additions & 0 deletions src/NQP/Actions.pm
@@ -1,7 +1,9 @@
class NQP::Actions is HLL::Actions;

# These will eventually go in NQP::Grammar.
NQP::Grammar.O(':prec<x=>, :assoc<unary>', '%autoincrement');
NQP::Grammar.O(':prec<w=>, :assoc<left>', '%exponentiation');
NQP::Grammar.O(':prec<v=>, :assoc<unary>', '%symbolic_unary');
NQP::Grammar.O(':prec<u=>, :assoc<left>', '%multiplicative');
NQP::Grammar.O(':prec<t=>, :assoc<left>', '%additive');

Expand Down
6 changes: 6 additions & 0 deletions src/NQP/Grammar.pm
Expand Up @@ -13,6 +13,12 @@ token infix:sym<%> { $<sym>=['%'] <O('%multiplicative, :pirop<mod>')> }
token infix:sym<+> { $<sym>=['+'] <O('%additive , :pirop<add>')> }
token infix:sym<-> { $<sym>=['-'] <O('%additive , :pirop<sub>')> }

token prefix:sym<-> { $<sym>=['-'] <O('%symbolic_unary')> }
token prefix:sym<--> { $<sym>=['--'] <O('%autoincrement')> }

token postfix:sym<++> { $<sym>=['++'] <O('%autoincrement')> }


token value {
| <integer>
| <quote_delimited>
Expand Down
60 changes: 60 additions & 0 deletions src/cheats/hll-grammar.pir
Expand Up @@ -381,6 +381,45 @@ An operator precedence parser.
term = here.'MATCH'()
push termstack, term

# interleave any prefix/postfix we might have found
.local pmc prefixish, postfixish
prefixish = term['prefixish']
postfixish = term['postfixish']

prepostfix_loop:
unless prefixish goto prepostfix_done
unless postfixish goto prepostfix_done
.local string preprec, postprec
$P0 = prefixish[0]
preprec = $P0['prec']
$P1 = postfixish[0]
postprec = $P0['prec']
if postprec < preprec goto postltpre
postgtpre:
$P0 = shift prefixish
push opstack, $P0
goto prepostfix_loop
postltpre:
$P0 = shift postfixish
push opstack, $P0
goto prepostfix_loop
prepostfix_done:

prefix_loop:
unless prefixish goto prefix_done
$P0 = shift prefixish
push opstack, $P0
goto prefix_loop
prefix_done:

postfix_loop:
unless postfixish goto postfix_done
$P0 = shift postfixish
push opstack, $P0
goto postfix_loop
postfix_done:

# Now see if we can fetch an infix operator
.local pmc infixcur, infix
here = here.'ws'()
infixcur = here.'infixish'()
Expand All @@ -395,6 +434,7 @@ An operator precedence parser.
unless inprec goto err_inprec

reduce_loop:
unless opstack goto reduce_done
$P0 = opstack[-1]
$P0 = $P0['O']
opprec = $P0['prec']
Expand Down Expand Up @@ -448,14 +488,34 @@ An operator precedence parser.
opstack = find_lex '@opstack'

.local pmc op
.local string opassoc
op = pop opstack
$P0 = op['O']
opassoc = $P0['assoc']
if opassoc == 'unary' goto op_unary
op_infix:
.local pmc right, left
right = pop termstack
left = pop termstack
op[0] = left
op[1] = right
self.'!reduce'('EXPR', 'INFIX', op)
goto done
op_unary:
.local pmc arg, afrom, ofrom
arg = pop termstack
op[0] = arg
afrom = arg.'from'()
ofrom = op.'from'()
if afrom < ofrom goto op_postfix
op_prefix:
self.'!reduce'('EXPR', 'PREFIX', op)
goto done
op_postfix:
self.'!reduce'('EXPR', 'POSTFIX', op)
goto done

done:
push termstack, op
.end

Expand Down

0 comments on commit 2d1ddd7

Please sign in to comment.