use v6.e.PREVIEW; use Test; plan 20; my $ast; my $deparsed; my $raku; my @type = | xx *; sub ast(RakuAST::Node:D $node --> Nil) { $ast := $node; $deparsed := $node.DEPARSE; $raku := 'use experimental :rakuast; ' ~ $node.raku; diag $deparsed.chomp; } subtest 'Application of a positive power postfix operator' => { # 3²² ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(3), postfix => RakuAST::Postfix::Power.new(22) ); is-deeply $deparsed, '3²²', 'deparse'; is-deeply $_, 31381059609, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Application of a negative power postfix operator' => { # 4⁻² ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(4), postfix => RakuAST::Postfix::Power.new(-2) ); is-deeply $deparsed, '4⁻²', 'deparse'; is-deeply $_, 0.0625, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } # XXX enable test when RAKUDO_RAKUAST=1 is default #subtest 'Application of a vulgar postfix operator' => { # # 3²/₃ # ast RakuAST::ApplyPostfix.new( # operand => RakuAST::IntLiteral.new(3), # postfix => RakuAST::Postfix::Vulgar.new(2/3) # ); # # is-deeply $deparsed, '3²/₃', 'deparse'; # is-deeply $_, 11/3 , @type[$++] # for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); # is-deeply EVAL("3⅔"), 11/3, 'unicode'; #} subtest 'Application of a (user-defined) postfix operator to a literal' => { sub postfix:($n) { [*] 1..$n } # 4! ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(4), postfix => RakuAST::Postfix.new(:operator) ); is-deeply $deparsed, '4!', 'deparse'; is-deeply $_, 24, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Basic single-dimension array index' => { my @a = 10..20; # @a[5] ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('@a'), postfix => RakuAST::Postcircumfix::ArrayIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(5) ) ) ) ); is-deeply $deparsed, '@a[5]', 'deparse'; is-deeply $_, 15, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Basic single-dimension array index with colonpair' => { my @a = 10..20; # @a[5]:exists ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('@a'), postfix => RakuAST::Postcircumfix::ArrayIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(5) ) ), colonpairs => ( RakuAST::ColonPair::True.new("exists"), ) ) ); is-deeply $deparsed, '@a[5]:exists', 'deparse'; is-deeply $_, True, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Zen array slice' => { my @a = 10..20; # @a[] ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('@a'), postfix => RakuAST::Postcircumfix::ArrayIndex.new( index => RakuAST::SemiList.new ) ); is-deeply $deparsed, '@a[]', 'deparse'; is-deeply $_, @a, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Zen array slice' => { my @a = 10..20; # @a[] ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('@a'), postfix => RakuAST::Postcircumfix::ArrayIndex.new( index => RakuAST::SemiList.new, colonpairs => ( RakuAST::ColonPair::True.new("v"), ) ) ); is-deeply $deparsed, '@a[]:v', 'deparse'; is-deeply $_, @a.List, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Multi-dimensional array indexing' => { my @a[3;3] = , , ; # @a[2;1] ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('@a'), postfix => RakuAST::Postcircumfix::ArrayIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(2) ), RakuAST::Statement::Expression.new( expression => RakuAST::IntLiteral.new(1) ) ) ) ); is-deeply $deparsed, '@a[2; 1]', 'deparse'; is-deeply $_, 'h', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } # Not yet supported?? #subtest 'Multi-dimensional array indexing with colonpairs' => { # my @a[3;3] = , , ; # # # @a[2;1] # ast RakuAST::ApplyPostfix.new( # operand => RakuAST::Var::Lexical.new('@a'), # postfix => RakuAST::Postcircumfix::ArrayIndex.new( # index => RakuAST::SemiList.new( # RakuAST::Statement::Expression.new( # expression => RakuAST::IntLiteral.new(2) # ), # RakuAST::Statement::Expression.new( # expression => RakuAST::IntLiteral.new(1) # ) # ), # colonpairs => ( # RakuAST::ColonPair::True.new("v"), # ) # ) # ); # # is-deeply $deparsed, '@a[2; 1]:v', 'deparse'; # is-deeply $_, 'h', @type[$++] # for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); #} { my %h = a => 'add', s => 'subtract'; subtest 'Basic single-dimension hash index' => { # %h{"s")} ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('s') ) ) ) ); is-deeply $deparsed, '%h{"s"}', 'deparse'; is-deeply $_, 'subtract', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Basic single-dimension hash index with colonpairs' => { # %h{"s")}:p ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('s') ) ), colonpairs => ( RakuAST::ColonPair::True.new("p"), ) ) ); is-deeply $deparsed, '%h{"s"}:p', 'deparse'; is-deeply $_, 's' => 'subtract', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Zen hash slice' => { # %h{} ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new ) ); is-deeply $deparsed, '%h{}', 'deparse'; is-deeply $_, %h, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Zen hash slice with colonpairs' => { # %h{}:k ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new, colonpairs => ( RakuAST::ColonPair::True.new("k"), ) ) ); is-deeply $deparsed, '%h{}:k', 'deparse'; is-deeply $_, | , @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Basic literal hash index' => { # %h ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('s')], processors => ['words','val'] ) ) ); is-deeply $deparsed, '%h', 'deparse'; is-deeply $_, 'subtract', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Basic literal hash index with colonpairs' => { # %h:exists ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('s')], processors => ['words','val'] ), colonpairs => ( RakuAST::ColonPair::True.new("exists"), ) ) ); is-deeply $deparsed, '%h:exists', 'deparse'; is-deeply $_, True, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Literal hash index with multiple keys' => { # %h ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('s a')], processors => ['words','val'] ) ) ); is-deeply $deparsed, '%h', 'deparse'; is-deeply $_, ('subtract', 'add'), @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Literal hash index with multiple keys with colonpairs' => { # %h ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('s a')], processors => ['words','val'] ), colonpairs => ( RakuAST::ColonPair::True.new("exists"), ) ) ); is-deeply $deparsed, '%h:exists', 'deparse'; is-deeply $_, (True, True), @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Empty literal hash index works as zen slice' => { # %h<> ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('')], processors => ['words','val'] ) ) ); is-deeply $deparsed, '%h<>', 'deparse'; is-deeply $_, %h, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Empty literal hash index works as zen slice with colonpairs' => { # %h<>:v ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::LiteralHashIndex.new( index => RakuAST::QuotedString.new( segments => [RakuAST::StrLiteral.new('')], processors => ['words','val'] ), colonpairs => ( RakuAST::ColonPair::True.new("v"), ) ) ); is-deeply $deparsed, '%h<>:v', 'deparse'; is-deeply $_, | , @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } } subtest 'Multi-dimensional hash indexing' => { my %h = x => { :1a, :2b }, y => { :3a, :4b }; # %h{'y';'a'} ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('y') ), RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('a') ) ) ) ); is-deeply $deparsed, '%h{"y"; "a"}', 'deparse'; is-deeply $_, 3, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Multi-dimensional hash indexing with colonpairs' => { my %h = x => { :1a, :2b }, y => { :3a, :4b }; # %h{'y';'a'}:v ast RakuAST::ApplyPostfix.new( operand => RakuAST::Var::Lexical.new('%h'), postfix => RakuAST::Postcircumfix::HashIndex.new( index => RakuAST::SemiList.new( RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('y') ), RakuAST::Statement::Expression.new( expression => RakuAST::StrLiteral.new('a') ) ), colonpairs => ( RakuAST::ColonPair::True.new("v"), ) ) ); is-deeply $deparsed, '%h{"y"; "a"}:v', 'deparse'; is-deeply $_, 3, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } # vim: expandtab shiftwidth=4