#!/usr/bin/env raku
my %VARS;
my %FNS = '+' => { $^a + $^b },
'-' => { $^a - $^b },
'*' => { $^a * $^b },
'/' => { $^a / $^b };
grammar Simple {
token TOP { <statement>* %% \n {make $<statement>.map(*.made)} }
token statement { \s* [ <comment> || <loop> || <assignement> || <code> {make $<code>.made} || <call> {make $<call>.made} ] }
token comment { '#' \N* }
regex loop { 'for' \s+ $<cond>=<code> \n+ $<body> = (<!before 'end'> <statement>)* \s+ 'end'
{ my $cond = $<cond>;
my @statements = $<statement>;
while Simple.parse($cond).made { Simple.parse($_) for @statements; }
}
}
token assignement { $<identifier> = \w+ \s* '=' \s* <code> {%VARS{$<identifier>} = $<code>.made} }
token call { $<args> = ((\w+)* %% <-[\S\n]>+) $<fn> = \N+ <?{ %FNS{$<fn>}:exists }>
{make %FNS{$<fn>}(|$<args>[0].map({Simple.parse($_).made[0]}))} # this return Nil somehow
# but when printing directly, shows the right answer
}
token code { $<value> = \d+ {make $<value>.Int} | $<identifier> = \w+ {make %VARS{$<identifier>} // 0 } | <call> {make $<call>.made} }
}
my $code = Simple.parse: q:to/LANG/;
n = 4
z = n 3 +
LANG
say $code;
say %VARS;