# use Grammar::Tracer; grammar Vixen { token id { <[A..Za..z*]>+ } token selector { <[A..Za..z*]>+ \: } token string { \" <[A..Za..z*]>* \" } token param { \: } token ass { \:\= } proto rule obj {*} rule obj:sym { } rule obj:sym { '(' ')' } rule obj:sym { } rule obj:sym { } proto rule unary {*} rule unary:sym { (* % ) } proto rule message {*} rule message:sym { ( )+ } proto rule call {*} rule call:sym { (* % ';') } proto rule assign {*} rule assign:sym { } rule assign:sym { } proto rule exprs {*} rule exprs:sym { ( '.')* '^' } rule exprs:sym { ( '.')* } rule block { '[' * '|' ']' } rule TOP { } } class MakeBlocks { has Int $!syms; method gensym { $!syms += 1; "gs" ~ $!syms; } method callTo($name, @row) { say "callTo $name ", @row; my $args = @row.join; say "backtick -E $name \{ \$\{V\}/call: $args \}"; $name; } method callAnon(@row) { self.callTo: self.gensym, @row; } method obj:sym($/) { make $.Str; } method obj:sym($/) { make $.made; } method obj:sym($/) { make $.Str; } method obj:sym($/) { make $.Str; } method unary:sym($/) { my Str $rv = $.made; for $ { my @row = @_.map: *.made; @row.prepend: $rv; say "my unary row: ", @row; my ($name, $line) = self.callAnon(@row); $rv = $name; say $line; } make $rv; } method message:sym($/) { my $verb = $/[0, 2 ... *].join; say "my verb: $verb"; make $[1, 3 ... *].map(*.made).prepend: $verb; } method call:sym($/) { my Str $target = $.made; my Str $rv = $target; for $ { my @row = @_.map: *.target; @row.prepend: $target; say "my cascade row: ", @row; my ($name, $line) = self.callAnon(@row); $rv = $name; say $line; } make $rv; } method assign:sym($/) { make self.callTo($.made, $.made); } method assign:sym($/) { make self.callAnon($.made); } method exprs:sym($/) { make $.made; } method exprs:sym($/) { say "importas -iS Nil \$Nil"; make $.made; } method block($/) { say "#!/usr/bin/env -S execlineb -s", $.elems + 1; say "importas -iS V"; say "export self \$1"; for $.kv -> $i, $n { say "export ", substr($n, 1), " \$", $i + 2; } make $.made; } method TOP($/) { say "top"; make $.made; } } my $actions = MakeBlocks.new(); my $parsed = Vixen.parse: slurp $*IN, :$actions; say "Parse tree: ", $parsed; say "Made: ", $parsed.made;