Prequel
primitive recursive driven programming
prequel-program = [ "@" module-name ":" newline ] module { "@" module-name ":" newline module } module = instruction newline instructions instructions = { instruction newline } instruction = assignment | assignment-random | unassign | push | queue | pop | unqueue | if | repeat | procedure-call | print assignment = mvar { index } "=" expression assignment-random = mvar { index } "~=" "random" | mvar { index } "~=" expression unassign = mvar ".unassign" push = mvar { index } ".push" "(" expression [ "," expression ] ")" queue = mvar { index } ".queue" "(" expression ")" pop = [ mvar { index } "=" ] mvar { index } ".pop" "(" [ expression ] ")" unqueue = [ mvar { index } "=" ] mvar { index } ".unqueue" "(" ")" if = "if" expression newline instructions { "elif" expression newline instructions } [ "else" newline instructions ] "endif" repeat = "repeat" ivar newline instructions (* including "break" or "continue" *) "endrep" procedure-call = procedure-name "(" { arg "," } ")" print = "print" "(" print-arg { "," print-arg } ")" index = "[" expression "]" expression = "(" expression ")" | "not" expression | expression "and" expression | expression "or" expression | expression is-or-isnot 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 ] ")" | "[" { 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 ")" procedure-name = evar | "call" | "return" arg = expression | module-name-ref | mvar-ref | string print-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 } module-name-ref = "@" module-name mvar-ref = "&" mvar { index } is-or-isnot = "is" | "isnot" expression-type = "number" | "list" | "empty" | "procedure" | "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 *) module-name = module-name-start-char { module-name-char } module-name-start-char = "_" | alpha module-name-char = "_" | alphanum 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 "\" *) | "\" printable-char (* ascii code between 32 and 126 *) 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-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-procedure-assign { mvar { index } "," } "=" procedure-name "(" { arg "," } ")" = procedure-name "(" { mvar-ref "," } { arg "," } ")" sugar-last-comma-par "(" { element "," } ")" = "(" [ element { "," element } ] ")" sugar-last-comma-sqr "[" { element "," } "]" = "[" [ element { "," element } ] "]" sugar-last-comma-proc "," "=" procedure-name "(" = "=" procedure-name "("