/r/programminglanguages toy

Run Settings
LanguageRaku
Language Version
Run Command
use Grammar::Tracer; grammar toy { rule TOP { <.ws> <statement>* %% ';' } proto rule statement {*} rule statement:import { 'import' <value:string> } rule statement:print { 'print(' ~ ')' <value> } rule statement:vdecl { 'var' <ident> [ '=' <value> | 'in' <ident> ] } rule statement:ifelse { 'if' <condition> '{' ~ '}' <TOP> [ 'else' '{' ~ '}' <TOP> ]? } rule statement:while { 'while' <condition> '{' ~ '}' <TOP> } rule statement:expr { <expr> } proto rule value {*} token value:boolean { 'true' | 'false' } token value:string { '"' ~ '"' <-["]>* } token value:number { \d+ [ '.' \d+ ]? } rule value:array { '[' ~ ']' <value>* %% ',' } rule value:object { '{' ~ '}' [ [ <ident> ':' <value> ]* %% ',' ] } token value:atkey { <value> '[' ~ ']' <value:string> } token value:dotkey { <value> '.' <ident> } token value:ident { <ident> } token condition { '(' ~ ')' [ '!'? <expr> ] } rule expr(:$left) # pass :left to avoid grammar left recursion { <prefix-op> <expr> | '(' ~ ')' <expr> | <value> | <statement:vdecl> | { say 42; die } <{'<postfixed-expr>' unless $left}> | { say 99; die } <{'<infixed-exprs>' unless $left}> } rule postfixed-expr { <expr(:left)> <postfix-op> } rule infixed-exprs { <expr(:left)> <infix-op> <expr> } token prefix-op { '+' | '-' | '++' } token postfix-op { '+' | '-' | '++' } token infix-op { '+' | '-' | '*' | '/' | '<' | '>' | '==' } regex ws { <!ww> \s* [ [ '//' \N* || '/*' ~ '*/' [ <!before '*/'> . ]* ] \s* ]* } } say toy.parse: slurp 'test.toy';
// oneline comment /* multiline comment */ import "standard"; //imports built-in libraries, or .toy files import "external.toy"; print("hello world\n"); //print is a keyword, rather than a function - useful for debugging //five types of data - booleans, strings, numbers, arrays and dictionaries var a = true; var b = false; var c = "Hello world"; //only allow double-quotes for strings var d = 42; //numbers can optionally have trailing decimal places... var e = [a, b, c, d, "hello world", 42]; //mixed types allowed in arrays and objects var f = { //objects are key-value pairs, essentially JSON hello: "world" //"hello" is the string key - this is for familiarity with JS }; f["hello"] == f.hello //the '.' operator only works for string keys /* if (!b) { //conditional } else { //otherwise } var sentinel = 0; while (sentinel < 10) { sentinel++; //can also use '+=' operator } for (var element in e) { //array iteration e[0] == element } for (var element in f) { //dictionary iteration element.key element.value } //functions can be defined in several ways var g = function(arguments) { // } var h = (arguments) => { // } var i = x => x; //parenthesis and braces are optional, when there is only one argument or one expression respectfully //closures are explicitly supported var createCounter = function() { var count = 0; return () => ++count; } //an incorrect number of arguments is invalid, but the 'rest' parameter is allowed, creating an array var j = function(...args) { // }*/
Editor Settings
Theme
Key bindings
Full width
Lines