use v6.e.PREVIEW; use Test; plan 8; 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; } sub no-args() { 444 } subtest 'Can make a named call with no arguments' => { # no-args() ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('no-args') ); is-deeply $deparsed, 'no-args()', 'deparsed'; is-deeply $_, 444, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } sub one-arg($x) { 9 * $x } subtest 'Can make a named call with one positional argument' => { # one-arg(5) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('one-arg'), args => RakuAST::ArgList.new(RakuAST::IntLiteral.new(5)) ); is-deeply $deparsed, 'one-arg(5)', 'deparsed'; is-deeply $_, 45, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } sub two-args($x, $y) { $x - $y } subtest 'Can make a named call with two positional arguments' => { # two-args(5, 3) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('two-args'), args => RakuAST::ArgList.new( RakuAST::IntLiteral.new(5), RakuAST::IntLiteral.new(3), ) ); is-deeply $deparsed, 'two-args(5, 3)', 'deparsed'; is-deeply $_, 2, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } sub two-named(:$n1, :$n2) { $n1 / $n2 } subtest 'Can make a named call with two named arguments' => { # two-named(n1 => 200, n2 => 4) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('two-named'), args => RakuAST::ArgList.new( RakuAST::FatArrow.new( key => 'n1', value => RakuAST::IntLiteral.new(200) ), RakuAST::FatArrow.new( key => 'n2', value => RakuAST::IntLiteral.new(4) ) ) ); is-deeply $deparsed, 'two-named(n1 => 200, n2 => 4)', 'deparsed'; is-deeply $_, 50.0, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Duplicated named arguments are correctly handled' => { # two-named(n1 => 200, n2 => 4, n1 => 400) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('two-named'), args => RakuAST::ArgList.new( RakuAST::FatArrow.new( key => 'n1', value => RakuAST::IntLiteral.new(200) ), RakuAST::FatArrow.new( key => 'n2', value => RakuAST::IntLiteral.new(4) ), RakuAST::FatArrow.new( key => 'n1', value => RakuAST::IntLiteral.new(400) ), ) ); is-deeply $deparsed, 'two-named(n1 => 200, n2 => 4, n1 => 400)', 'deparsed'; is-deeply $_, 100.0, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } my $target = -> $a, $b { $a - $b } subtest 'Can make a call on a term with two positional arguments' => { # $target(9, 4) ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('$target'), postfix => RakuAST::Call::Term.new( args => RakuAST::ArgList.new( RakuAST::IntLiteral.new(9), RakuAST::IntLiteral.new(4), ) ) ); is-deeply $deparsed, '$target(9, 4)', 'deparsed'; is-deeply $_, 5, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a call that flattens into array' => { my @args; # no-args(|@args) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('no-args'), args => RakuAST::ArgList.new( RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('|'), operand => RakuAST::Var::Lexical.new('@args') ) ) ); is-deeply $deparsed, 'no-args(|@args)', 'deparsed'; is-deeply $_, 444, "@type[$++]: flattening empty list" for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); @args = 95, 40; # two-args(|@args) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('two-args'), args => RakuAST::ArgList.new( RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('|'), operand => RakuAST::Var::Lexical.new('@args') ) ) ); is-deeply $deparsed, 'two-args(|@args)', 'deparsed'; is-deeply $_, 55, "@type[$++]: two positional arguments" for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a call that flattens into hash' => { my %args; # no-args(|%args) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('no-args'), args => RakuAST::ArgList.new( RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('|'), operand => RakuAST::Var::Lexical.new('%args') ) ) ); is-deeply $deparsed, 'no-args(|%args)', 'deparsed'; is-deeply $_, 444, "@type[$++]: flattening empty list" for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); %args = 60, 12; # two-named(|%args) ast RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier('two-named'), args => RakuAST::ArgList.new( RakuAST::ApplyPrefix.new( prefix => RakuAST::Prefix.new('|'), operand => RakuAST::Var::Lexical.new('%args') ) ) ); is-deeply $deparsed, 'two-named(|%args)', 'deparsed'; is-deeply $_, 5.0, "@type[$++]: flattening two named arguments" for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } # vim: expandtab shiftwidth=4