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
  | log

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 "," } ")"

log = "LOG" log-arg { log-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
  = list-expression
  | arithmetic-expression

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

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

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

arithmetic-factor
  = "(" arithmetic-expression ")"
  | decimal
  | hexadecimal
  | var { "[" arithmetic-expression "]" }
  | var { "[" arithmetic-expression "]" } ".LENGTH"
  | var { "[" arithmetic-expression "]" } ".SIZE"
  | var { "[" arithmetic-expression "]" } ".ISIZE"
  | var { "[" arithmetic-expression "]" } ".LSIZE"
  | var { "[" arithmetic-expression "]" } ".INDEXOF"
    arithmetic-or-list-expression [ 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
  = "INTEGER"
  | "LIST"

rel-op
  = "="
  | "<>"
  | "<"
  | "<="
  | ">"
  | ">="

unary-op
  = "+"
  | "-"
  | "~" (* BITWISE NOT *)

add-op
  = "+"
  | "-"
  | "|" (* BITWISE OR *)
  | "^" (* BITWISE XOR *)

mul-op
  = "*"
  | "/"
  | "%" (* MODULO *)
  | "&" (* BITWISE AND *)
  | "<<" (* BITWISE SHIFT LEFT *)
  | ">>" (* BITWISE SHIFT RIGHT *)

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

module-name = module-name-char { module-name-char }

module-name-char
  = "_"
  | "."
  | alphanum

alphanum
  = alpha
  | digit

decimal = digit { digit }

hexadecimal = "0x" hexa-char { hexa-char }

hexa-char
  = digit
  | "a" | "b" | "c" | "d" | "e" | "f"
  | "A" | "B" | "C" | "D" | "E" | "F"

string = """ { string-char } """

string-char
  = "\\"
  | "\""
  | "\n"
  | not-backslash-char (* ASCII CODE BETWEEN 32 AND 126, EXCEPT "\" *)

digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

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"

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-expression
  = ivar { "[" arithmetic-expression "]" } ":="
    ivar { "[" arithmetic-expression "]" } "+" arithmetic-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 "("