use v6.e.PREVIEW; use Test; plan 14; my $ast; my $deparsed; my $raku; my @type = ; sub ast(RakuAST::Node:D $node --> Nil) { $ast := $node; $deparsed := $node.DEPARSE; $raku := 'use experimental :rakuast; ' ~ $node.raku; diag $deparsed.chomp; } subtest 'The postfix "if" statement works with a true expression' => { # 42 if 666 ast RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42), condition-modifier => RakuAST::StatementModifier::If.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(666) ) ) ); is-deeply $deparsed, '42 if 666', 'deparse'; is-deeply $_, 42, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "if" statement works with a false expression' => { # 42 if "" ast RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42), condition-modifier => RakuAST::StatementModifier::If.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new("") ) ) ); is-deeply $deparsed, '42 if ""', 'deparse'; # cannot put Empty as an entity in a for is-deeply EVAL($ast), Empty, @type[$++]; is-deeply EVAL($deparsed), Empty, @type[$++]; is-deeply EVAL(EVAL $raku), Empty, @type[$++]; } subtest 'The postfix "unless" statement works with a false expression' => { # 42 unless "" ast RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42), condition-modifier => RakuAST::StatementModifier::Unless.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new("") ) ) ); is-deeply $deparsed, '42 unless ""', 'deparse'; is-deeply $_, 42, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "unless" statement works with a true expression' => { # 42 unless 666 ast RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42), condition-modifier => RakuAST::StatementModifier::Unless.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(666) ) ) ); is-deeply $deparsed, '42 unless 666', 'deparse'; # cannot put Empty as an entity in a for is-deeply EVAL($ast), Empty, @type[$++]; is-deeply EVAL($deparsed), Empty, @type[$++]; is-deeply EVAL(EVAL $raku), Empty, @type[$++]; } subtest 'The postfix "with" statement works with defined expression' => { # $_ * 2 with 42 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$_'), infix => RakuAST::Infix.new('*'), right => RakuAST::IntLiteral.new(2) ), condition-modifier => RakuAST::StatementModifier::With.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42) ) ) ); is-deeply $deparsed, '$_ * 2 with 42', 'deparse'; is-deeply $_, 84, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "with" statement works with a type object' => { # $_ * 2 with Int ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$_'), infix => RakuAST::Infix.new('*'), right => RakuAST::IntLiteral.new(2) ), condition-modifier => RakuAST::StatementModifier::With.new( RakuAST::Statement::Expression.new( expression => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('Int') ) ) ) ); is-deeply $deparsed, '$_ * 2 with Int', 'deparse'; # cannot put Empty as an entity in a for is-deeply EVAL($ast), Empty, @type[$++]; is-deeply EVAL($deparsed), Empty, @type[$++]; is-deeply EVAL(EVAL $raku), Empty, @type[$++]; } subtest 'The postfix "without" statement works with defined expression' => { # $_ * 2 without 42 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$_'), infix => RakuAST::Infix.new('*'), right => RakuAST::IntLiteral.new(2) ), condition-modifier => RakuAST::StatementModifier::Without.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42) ) ) ); is-deeply $deparsed, '$_ * 2 without 42', 'deparse'; # cannot put Empty as an entity in a for is-deeply EVAL($ast), Empty, @type[$++]; is-deeply EVAL($deparsed), Empty, @type[$++]; is-deeply EVAL(EVAL $raku), Empty, @type[$++]; } subtest 'The postfix "given" statement works with defined expression' => { # $_ * 2 given 42 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$_'), infix => RakuAST::Infix.new('*'), right => RakuAST::IntLiteral.new(2) ), loop-modifier => RakuAST::StatementModifier::Given.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(42) ) ) ); is-deeply $deparsed, '$_ * 2 given 42', 'deparse'; is-deeply $_, 84, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "without" statement works with a type object' => { # .Str without Int ast RakuAST::Statement::Expression.new( expression => RakuAST::Term::TopicCall.new( RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('Str') ) ), condition-modifier => RakuAST::StatementModifier::Without.new( RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('Int') ) ) ); is-deeply $deparsed, '.Str without Int', 'deparse'; is-deeply $_, "", @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "when" statement works' => { my $foo; # $_ = 42; 666 when 42 ast RakuAST::StatementList.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$_'), infix => RakuAST::Infix.new('='), right => RakuAST::IntLiteral.new(42) ), ), RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(666), condition-modifier => RakuAST::StatementModifier::When.new( RakuAST::IntLiteral.new(42) ) ) ); is-deeply $deparsed, q:to/CODE/, 'deparse'; $_ = 42; 666 when 42 CODE is-deeply $_, 666, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "given" statement works with a type object' => { # .Str given Int ast RakuAST::Statement::Expression.new( expression => RakuAST::Term::TopicCall.new( RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('Str') ) ), loop-modifier => RakuAST::StatementModifier::Given.new( RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('Int') ) ) ); is-deeply $deparsed, '.Str given Int', 'deparse'; is-deeply $_, "", @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'The postfix "while" statement works' => { my $foo; # ++$foo while $foo < 5 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('++'), operand => RakuAST::Var::Lexical.new('$foo') ), loop-modifier => RakuAST::StatementModifier::While.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$foo'), infix => RakuAST::Infix.new('<'), right => RakuAST::IntLiteral.new(5), ) ) ) ); is-deeply $deparsed, '++$foo while $foo < 5', 'deparse'; for 'AST', $ast, 'Str', $deparsed, 'Raku', EVAL($raku) -> $type, $it { $foo = 0; is-deeply EVAL($it), Nil, @type[$++]; is-deeply $foo, 5, @type[$++]; } } subtest 'The postfix "until" statement works' => { my $foo; # ++$foo until $foo >= 5 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('++'), operand => RakuAST::Var::Lexical.new('$foo') ), loop-modifier => RakuAST::StatementModifier::Until.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::Var::Lexical.new('$foo'), infix => RakuAST::Infix.new('>='), right => RakuAST::IntLiteral.new(5), ) ) ) ); is-deeply $deparsed, '++$foo until $foo >= 5', 'deparse'; for 'AST', $ast, 'Str', $deparsed, 'Raku', EVAL($raku) -> $type, $it { $foo = 0; is-deeply EVAL($it), Nil, @type[$++]; is-deeply $foo, 5; @type[$++]; } } subtest 'The postfix "for" statement works' => { my $foo; # ++$foo for 1 .. 5 ast RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('++'), operand => RakuAST::Var::Lexical.new('$foo') ), loop-modifier => RakuAST::StatementModifier::For.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyInfix.new( left => RakuAST::IntLiteral.new(1), infix => RakuAST::Infix.new('..'), right => RakuAST::IntLiteral.new(5), ) ) ) ); is-deeply $deparsed, '++$foo for 1 .. 5', 'deparse'; for 'AST', $ast, 'Str', $deparsed, 'Raku', EVAL($raku) -> $type, $it { $foo = 0; is-deeply EVAL($it), Nil, @type[$++]; is-deeply $foo, 5, @type[$++]; } } # vim: expandtab shiftwidth=4