Shane's Turing complete language; P6 grammar, pars

Run Settings
LanguageRaku
Language Version
Run Command
# See https://www.reddit.com/r/ProgrammingLanguages/comments/d076go/how_to_write_a_turingcomplete_programming/ezaqcs2 no precompilation; use lib '.'; use Shanish-grammar; use Shanish-toP6; use Grammar::ToAST; use MONKEY; my $mo = Shanish-grammar .parse: 'sieve-code'.&slurp, actions => Shanish-toP6.new; say cst2ast $mo;
maxPrime = 6 [0] = 0 i = 1 while < i maxPrime do [i] = i i = + i 1 end i = 2 while < i maxPrime do if [i] then j = * i 2 while < j maxPrime do [j] = 0 j = + j i end end i = + i 1 end
no precompilation; #use Grammar::Tracer; grammar Shanish-grammar { rule TOP { <.ws> <stmts> } rule stmts { <expr>+ } rule expr { <ifExpr> | <whileExpr> | <opExpr> | <storeSet> | <storeGet> | <value> | <var> } rule ifExpr { 'if' <stmts> 'then' <stmts> [ 'else' <stmts> ]? 'end' } rule whileExpr { 'while' <stmts> 'do' <stmts> 'end' } rule storeSet { [ '[' <stmts> ']' | <var> ] '=' <expr> } rule storeGet { '[' <stmts> ']' | <var> } my @keywords = < if then else while do end >; token var { :i <!before @keywords> <[_a..z]> \w* } my @ops = << <= >= == - + * / < > >>; token op { @ops } rule opExpr { <op> <expr> <expr> } token value { '-'? <[0..9]>+ } }
no precompilation; unit class Shanish-toP6; use Grammar::ToAST; has %!store; method TOP ($/) { hang #`[[[ put %!store ]]] } #method stmts ($/) { hang } #method expr ($/) { hang } #method ifExpr ($/) { hang #`[[[ p6 "if &cake() \{\n &cake(:piece(1)) } else \{\n &cake(:piece(2)) }\n" ]]] } #method whileExpr ($/) { hang #`[[[ p6 "while &cake() \{\n &cake(:piece(1)) }\n" ]]] } #method storeSet ($/) # { hang #`[[[ make '%!store{\'' ~ ($<var> // '[\'~' ~ $<stmts>.made ~ '~\']') ~ "'} = " ~ expr-made($<expr>) ]]] } #method storeGet ($/) # { hang #`[[[ make '%!store{\'' ~ ($<var> // '[\'~' ~ $<stmts>.made ~ '~\']') ~ "'}" ]]] } #method opExpr ($/) { hang #`[[[ make expr-made($<expr>[0]) ~ " $<op> " ~ expr-made($<expr>[1]) ]]] } #method value ($/) { hang #`[[[ make ~ $/ ]]] }
no precompilation; unit module Grammar::ToAST; our proto cst2ast (|) is export { say 'cst2ast proto'; {*} } multi cst2ast (Match $_ where *.ast) { say '.ast'; .ast } # if arg is capture, with `.ast`, then return it multi cst2ast (Match $_ where *.list) { say '.list'; .&hashcheck: 0; .&cst2ast for .list } # else `cst2ast` of numbered captures if any multi cst2ast (Match $_ where *.hash) { say '.hash'; .&hashcheck: 1; cst2ast .hash.pairs[0].value } # else `cst2ast` of first named capture value multi cst2ast (Match $_) { say 'Match'; $_ } # else return capture as is multi cst2ast (@_) { say '@_'; .&cst2ast for @_ } # if NOT a single capture, then `cst2ast` args sub hashcheck ($_, $element-count) { # expecting either 0 or 1 hash elements return if .hash == $element-count; note "cst2ast ignoring hash pairs(s):\n", .hash.pairs[$element-count..*].join: "\n" } our proto hung (|) is export { say 'hung proto'; {*} } # Multi that will match for a *quantified* sub-capture `$<foo>` (eg sub-rule was `<foo>*` or `<foo>+`, NOT `<foo>` or `<foo>?`). multi hung (List $captures where *.all ~~ Match) { say '.all'; .&hung for $captures } # Multis that will match for a *non* quantified sub-capture `$<foo>` (i.e. sub-rule was eg `<foo>`, NOT eg `<foo>*`). multi hung (Match $_ where .ast) { say '.ast'; .ast } # if .ast already generated then use that multi hung (Match $_ where .list) { say '.list'; .&hung for .list } # elsif positional captures then use them multi hung (Match $_ where .hash) { say '.hash'; .hash.pairs[0].value } # elsif named captures then use the first value multi hung (Match $_) { say '$_'; $_ } # else use cst (concrete syntax tree capture) sub msg ($msg) { warn "hung $msg" } our proto hang (|) is export { say 'hang proto'; {*} } multi hang () { CALLERS::<$/> .make: hung CALLERS::<$/> } # if nullary `hang` then write caller's `hung` to its `.ast` multi hang ($ast) { CALLERS::<$/> .make: $ast } # elsif unary `hang` then write passed arg to caller's `.ast` multi hang (*@hung) { CALLERS::<$/> .make: do .&hung for @hung } # otherwise write list of `hung` of each passed arg to caller's `.ast` proto wrap { * } multi wrap () { :wrap }
Editor Settings
Theme
Key bindings
Full width
Lines