Changeset 22561

Show
Ignore:
Timestamp:
10/10/08 08:49:28 (6 weeks ago)
Author:
lwall
Message:

[STD] move adverb parsing into infixish and EXPR with loose_unary prec

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/perl6/STD.pm

    r22553 r22561  
    868868     
    869869    <prefix_postfix_meta_operator>*                 {*}         #= prepost 
    870     { $+prevop = $<O> } 
    871870    <.ws> 
    872871} 
     
    892891    ] 
    893892 
    894     # also queue up any postfixes, since adverbs could change things 
     893    # also queue up any postfixes 
    895894    :dba('postfix') 
    896895    [ <?stdstopper> || 
    897896        <post>* 
    898         <.ws> 
    899         <adverbs>? 
    900     ] 
    901 } 
    902  
    903 token adverbs { 
    904     <!stdstopper> 
    905     [ <colonpair> <.ws> ]+ 
    906     { 
    907         my $prop = $+prevop orelse 
    908             $¢.panic('No previous operator visible to adverbial pair'); 
    909 #        $prop.adverb($<colonpair>); 
    910     } 
     897    ] 
     898    <.ws> 
    911899} 
    912900 
     
    947935        { $key = $<identifier>.text; $value = 0; } 
    948936        {*}                                                     #= false 
     937    | $<num> = [\d+] <identifier> 
    949938    | <identifier> 
    950939        { $key = $<identifier>.text; } 
     
    994983    :dba('infix or meta-infix') 
    995984    [ 
     985    | <colonpair> { $<fake> = 1; $<sym> = ':'; %<O><prec> = %loose_unary<prec>;  } 
    996986    | <infix> 
    997987       [ 
     
    10511041    | <postop> { $<O> = $<postop><O> } 
    10521042    ] 
    1053     { $+prevop = $<O> } 
    10541043} 
    10551044 
     
    32453234    || <?{ $listopish }> 
    32463235    || ':' <?before \s> <arglist>    # either switch to listopiness 
    3247     || {{ $+prevop = $<O> = {}; }}   # or allow adverbs (XXX needs hoisting?) 
     3236    || {{ $<O> = {}; }}   # or allow adverbs (XXX needs hoisting?) 
    32483237    ] 
    32493238} 
     
    33883377    my $preclim = $preclvl ?? $preclvl.<prec> // $LOOSEST !! $LOOSEST; 
    33893378    my $inquote is context = 0; 
    3390     my $prevop is context<rw>; 
    33913379    my @termstack; 
    33923380    my @opstack; 
     
    34753463    }; 
    34763464 
     3465  TERM: 
    34773466    loop { 
    34783467        self.deb("In loop, at ", $here.pos) if $*DEBUG +& DEBUG::EXPR; 
     
    35113500        push @termstack, $here; 
    35123501        self.deb("after push: " ~ (0+@termstack)) if $*DEBUG +& DEBUG::EXPR; 
    3513         $oldpos = $here.pos; 
    3514         my @infix = $here.cursor_fresh.infixish(); 
    3515         last unless @infix; 
    3516         my $infix = @infix[0]; 
    3517         last unless $infix.pos > $oldpos; 
    3518          
    3519         # XXX might want to allow this in a declaration though 
    3520         if not $infix { $here.panic("Can't have two terms in a row") } 
    3521  
    3522         if not $infix<sym> { 
    3523             die $infix.dump if $*DEBUG +& DEBUG::EXPR; 
    3524         } 
    3525  
    3526         my $inO = $infix<O>; 
    3527         $prevop = $inO; 
    3528         my Str $inprec = $inO<prec>; 
    3529         if not defined $inprec { 
    3530             self.deb("No prec given in infix!") if $*DEBUG +& DEBUG::EXPR; 
    3531             die $infix.dump if $*DEBUG +& DEBUG::EXPR; 
    3532             $inprec = %terminator<prec>; 
    3533         } 
    3534  
    3535         last unless $inprec gt $preclim; 
    3536  
    3537         $here = $infix.cursor_fresh.ws(); 
    3538  
    3539  
    3540         # substitute precedence for listops 
    3541         $inO<prec> = $inO<sub> if $inO<sub>; 
    3542  
    3543         # Does new infix (or terminator) force any reductions? 
    3544         while @opstack[*-1]<O><prec> gt $inprec { 
    3545             reduce(); 
    3546         } 
    3547  
    3548         # Not much point in reducing the sentinels... 
    3549         last if $inprec lt $LOOSEST; 
    3550  
    3551         # Equal precedence, so use associativity to decide. 
    3552         if @opstack[*-1]<O><prec> eq $inprec { 
    3553             given $inO<assoc> { 
    3554                 when 'non'   { $here.panic("\"$infix\" is not associative") } 
    3555                 when 'left'  { reduce() }   # reduce immediately 
    3556                 when 'right' { }            # just shift 
    3557                 when 'chain' { }            # just shift 
    3558                 when 'list'  {              # if op differs reduce else shift 
    3559                     reduce() if $infix<sym> !eqv @opstack[*-1]<sym>; 
     3502 
     3503        loop {     # while we see adverbs 
     3504            $oldpos = $here.pos; 
     3505            my @infix = $here.cursor_fresh.infixish(); 
     3506            last TERM unless @infix; 
     3507            my $infix = @infix[0]; 
     3508            last TERM unless $infix.pos > $oldpos; 
     3509             
     3510            if not $infix<sym> { 
     3511                die $infix.dump if $*DEBUG +& DEBUG::EXPR; 
     3512            } 
     3513 
     3514            my $inO = $infix<O>; 
     3515            my Str $inprec = $inO<prec>; 
     3516            if not defined $inprec { 
     3517                self.deb("No prec given in infix!") if $*DEBUG +& DEBUG::EXPR; 
     3518                die $infix.dump if $*DEBUG +& DEBUG::EXPR; 
     3519                $inprec = %terminator<prec>; 
     3520            } 
     3521 
     3522            last TERM unless $inprec gt $preclim; 
     3523 
     3524            $here = $infix.cursor_fresh.ws(); 
     3525 
     3526 
     3527            # substitute precedence for listops 
     3528            $inO<prec> = $inO<sub> if $inO<sub>; 
     3529 
     3530            # Does new infix (or terminator) force any reductions? 
     3531            while @opstack[*-1]<O><prec> gt $inprec { 
     3532                reduce(); 
     3533            } 
     3534 
     3535            # Not much point in reducing the sentinels... 
     3536            last if $inprec lt $LOOSEST; 
     3537 
     3538            # Equal precedence, so use associativity to decide. 
     3539            if @opstack[*-1]<O><prec> eq $inprec { 
     3540                given $inO<assoc> { 
     3541                    when 'non'   { $here.panic("\"$infix\" is not associative") } 
     3542                    when 'left'  { reduce() }   # reduce immediately 
     3543                    when 'right' { }            # just shift 
     3544                    when 'chain' { }            # just shift 
     3545                    when 'list'  {              # if op differs reduce else shift 
     3546                        reduce() if $infix<sym> !eqv @opstack[*-1]<sym>; 
     3547                    } 
     3548                    default { $here.panic("Unknown associativity \"$_\" for \"$infix\"") } 
    35603549                } 
    3561                 default { $here.panic("Unknown associativity \"$_\" for \"$infix\"") } 
     3550            } 
     3551            if $infix<fake> { 
     3552                my $adverbs = @termstack[*-1]<ADV> ||= []; 
     3553                push @$adverbs, $infix<colonpair>; 
     3554                next;  # not really an infix, so keep trying 
     3555            } 
     3556            else { 
     3557                $termish = $inO<nextterm> if $inO<nextterm>; 
     3558                push @opstack, $infix; 
     3559                last; 
    35623560            } 
    35633561        } 
    3564         $termish = $inO<nextterm> if $inO<nextterm>; 
    3565         push @opstack, $infix; 
    35663562    } 
    35673563    reduce() while +@termstack > 1;