Prequel
primitive recursive driven programming
prequel-program = [ "@" module-name ":" newline ] module { "@" module-name ":" newline module } module = instruction newline instructions instructions = { instruction newline } instruction = assignments | list-modifications | conditionals | bounded-loop | module-call | function-call assignments = assignment | assignment-random | assignment-module-call | assignment-function-call | unassignment assignment = mvar { index } "=" expression assignment-random = mvar { index } "~=" "random" | mvar { index } "~=" expression assignment-module-call = { mvar { index } "," } "=" module-name "(" { expression "," } ")" assignment-function-call = { mvar { index } "," } "=" function-name "(" { arg "," } ")" unassignment = mvar ".unassign" "(" ")" list-modifications = push | queue | pop | unqueue push = mvar { index } ".push" "(" expression [ "," expression ] ")" queue = mvar { index } ".queue" "(" expression ")" pop = [ mvar { index } "=" ] mvar { index } ".pop" "(" [ expression ] ")" unqueue = [ mvar { index } "=" ] mvar { index } ".unqueue" "(" ")" conditionals = "if" expression newline instructions { "elif" expression newline instructions } [ "else" newline instructions ] "endif" bounded-loop = "repeat" ivar newline instructions (* including "repstop" or "repnext", *) (* or its synonyms "break" and "continue", *) (* respectively *) "endrep" module-call = module-name "(" { expression "," } ")" function-call = function-name "(" { arg "," } ")" index = "[" expression "]" expression = "(" expression ")" | "not" expression | expression "and" expression | expression "or" expression | expression "is" [ "not" ] expression-type | expression rel-op expression | unary-op expression | expression add-op expression | expression mul-op expression | var { index } | var { index } ".length" "(" ")" | var { index } ".indexof" "(" expression [ "," expression ] ")" | var { index } ".exists" "(" expression [ "," expression [ "," expression ] ] ")" | "[" { expression "," } "]" { index } | number | math-factor number = decimal | binary | hexadecimal math-factor = "math.abs" "(" expression ")" | "math.acos" "(" expression ")" | "math.asin" "(" expression ")" | "math.atan" "(" expression ")" | "math.atan2" "(" expression "," expression ")" | "math.ceil" "(" expression ")" | "math.cos" "(" expression ")" | "math.e" | "math.exp" "(" expression ")" | "math.exp2" "(" expression ")" | "math.floor" "(" expression ")" | "math.log" "(" expression ")" | "math.log2" "(" expression ")" | "math.max" "(" expression "," expression ")" | "math.min" "(" expression "," expression ")" | "math.pi" | "math.pow" "(" expression "," expression ")" | "math.round" "(" expression ")" | "math.sign" "(" expression ")" | "math.sin" "(" expression ")" | "math.sqrt" "(" expression ")" | "math.tan" "(" expression ")" module-name = ivar function-name = evar | "return" | "print" | "halt" | "loop" arg = expression | string var = mvar | evar mvar = ivar | csvar ivar = ivar-start-char { ivar-char } ivar-start-char = "_" | alpha ivar-char = "_" | alphanum csvar = "!" ivar [ "@" module-name ] evar = ivar "." ivar { "." ivar } expression-type = "number" | "list" | "empty" | "undefined" rel-op = "==" | "<>" | "<" | "<=" | ">" | ">=" unary-op = "+" | "-" | "~" (* bitwise not *) add-op = "+" | "-" | "|" (* bitwise or *) | "^" (* bitwise xor *) mul-op = "*" | "/" | "%" (* modulo *) | "//" (* integer division *) | "&" (* bitwise and *) | "<<" (* bitwise shift left *) | ">>" (* bitwise shift right *) alphanum = alpha | d-digit decimal = d-digit { d-digit } [ "." d-digit { d-digit } ] binary = "0b" b-digit { b-digit } [ "." b-digit { b-digit } ] hexadecimal = "0x" h-digit { h-digit } [ "." h-digit { h-digit } ] string = """ { string-char } """ alpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" d-digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" b-digit = "0" | "1" h-digit = d-digit | "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" string-char = non-backslash-char (* ascii code between 32 and 126, except "\" *) | "\" "\" (* "\" *) | "\" """ (* """ *) | "\" "n" (* newline *) newline = line-feed-char (* ascii code 10 *)
sugar-incr mvar { index } "++" = mvar { index } "+=" "1" sugar-decr mvar { index } "--" = mvar { index } "-=" "1" sugar-toggle mvar { index } "~~" = mvar { index } "=" "~" mvar { index } sugar-plus-assign mvar { index } "+=" expression = mvar { index } "=" mvar { index } "+" expression sugar-minus-assign mvar { index } "-=" expression = mvar { index } "=" mvar { index } "-" expression sugar-mul-assign mvar { index } "*=" expression = mvar { index } "=" mvar { index } "*" expression sugar-div-assign mvar { index } "/=" expression = mvar { index } "=" mvar { index } "/" expression sugar-mod-assign mvar { index } "%=" expression = mvar { index } "=" mvar { index } "%" expression sugar-idv-assign mvar { index } "//=" expression = mvar { index } "=" mvar { index } "//" expression sugar-and-assign mvar { index } "&=" expression = mvar { index } "=" mvar { index } "&" expression sugar-or-assign mvar { index } "|=" expression = mvar { index } "=" mvar { index } "|" expression sugar-xor-assign mvar { index } "^=" expression = mvar { index } "=" mvar { index } "^" expression sugar-shift-left-assign mvar { index } "<<=" expression = mvar { index } "=" mvar { index } "<<" expression sugar-shift-right-assign mvar { index } ">>=" expression = mvar { index } "=" mvar { index } ">>" expression sugar-last-comma-par "(" { element "," } ")" = "(" [ element { "," element } ] ")" sugar-last-comma-sqr "[" { element "," } "]" = "[" [ element { "," element } ] "]" sugar-last-comma-assign "," "=" = "="