Skip to content

Commit

Permalink
RakuAST: improve deparsing of nested ternaries
Browse files Browse the repository at this point in the history
And add test for nested ternaries
  • Loading branch information
lizmat committed Jun 28, 2023
1 parent 90ccaeb commit dd55ffe
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
54 changes: 33 additions & 21 deletions src/core.c/RakuAST/Deparse.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -2150,38 +2150,50 @@ class RakuAST::Deparse {

# no place to store heredocs, make one, try again, add them at the end
if nqp::istype($heredoc,Failure) {
my $*TERNARY = ""; # indenting for nested ternaries

$heredoc := my $*HEREDOC := my str @;
my $deparsed := self.deparse($ast);

nqp::elems($heredoc)
return nqp::elems($heredoc)
?? $deparsed ~ $heredoc.join ~ "\n"
!! $deparsed
}

# already have a place to store heredocs
else {
my str @parts =
self.deparse($ast.condition),
self.hsyn('ternary', $.ternary1);

# helper sup for a ternary part
sub deparse-part($node --> Nil) {
if nqp::istype($node,RakuAST::Heredoc) {
my str ($header,$rest) = self.deparse($node).split("\n",2);
@parts.push($header);
$heredoc.push("\n" ~ $rest.chomp);
}
else {
@parts.push(self.deparse($node));
}
my $then := $ast.then;
my $else := $ast.else;
my $intern := $*TERNARY;
my $nested := $intern
|| nqp::istype($then,RakuAST::Ternary)
|| nqp::istype($else,RakuAST::Ternary);
my str $indent = $nested
?? "\n" ~ ($intern ~= ' ').chop # assume 1 space left of ?? !!
!! '';

my str @parts =
self.deparse($ast.condition),
$indent,
self.hsyn('ternary', $.ternary1);

# helper sub for a ternary part
sub deparse-part($node --> Nil) {
if nqp::istype($node,RakuAST::Heredoc) {
my str ($header,$rest) = self.deparse($node).split("\n",2);
@parts.push($header);
$heredoc.push("\n" ~ $rest.chomp);
}
else {
@parts.push(self.deparse($node));
}
}

deparse-part($ast.then);
@parts.push(self.hsyn('ternary', $.ternary2));
deparse-part($ast.else);
deparse-part($then);
@parts.push($indent);
@parts.push(self.hsyn('ternary', $.ternary2));
deparse-part($else);

@parts.join
}
@parts.join
}

#- Trait -----------------------------------------------------------------------
Expand Down
27 changes: 26 additions & 1 deletion t/12-rakuast/operators.rakutest
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use v6.e.PREVIEW;
use Test;

plan 31;
plan 32;

my $ast;
my $deparsed;
Expand Down Expand Up @@ -461,6 +461,31 @@ subtest 'Correct outcome of ternary operator' => {
for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku);
}

subtest 'Correct outcome of nested ternary operator' => {
# $a ?? $b ?? 22 !! 33 !! 44
ast RakuAST::Ternary.new(
condition => RakuAST::Var::Lexical.new("\$a"),
then => RakuAST::Ternary.new(
condition => RakuAST::Var::Lexical.new("\$b"),
then => RakuAST::IntLiteral.new(22),
else => RakuAST::IntLiteral.new(33)
),
else => RakuAST::IntLiteral.new(44)
);
is-deeply $deparsed, q:to/CODE/.chomp, 'deparse';
$a
?? $b
?? 22
!! 33
!! 44
CODE

for 0,0,44, 1,0,33, 0,1,44, 1,2,22 -> $a, $b, $result {
is-deeply $_, $result, @type[$++]
for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku);
}
}

subtest 'Application of dotty infix `.`' => {
# "foo" .uc()
ast RakuAST::ApplyDottyInfix.new(
Expand Down

0 comments on commit dd55ffe

Please sign in to comment.