Prequel
primitive recursive driven programming


Prequel Grammar

prequel-program =
  [ "@" module-name ":" newline ]
  module
  {
  "@" module-name ":" newline
  module
  }

module =
  instruction newline
  sequence-instructions

sequence-instructions =
  {
  instruction newline
  }

instruction
  = assignment
  | assignment-random
  | unassign
  | push
  | queue
  | pop
  | unqueue
  | if
  | repeat
  | procedure-call
  | debugl

assignment =
  ivar { "[" arithmetic-expression "]" } ":=" arithmetic-or-list-expression

assignment-random
  = ivar { "[" arithmetic-expression "]" } ":~" "RANDOM"
  | ivar { "[" arithmetic-expression "]" } ":~" arithmetic-expression

unassign = ivar ".UNASSIGN"

push =
  ivar { "[" arithmetic-expression "]" } ".PUSH"
  arithmetic-or-list-expression [ arithmetic-expression ]

queue =
  ivar { "[" arithmetic-expression "]" } ".QUEUE"
  arithmetic-or-list-expression

pop =
  [ ivar { "[" arithmetic-expression "]" } ":=" ]
  ivar { "[" arithmetic-expression "]" } ".POP" [ arithmetic-expression ]

unqueue =
  [ ivar { "[" arithmetic-expression "]" } ":=" ]
  ivar { "[" arithmetic-expression "]" } ".UNQUEUE"

if =
  "IF" logical-expression newline
   sequence-instructions
  {
  "ELSIF" logical-expression newline
   sequence-instructions
  }
  [
  "ELSE" newline
   sequence-instructions
  ]
  "ENDIF"

repeat =
  "REPEAT" ivar newline
   sequence-instructions (* INCLUDING "REPSTOP" or "REPNEXT" *)
  "ENDREP"

procedure-call = evar "(" { arg "," } ")"

debugl = "DEBUGL" debugl-arg { debugl-arg }

logical-expression = logical-term { "OR" logical-term }

logical-term = logical-factor { "AND" logical-factor }

logical-factor
  = "(" logical-expression ")"
  | "NOT" logical-factor
  | relational-expression

relational-expression
  = var is-or-is-not vartype
  | var { "[" arithmetic-expression "]" } is-or-is-not vartype-data
  | arithmetic-expression rel-op arithmetic-expression

arithmetic-or-list-expression
  = "[" { arithmetic-or-list-expression "," } "]"
  | arithmetic-expression

arithmetic-expression =
  [ unary-op ] arithmetic-term { add-op arithmetic-term }

arithmetic-term = arithmetic-factor { mul-op arithmetic-factor }

arithmetic-factor
  = "(" arithmetic-expression ")"
  | base-factor

base-factor
  = decimal
  | binary
  | hexadecimal
  | var { "[" arithmetic-expression "]" }
  | var { "[" arithmetic-expression "]" } ".LENGTH"
  | var { "[" arithmetic-expression "]" } ".SIZE"
  | var { "[" arithmetic-expression "]" } ".NSIZE"
  | var { "[" arithmetic-expression "]" } ".LSIZE"
  | var { "[" arithmetic-expression "]" } ".INDEXOF"
    arithmetic-or-list-expression [ arithmetic-expression ]
  | math-factor

math-factor
  = "ABS" "(" arithmetic-expression ")"
  | "ACOS" "(" arithmetic-expression ")"
  | "ASIN" "(" arithmetic-expression ")"
  | "ATAN" "(" arithmetic-expression ")"
  | "ATAN2" "(" arithmetic-expression "," arithmetic-expression ")"
  | "CEIL" "(" arithmetic-expression ")"
  | "COS" "(" arithmetic-expression ")"
  | "E"
  | "EXP" "(" arithmetic-expression ")"
  | "EXP2" "(" arithmetic-expression ")"
  | "FLOOR" "(" arithmetic-expression ")"
  | "LOG" "(" arithmetic-expression ")"
  | "LOG2" "(" arithmetic-expression ")"
  | "MAX" "(" arithmetic-expression "," arithmetic-expression ")"
  | "MIN" "(" arithmetic-expression "," arithmetic-expression ")"
  | "PI"
  | "POW" "(" arithmetic-expression "," arithmetic-expression ")"
  | "ROUND" "(" arithmetic-expression ")"
  | "SIGN" "(" arithmetic-expression ")"
  | "SIN" "(" arithmetic-expression ")"
  | "SQRT" "(" arithmetic-expression ")"
  | "TAN" "(" arithmetic-expression ")"

var
  = ivar
  | evar

ivar = ivar-start-char { ivar-char }

ivar-start-char
  = "_"
  | alpha

ivar-char
  = "_"
  | alphanum

evar = ivar "." ivar { "." ivar }

arg
  = arithmetic-or-list-expression
  | module-name-ref
  | ivar-ref
  | string

module-name-ref = "@" module-name

ivar-ref = "&" ivar { "[" arithmetic-expression "]" }

is-or-is-not
  = "IS"
  | "IS NOT"

vartype
  = vartype-data
  | "PROCEDURE"
  | "UNDEFINED"

vartype-data
  = "NUMBER"
  | "LIST"
  | "EMPTY"

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 *)

debugl-arg
  = arithmetic-or-list-expression
  | logical-expression
  | string

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
  = "\\"
  | "\""
  | "\n"
  | not-backslash-char (* ASCII CODE BETWEEN 32 AND 126, EXCEPT "\" *)

newline = line-feed-char (* ASCII CODE 10 *)

Syntactic Sugar

sugar-incr
    ivar { "[" arithmetic-expression "]" } "++"
  = ivar { "[" arithmetic-expression "]" } "+=" "1"

sugar-decr
    ivar { "[" arithmetic-expression "]" } "--"
  = ivar { "[" arithmetic-expression "]" } "-=" "1"

sugar-toggle
    ivar { "[" arithmetic-expression "]" } "~~"
  = ivar { "[" arithmetic-expression "]" } ":="
    "~" ivar { "[" arithmetic-expression "]" }

sugar-plus-assign
    ivar { "[" arithmetic-expression "]" } "+=" arithmetic-or-list-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "+" arithmetic-or-list-expression

sugar-minus-assign
    ivar { "[" arithmetic-expression "]" } "-=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "-" arithmetic-expression

sugar-mul-assign
    ivar { "[" arithmetic-expression "]" } "*=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "*" arithmetic-expression

sugar-div-assign
    ivar { "[" arithmetic-expression "]" } "/=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "/" arithmetic-expression

sugar-mod-assign
    ivar { "[" arithmetic-expression "]" } "%=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "%" arithmetic-expression

sugar-and-assign
    ivar { "[" arithmetic-expression "]" } "&=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "&" arithmetic-expression

sugar-or-assign
    ivar { "[" arithmetic-expression "]" } "|=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "|" arithmetic-expression

sugar-xor-assign
    ivar { "[" arithmetic-expression "]" } "^=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "^" arithmetic-expression

sugar-shift-left-assign
    ivar { "[" arithmetic-expression "]" } "<<=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "<<" arithmetic-expression

sugar-shift-right-assign
    ivar { "[" arithmetic-expression "]" } ">>=" arithmetic-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } ">>" arithmetic-expression

sugar-procedure-assign
    { ivar { "[" arithmetic-expression "]" } "," }
    ":=" evar "(" { arg "," } ")"
  = evar "(" { ivar-ref "," } { arg "," } ")"

sugar-last-comma-par
    "(" { element "," } ")"
  = "(" [ element { "," element } ] ")"

sugar-last-comma-sqr
    "[" { element "," } "]"
  = "[" [ element { "," element } ] "]"

sugar-last-comma-proc
    "," ":=" evar "("
  = ":=" evar "("