Skip to content

Commit

Permalink
RakuAST: several OperatorProperties updates
Browse files Browse the repository at this point in the history
- move .raku method to NQP land, we need it earlier
- add "ternary" flag, add '?? !!' as an infix op
- add "dotty" category
- add entries to "postcircumfix" and "circumfix" categories
  • Loading branch information
lizmat committed Sep 2, 2023
1 parent c82791b commit 1d78555
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 60 deletions.
124 changes: 94 additions & 30 deletions src/Raku/ast/operator-properties.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class OperatorProperties {
has int $.diffy;
has int $.fiddly;
has int $.adverb;
has int $.ternary;

# Basic interface
method new(
Expand All @@ -37,7 +38,8 @@ class OperatorProperties {
int :$iffy,
int :$diffy,
int :$fiddly,
int :$adverb
int :$adverb,
int :$ternary
) {
my $obj := nqp::create(self);
nqp::bindattr_s($obj,OperatorProperties,'$!precedence',
Expand All @@ -61,6 +63,8 @@ class OperatorProperties {
$fiddly // (nqp::isconcrete(self) ?? $!fiddly !! 0));
nqp::bindattr_i($obj,OperatorProperties,'$!adverb',
$adverb // (nqp::isconcrete(self) ?? $!adverb !! 0));
nqp::bindattr_i($obj,OperatorProperties,'$!ternary',
$ternary // (nqp::isconcrete(self) ?? $!ternary !! 0));

$obj
}
Expand All @@ -77,6 +81,7 @@ class OperatorProperties {
int :$diffy,
int :$fiddly,
int :$adverb,
int :$ternary,
*%_
) {
self.new(
Expand All @@ -89,10 +94,40 @@ class OperatorProperties {
:$iffy,
:$diffy,
:$fiddly,
:$adverb
:$adverb,
:$ternary
)
}

# A readable .raku representation for debugging
method raku() {
my str $name := self.HOW.name(self);
return $name unless nqp::isconcrete(self);

my $parts := nqp::list_s;

nqp::push_s($parts,':precedence("' ~ $!precedence ~ '")')
if $!precedence;
nqp::push_s($parts,':sub-precedence("' ~ $!sub-precedence ~ '")')
if $!sub-precedence;
nqp::push_s($parts,':associative("' ~ $!associative ~ '")')
if $!associative;
nqp::push_s($parts,':thunky("' ~ $!thunky ~ '")')
if $!thunky;
nqp::push_s($parts,':dba("' ~ $!dba ~ '")')
if $!dba;
nqp::push_s($parts,':next-term("' ~ $!next-term ~ '")')
if $!next-term;

nqp::push_s($parts,':iffy') if $!iffy;
nqp::push_s($parts,':diffy') if $!diffy;
nqp::push_s($parts,':fiddly') if $!fiddly;
nqp::push_s($parts,':adverb') if $!adverb;
nqp::push_s($parts,':ternary') if $!ternary;

$name ~ '.new: ' ~ nqp::join(', ',$parts)
}

#-------------------------------------------------------------------------------
# Allowable brackets in (post)circumfix operators

Expand Down Expand Up @@ -203,10 +238,11 @@ class OperatorProperties {
(nqp::isconcrete(self) ?? $!next-term !! "") || 'termish'
}

method iffy() { nqp::isconcrete(self) ?? $!iffy !! 0 }
method diffy() { nqp::isconcrete(self) ?? $!diffy !! 0 }
method fiddly() { nqp::isconcrete(self) ?? $!fiddly !! 0 }
method adverb() { nqp::isconcrete(self) ?? $!adverb !! 0 }
method iffy() { nqp::isconcrete(self) ?? $!iffy !! 0 }
method diffy() { nqp::isconcrete(self) ?? $!diffy !! 0 }
method fiddly() { nqp::isconcrete(self) ?? $!fiddly !! 0 }
method adverb() { nqp::isconcrete(self) ?? $!adverb !! 0 }
method ternary() { nqp::isconcrete(self) ?? $!ternary !! 0 }

# Convenience methods
method chaining() {
Expand Down Expand Up @@ -249,26 +285,20 @@ class OperatorProperties {
method prec(str $key?) {
if nqp::isconcrete(self) {
if $key {
$key eq 'prec'
?? $!precedence
!! $key eq 'assoc'
?? $!associative
!! $key eq 'thunky'
?? $!thunky
!! $key eq 'iffy'
?? $!iffy
!! $key eq 'nextterm'
?? $!next-term
!! nqp::null
nqp::atkey(self.prec,$key)
}
else {
my $hash := nqp::hash;
nqp::bindkey($hash,'prec', $!precedence) if $!precedence;
nqp::bindkey($hash,'sub', $!sub-precedence) if $!sub-precedence;
nqp::bindkey($hash,'assoc', $!associative) if $!associative;
nqp::bindkey($hash,'thunky', $!thunky) if $!thunky;
nqp::bindkey($hash,'nextterm', $!next-term) if $!next-term;
nqp::bindkey($hash,'iffy', $!iffy) if $!iffy;
nqp::bindkey($hash,'prec',$!precedence) if $!precedence;
nqp::bindkey($hash,'sub',$!sub-precedence) if $!sub-precedence;
nqp::bindkey($hash,'assoc',$!associative) if $!associative;
nqp::bindkey($hash,'thunky',$!thunky) if $!thunky;
nqp::bindkey($hash,'nextterm',$!next-term) if $!next-term;
nqp::bindkey($hash,'iffy',$!iffy) if $!iffy;
nqp::bindkey($hash,'diffy',$!diffy) if $!diffy;
nqp::bindkey($hash,'fiddly',$!fiddly) if $!fiddly;
nqp::bindkey($hash,'adverb',$!adverb) if $!adverb;
nqp::bindkey($hash,'ternary',$!ternary) if $!ternary;
$hash
}
}
Expand Down Expand Up @@ -360,7 +390,9 @@ class OperatorProperties {
'precedence','y='
),
'default-circumfix', nqp::hash(),

'default-dotty', nqp::hash(
'precedence','y='
),
'methodcall', nqp::hash(
'precedence','y=', 'associative','unary', 'fiddly', 1
),
Expand Down Expand Up @@ -435,10 +467,16 @@ class OperatorProperties {
'precedence','k=', 'associative','list'
),
'conditional', nqp::hash(
'precedence','j=', 'associative','right', 'thunky','.tt', 'iffy',1
'precedence','j=', 'associative','right', 'thunky','.tt',
'iffy',1
),
'ternary', nqp::hash(
'precedence','j=', 'associative','right', 'thunky','.tt',
'ternary',1
),
'conditional-ff', nqp::hash(
'precedence','j=', 'associative','right', 'thunky','tt', 'iffy',1
'precedence','j=', 'associative','right', 'thunky','tt',
'iffy',1
),
'item-assignment', nqp::hash(
'precedence','i=', 'associative','right'
Expand Down Expand Up @@ -654,6 +692,8 @@ class OperatorProperties {
'min', 'tight-minmax',
'max', 'tight-minmax',

'?? ::', 'ternary',

'ff', 'conditional-ff',
'^ff', 'conditional-ff',
'ff^', 'conditional-ff',
Expand Down Expand Up @@ -756,10 +796,13 @@ class OperatorProperties {
my constant PROPERTIES := nqp::hash(
'', 'default-postcircumfix',

'[ ]', 'methodcall',
'[; ]', 'methodcall',
'{ }', 'methodcall',
'{; }', 'methodcall',
'< >', 'methodcall',
'<< >>', 'methodcall',
'« »', 'methodcall',
'[ ]', 'methodcall',
'[; ]', 'methodcall',
'{ }', 'methodcall',
'{; }', 'methodcall',
);

self.produce(PROPERTIES, $operator // '')
Expand All @@ -769,6 +812,27 @@ class OperatorProperties {
method circumfix(str $operator?) {
my constant PROPERTIES := nqp::hash(
'', 'default-circumfix',

'< >', 'methodcall',
'<< >>', 'methodcall',
'« »', 'methodcall',
'[ ]', 'methodcall',
'{ }', 'methodcall',
);

self.produce(PROPERTIES, $operator // '')
}

# Lookup properties of a dotty operator
method dotty(str $operator?) {
my constant PROPERTIES := nqp::hash(
'', 'default-dotty',

'.', 'methodcall',
'.^', 'methodcall',
'.?', 'methodcall',
'.&', 'methodcall',
'.=', 'methodcall',
);

self.produce(PROPERTIES, $operator // '')
Expand Down
41 changes: 11 additions & 30 deletions src/core.c/OperatorProperties.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,39 @@ class OperatorProperties {
# has str $.associative;
# has str $.thunky;
# has str $.dba;
# has str $.next-term;
# has int $.iffy;
# has int $.diffy;
# has int $.fiddly;
# has int $.dottyopish
# has int $.nulltermish
# has int $.adverb
# has int $.ternary

multi method WHICH(OperatorProperties:D: --> ValueObjAt:D) {
my $parts := nqp::list_s('OperatorProperties');

if $.precedence -> str $precedence {
nqp::push_s($parts,nqp::concat('precedence=',$precedence));
}
if $.sub-precedence -> str $sub-precedence {
nqp::push_s($parts,nqp::concat('sub-precedence=',$sub-precedence));
}
if $.associative -> str $associative {
nqp::push_s($parts,nqp::concat('associative=',$associative));
}
if $.thunky -> str $thunky {
nqp::push_s($parts,nqp::concat('thunky=',$thunky))
}
nqp::push_s($parts,'iffy=1') if $.iffy;
nqp::push_s($parts,'diffy=1') if $.diffy;
nqp::push_s($parts,'fiddly=1') if $.fiddly;
nqp::push_s($parts,'dottyopish=1') if $.dottyopish;
nqp::push_s($parts,'nulltermish=1') if $.nulltermish;
nqp::push_s($parts,'iffy') if $.iffy;
nqp::push_s($parts,'diffy') if $.diffy;
nqp::push_s($parts,'fiddly') if $.fiddly;
nqp::push_s($parts,'adverb') if $.adverb;
nqp::push_s($parts,'ternary') if $.ternary;

nqp::box_s(nqp::join('|',$parts),ValueObjAt)
}

# Return handler for reducing with these operator properties
method reducer() { ::(self.reducer-name) }

multi method raku(OperatorProperties:D: --> Str:D) {
my $parts := nqp::list_s;

if $.precedence -> str $precedence {
nqp::push_s($parts,nqp::concat('precedence => ',$precedence.raku));
}
if $.associative -> str $associative {
nqp::push_s($parts,nqp::concat('associative => ',$associative.raku));
}
if $.thunky -> str $thunky {
nqp::push_s($parts,nqp::concat('thunky => ',$thunky.raku))
}
nqp::push_s($parts,':iffy') if $.iffy;
nqp::push_s($parts,':diffy') if $.diffy;
nqp::push_s($parts,':fiddly') if $.fiddly;
nqp::push_s($parts,':dottyopish') if $.dottyopish;
nqp::push_s($parts,':nulltermish') if $.nulltermish;

nqp::concat('OperatorProperties.new(',
nqp::concat(nqp::join(', ',$parts),')')
)
}
}

#-------------------------------------------------------------------------------
Expand Down

0 comments on commit 1d78555

Please sign in to comment.