program := __* stmt* stmt := assignment / funcall stop / conditional / loop / expr stop expr := - _ expr / expr "+" _ expr / expr "-" - expr / expr "*" _ expr / expr "/" _ expr / "(" _ expr ")" / ['"'] ((!['"'] [_] / #"\""#)*) ['"'] / funcall / fundef / boolean / id / num boolean := ("true" / "false") _ id := letter (letter / digit / ['?'|'.'|'-'])* _ num := (digit+ "."? digit* / "." digit+) _ assignment := id "<-" _ expr stop funcall := id "(" _ expr ** ("," _) ")" _ funcdef := id? "->" _ block conditional := if __* elif* __* else? __* if := "if" _ expr block elif := "elif" _ expr block else := "else" _ block loop := "loop" _ (until / over / block) until := "until" _ expr block over := "over"_ id "in" _ expr block block := expr / indented_block indented_block := stop indent __* stmt+ dedent letter := ['A'..='Z'] / ['a'..='z'] digit := ['0'..='9'] stop := __+ / eof indent := ">>>" dedent := "<<<" _ := ['\t'|' ']* __ := comment? newline / comment &eof comment := "#" (!newline [_])* &(newline / eof) newline := "\r\n" \ "\r" \ "\n" eof := ![_]