Skip to content

Commit 7e96389

Browse files
committed
Refactor how the <O()> rule works.
Things brings us closer in line with how STD does things, and does away with the rule taking a string of colonpairs that we then dissect into the precedence information.
1 parent a2bb2db commit 7e96389

File tree

2 files changed

+70
-152
lines changed

2 files changed

+70
-152
lines changed

src/HLL/Grammar.nqp

Lines changed: 7 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -165,91 +165,13 @@ C< :!pair >, and C<< :pair<strval> >>.
165165

166166
=end
167167

168-
# This lexical holds the hash cache. Right now we have one
169-
# cache for all grammars; eventually we may need a way to
170-
# separate them out by cursor type.
171-
my %ohash;
172-
173-
method O(str $spec, $save?) {
174-
# See if we've already created a Hash for the current
175-
# specification string -- if so, use that.
176-
my %hash := %ohash{$spec};
177-
unless %hash {
178-
# Otherwise, we need to build a new one.
179-
%hash := nqp::hash();
180-
my int $eos := nqp::chars($spec);
181-
my int $pos := 0;
182-
while ($pos := nqp::findnotcclass(nqp::const::CCLASS_WHITESPACE,
183-
$spec, $pos, $eos)) < $eos
184-
{
185-
my int $lpos;
186-
my str $s := nqp::substr($spec, $pos, 1);
187-
if $s eq ',' { # Ignore commas between elements for now.
188-
$pos++;
189-
}
190-
elsif $s eq ':' { # Parse whatever comes next like a pair.
191-
$pos++;
192-
193-
# If the pair is of the form :!name, then reverse the value
194-
# and skip the exclamation mark.
195-
my $value := 1;
196-
if nqp::substr($spec, $pos, 1) eq '!' {
197-
$pos++;
198-
$value := 0;
199-
}
200-
201-
# Get the name of the pair.
202-
$lpos := nqp::findnotcclass(nqp::const::CCLASS_WORD,
203-
$spec, $pos, $eos);
204-
my $name := nqp::substr($spec, $pos, $lpos - $pos);
205-
$pos := $lpos;
206-
207-
# Look for a <...> that follows.
208-
if nqp::substr($spec, $pos, 1) eq '<' {
209-
$pos := $pos + 1;
210-
$lpos := nqp::index($spec, '>', $pos);
211-
$value := nqp::substr($spec, $pos, $lpos - $pos);
212-
$pos := $lpos + 1;
213-
}
214-
# Done processing the pair, store it in the hash.
215-
%hash{$name} := $value;
216-
}
217-
else {
218-
# If whatever we found doesn't start with a colon, treat it
219-
# as a lookup of a previously saved hash to be merged in.
220-
# Find the first whitespace or comma
221-
$lpos := nqp::findcclass(nqp::const::CCLASS_WHITESPACE,
222-
$spec, $pos, $eos);
223-
my $index := nqp::index($spec, ',', $pos);
224-
$lpos := $index unless $index < 0 || $index >= $lpos;
225-
my $lookup := nqp::substr($spec, $pos, $lpos - $pos);
226-
my %lhash := %ohash{$lookup};
227-
self.'panic'('Unknown operator precedence specification "',
228-
$lookup, '"') unless %lhash;
229-
my $lhash_it := nqp::iterator(%lhash);
230-
while $lhash_it {
231-
$s := nqp::shift($lhash_it);
232-
%hash{$s} := %lhash{$s};
233-
}
234-
$pos := $lpos;
235-
}
236-
}
237-
# Done processing the spec string, cache the hash for later.
238-
%ohash{$spec} := %hash;
239-
}
240-
241-
if $save {
242-
%ohash{$save} := %hash;
243-
self;
244-
}
245-
else {
246-
# If we've been called as a subrule, then build a pass-cursor
247-
# to indicate success and set the hash as the subrule's match object.
248-
my $cur := self.'!cursor_start_cur'();
249-
$cur.'!cursor_pass'(nqp::getattr_i($cur, $cursor_class, '$!from'));
250-
nqp::bindattr($cur, $cursor_class, '$!match', %hash);
251-
$cur;
252-
}
168+
method O(*%hash) {
169+
# Build a pass-cursor to indicate success and set the hash as the
170+
# subrule's match object.
171+
my $cur := self.'!cursor_start_cur'();
172+
$cur.'!cursor_pass'(nqp::getattr_i($cur, $cursor_class, '$!from'));
173+
nqp::bindattr($cur, $cursor_class, '$!match', %hash);
174+
$cur;
253175
}
254176

255177

src/NQP/Grammar.nqp

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
grammar NQP::Grammar is HLL::Grammar {
2+
my %methodop := nqp::hash('prec', 'y=', 'assoc', 'unary');
3+
my %autoincrement := nqp::hash('prec', 'x=', 'assoc', 'unary');
4+
my %exponentiation := nqp::hash('prec', 'w=', 'assoc', 'left');
5+
my %symbolic_unary := nqp::hash('prec', 'v=', 'assoc', 'unary');
6+
my %multiplicative := nqp::hash('prec', 'u=', 'assoc', 'left');
7+
my %additive := nqp::hash('prec', 't=', 'assoc', 'left');
8+
my %concatenation := nqp::hash('prec', 'r=', 'assoc', 'left');
9+
my %relational := nqp::hash('prec', 'm=', 'assoc', 'non');
10+
my %tight_and := nqp::hash('prec', 'l=', 'assoc', 'left');
11+
my %tight_or := nqp::hash('prec', 'k=', 'assoc', 'left');
12+
my %conditional := nqp::hash('prec', 'j=', 'assoc', 'right');
13+
my %assignment := nqp::hash('prec', 'i=', 'assoc', 'right');
14+
my %comma := nqp::hash('prec', 'g=', 'assoc', 'list', 'nextterm', 'nulltermish');
15+
my %list_infix := nqp::hash('prec', 'f=', 'assoc', 'list');
16+
my %list_prefix := nqp::hash('prec', 'e=', 'assoc', 'unary');
17+
218
method TOP() {
319
# Language braids.
420
my %*LANG;
@@ -696,26 +712,6 @@ grammar NQP::Grammar is HLL::Grammar {
696712
token semilist { <.ws> <statement> <.ws> }
697713

698714
## Operators
699-
700-
INIT {
701-
NQP::Grammar.O(':prec<y=>, :assoc<unary>', '%methodop');
702-
NQP::Grammar.O(':prec<x=>, :assoc<unary>', '%autoincrement');
703-
NQP::Grammar.O(':prec<w=>, :assoc<left>', '%exponentiation');
704-
NQP::Grammar.O(':prec<v=>, :assoc<unary>', '%symbolic_unary');
705-
NQP::Grammar.O(':prec<u=>, :assoc<left>', '%multiplicative');
706-
NQP::Grammar.O(':prec<t=>, :assoc<left>', '%additive');
707-
NQP::Grammar.O(':prec<r=>, :assoc<left>', '%concatenation');
708-
NQP::Grammar.O(':prec<m=>, :assoc<non>', '%relational');
709-
NQP::Grammar.O(':prec<l=>, :assoc<left>', '%tight_and');
710-
NQP::Grammar.O(':prec<k=>, :assoc<left>', '%tight_or');
711-
NQP::Grammar.O(':prec<j=>, :assoc<right>', '%conditional');
712-
NQP::Grammar.O(':prec<i=>, :assoc<right>', '%assignment');
713-
NQP::Grammar.O(':prec<g=>, :assoc<list>, :nextterm<nulltermish>', '%comma');
714-
NQP::Grammar.O(':prec<f=>, :assoc<list>', '%list_infix');
715-
NQP::Grammar.O(':prec<e=>, :assoc<unary>', '%list_prefix');
716-
}
717-
718-
719715
token infixish { <!infixstopper> <OPER=infix> }
720716
token infixstopper {
721717
| <?{ $*IN_REGEX_ASSERTION }> <?[>]>
@@ -724,90 +720,90 @@ grammar NQP::Grammar is HLL::Grammar {
724720

725721
token postcircumfix:sym<[ ]> {
726722
'[' <.ws> <EXPR> ']'
727-
<O('%methodop')>
723+
<O(|%methodop)>
728724
}
729725

730726
token postcircumfix:sym<{ }> {
731727
'{' <.ws> <EXPR> '}'
732-
<O('%methodop')>
728+
<O(|%methodop)>
733729
}
734730

735731
token postcircumfix:sym<ang> {
736732
<?[<]> <quote_EXPR: ':q'>
737-
<O('%methodop')>
733+
<O(|%methodop)>
738734
}
739735

740736
token postcircumfix:sym<( )> {
741737
'(' <.ws> <arglist> ')'
742-
<O('%methodop')>
738+
<O(|%methodop)>
743739
}
744740

745-
token postfix:sym<.> { <dotty> <O('%methodop')> }
741+
token postfix:sym<.> { <dotty> <O(|%methodop)> }
746742

747-
token prefix:sym<++> { <sym> <O('%autoincrement, :op<preinc>')> }
748-
token prefix:sym<--> { <sym> <O('%autoincrement, :op<predec>')> }
743+
token prefix:sym<++> { <sym> <O(|%autoincrement, :op<preinc>)> }
744+
token prefix:sym<--> { <sym> <O(|%autoincrement, :op<predec>)> }
749745

750-
token postfix:sym<++> { <sym> <O('%autoincrement, :op<postinc>')> }
751-
token postfix:sym<--> { <sym> <O('%autoincrement, :op<postdec>')> }
746+
token postfix:sym<++> { <sym> <O(|%autoincrement, :op<postinc>)> }
747+
token postfix:sym<--> { <sym> <O(|%autoincrement, :op<postdec>)> }
752748

753-
token infix:sym<**> { <sym> <O('%exponentiation, :op<pow_n>')> }
749+
token infix:sym<**> { <sym> <O(|%exponentiation, :op<pow_n>)> }
754750

755-
token prefix:sym<+> { <sym> <O('%symbolic_unary, :op<numify>')> }
756-
token prefix:sym<~> { <sym> <O('%symbolic_unary, :op<stringify>')> }
757-
token prefix:sym<-> { <sym> <![>]> <!number> <O('%symbolic_unary, :op<neg_n>')> }
758-
token prefix:sym<?> { <sym> <O('%symbolic_unary, :op<istrue>')> }
759-
token prefix:sym<!> { <sym> <O('%symbolic_unary, :op<falsey>')> }
760-
token prefix:sym<|> { <sym> <O('%symbolic_unary')> }
751+
token prefix:sym<+> { <sym> <O(|%symbolic_unary, :op<numify>)> }
752+
token prefix:sym<~> { <sym> <O(|%symbolic_unary, :op<stringify>)> }
753+
token prefix:sym<-> { <sym> <![>]> <!number> <O(|%symbolic_unary, :op<neg_n>)> }
754+
token prefix:sym<?> { <sym> <O(|%symbolic_unary, :op<istrue>)> }
755+
token prefix:sym<!> { <sym> <O(|%symbolic_unary, :op<falsey>)> }
756+
token prefix:sym<|> { <sym> <O(|%symbolic_unary)> }
761757

762-
token infix:sym<*> { <sym> <O('%multiplicative, :op<mul_n>')> }
763-
token infix:sym</> { <sym> <O('%multiplicative, :op<div_n>')> }
764-
token infix:sym<%> { <sym> <O('%multiplicative, :op<mod_n>')> }
765-
token infix:sym<+&> { <sym> <O('%multiplicative, :op<bitand_i>')> }
758+
token infix:sym<*> { <sym> <O(|%multiplicative, :op<mul_n>)> }
759+
token infix:sym</> { <sym> <O(|%multiplicative, :op<div_n>)> }
760+
token infix:sym<%> { <sym> <O(|%multiplicative, :op<mod_n>)> }
761+
token infix:sym<+&> { <sym> <O(|%multiplicative, :op<bitand_i>)> }
766762

767-
token infix:sym<+> { <sym> <O('%additive, :op<add_n>')> }
768-
token infix:sym<-> { <sym> <O('%additive, :op<sub_n>')> }
769-
token infix:sym<+|> { <sym> <O('%additive, :op<bitor_i>')> }
770-
token infix:sym<+^> { <sym> <O('%additive, :op<bitxor_i>')> }
763+
token infix:sym<+> { <sym> <O(|%additive, :op<add_n>)> }
764+
token infix:sym<-> { <sym> <O(|%additive, :op<sub_n>)> }
765+
token infix:sym<+|> { <sym> <O(|%additive, :op<bitor_i>)> }
766+
token infix:sym<+^> { <sym> <O(|%additive, :op<bitxor_i>)> }
771767

772-
token infix:sym<~> { <sym> <O('%concatenation , :op<concat>')> }
768+
token infix:sym<~> { <sym> <O(|%concatenation , :op<concat>)> }
773769

774-
token infix:sym«==» { <sym> <O('%relational, :op<iseq_n>')> }
775-
token infix:sym«!=» { <sym> <O('%relational, :op<isne_n>')> }
776-
token infix:sym«<=» { <sym> <O('%relational, :op<isle_n>')> }
777-
token infix:sym«>=» { <sym> <O('%relational, :op<isge_n>')> }
778-
token infix:sym«<» { <sym> <O('%relational, :op<islt_n>')> }
779-
token infix:sym«>» { <sym> <O('%relational, :op<isgt_n>')> }
780-
token infix:sym«eq» { <sym> <O('%relational, :op<iseq_s>')> }
781-
token infix:sym«ne» { <sym> <O('%relational, :op<isne_s>')> }
782-
token infix:sym«le» { <sym> <O('%relational, :op<isle_s>')> }
783-
token infix:sym«ge» { <sym> <O('%relational, :op<isge_s>')> }
784-
token infix:sym«lt» { <sym> <O('%relational, :op<islt_s>')> }
785-
token infix:sym«gt» { <sym> <O('%relational, :op<isgt_s>')> }
786-
token infix:sym«=:=» { <sym> <O('%relational, :op<eqaddr>')> }
787-
token infix:sym<~~> { <sym> <O('%relational, :reducecheck<smartmatch>')> }
770+
token infix:sym«==» { <sym> <O(|%relational, :op<iseq_n>)> }
771+
token infix:sym«!=» { <sym> <O(|%relational, :op<isne_n>)> }
772+
token infix:sym«<=» { <sym> <O(|%relational, :op<isle_n>)> }
773+
token infix:sym«>=» { <sym> <O(|%relational, :op<isge_n>)> }
774+
token infix:sym«<» { <sym> <O(|%relational, :op<islt_n>)> }
775+
token infix:sym«>» { <sym> <O(|%relational, :op<isgt_n>)> }
776+
token infix:sym«eq» { <sym> <O(|%relational, :op<iseq_s>)> }
777+
token infix:sym«ne» { <sym> <O(|%relational, :op<isne_s>)> }
778+
token infix:sym«le» { <sym> <O(|%relational, :op<isle_s>)> }
779+
token infix:sym«ge» { <sym> <O(|%relational, :op<isge_s>)> }
780+
token infix:sym«lt» { <sym> <O(|%relational, :op<islt_s>)> }
781+
token infix:sym«gt» { <sym> <O(|%relational, :op<isgt_s>)> }
782+
token infix:sym«=:=» { <sym> <O(|%relational, :op<eqaddr>)> }
783+
token infix:sym<~~> { <sym> <O(|%relational, :reducecheck<smartmatch>)> }
788784

789-
token infix:sym<&&> { <sym> <O('%tight_and, :op<if>')> }
785+
token infix:sym<&&> { <sym> <O(|%tight_and, :op<if>)> }
790786

791-
token infix:sym<||> { <sym> <O('%tight_or, :op<unless>')> }
792-
token infix:sym<//> { <sym> <O('%tight_or, :op<defor>')> }
787+
token infix:sym<||> { <sym> <O(|%tight_or, :op<unless>)> }
788+
token infix:sym<//> { <sym> <O(|%tight_or, :op<defor>)> }
793789

794790
token infix:sym<?? !!> {
795791
'??'
796792
<.ws>
797793
<EXPR('i=')>
798794
'!!'
799-
<O('%conditional, :reducecheck<ternary>, :op<if>')>
795+
<O(|%conditional, :reducecheck<ternary>, :op<if>)>
800796
}
801797

802798
token infix:sym<=> {
803799
<sym> <.panic: 'Assignment ("=") not supported in NQP, use ":=" instead'>
804800
}
805-
token infix:sym<:=> { <sym> <O('%assignment, :op<bind>')> }
806-
token infix:sym<::=> { <sym> <O('%assignment, :op<bind>')> }
801+
token infix:sym<:=> { <sym> <O(|%assignment, :op<bind>)> }
802+
token infix:sym<::=> { <sym> <O(|%assignment, :op<bind>)> }
807803

808-
token infix:sym<,> { <sym> <O('%comma, :op<list>')> }
804+
token infix:sym<,> { <sym> <O(|%comma, :op<list>)> }
809805

810-
token prefix:sym<make> { <sym> \s <O('%list_prefix')> }
806+
token prefix:sym<make> { <sym> \s <O(|%list_prefix)> }
811807
token term:sym<return> { <sym> [\s <EXPR>]? { $*RETURN_USED := 1 } }
812808

813809
method smartmatch($/) {

0 commit comments

Comments
 (0)