grammar Think {
rule TOP {
[<_Statement>]*
}
token _Statement {
[
|<_Macro>
|<_value:sym<string>>
|<_call>
|<_calln>
|<_callfn>
|<_callf>
|<_expr>
|<_value>
|<_op>
|\s+
]
}
proto token _value { * }
token _value:sym<string> {
'"'.*?<![\\]>'"'
}
token _value:sym<number> {
\d+['.'\d+]?
}
token _value:sym<name> {
<.alpha>[\w|\-]*
}
token _Macro {
^^\s*'%'<_value:sym<name>>\s+(<-[\n\r]>+)
}
token _op {
#<!after <.alpha>><.punct><!before <._name>>
<[\+\*/\^\%\!\=\&\|\~\,]>+ |
'-'<!after <._value>> |
<!before <.alpha>>'.'
}
token _term {
[<_value>|<_expr>|<_calln>|<_callfn>]
}
token _expr {
['('
<._anyn>
[\s* <_op> \s*
<._anyn>]*
')']:
}
token _calln {
['('\s*
$<left>=<._anyn>
\s+
$<center>=<._anyn>
':'\s*
$<params>=[
<._anyn>\s*
[\,\s*<._anyn>]*
]
\s*')']:
}
token _call {
[^^\s*
$<left>=<._anyn>
\s*
$<center>=<._anyn>
':'\s*
$<params>=[
<._anyn>\s*
[\,\s*<._anyn>]*
]
\s*]
}
token _callfn {
['('\s*
$<func>=<._anyn>
\s+
$<params>=[
<._anyn><![\:]>\s*
[\,\s*<._anyn>]*
]
\s*')']
}
token _callf {
[^^\s*
$<func=._anyn>
\s+
$<params>=[
<._anyn><![\:]>\s*
[\,\s*<._anyn>]*
]
\s*$$]
}
token _anyn {
[<_calln>|<_callfn>|<_term>]
}
}
my $ast = q{
%make a ?pmc
%set a 1
%make b ?pmc
%set b 2.3
say ((a + b) - 2 * (b - a))
say "banana"
say (add-attr banana: idk, 5
)
add-attr mango: idk, ((get-attr banana: idk) * 2)
say 5
}.trim;
class Think-actions {
method TOP($/) {
#say $/;
#`[$/.make: {
_value => $<_value>».made,
_call => $<_call>».made,
_calln => $<_calln>».made,
_callf => $<_callf>».made,
_callfn => $<_callfn>».made
}]
make $<_Statement>».made;
#say $/.caps
}
method _Statement($/) {
make $/
}
method _term($/) {
make $/}
method _value:sym<string>($/) {
make $/.Str}
method _value:sym<number>($/) {
make $/.Num}
method _value:sym<name>($/) {
make {var => $/.Str}}
method _callf($/) {
make {$<func>.made => $<params>».made}
}
}
$ast = Think.parse: $ast, actions => Think-actions.new;
say $ast.made.flat;
#`[
$ast = Think.parse: $ast;#, actions => Think-actions.new;
say $ast[0].map: {
.keys[0] => .values.pairs[0]{0}.pairs
};]
#`[
for $ast.actions.nodes {
#say "{.key} => {.value}"
}
my @n;
say gather for $ast.values {
my $p = $_;
given $p.keys[0] {
when "_Macro" {
take $p.values.flat>>.[1]
}
}
}
for ^$ast.flat.list.elems {
#say $ast.flat.list[$_].pairs[0].value.pairs;
@n.push: [.keys[0], .values[0].make: $_] given $ast.flat.list[$_]
}]
#say $ast[0]
#[0].values[0].pairs
#(say $_ given .kv) for $ast.hash;
#say [.<_name>, .[0]]>>.Str.perl for $ast.hash<_Macro>