Intermediate Code Grammar

intermediate‑code‑file → compile‑unit‑header type‑declarations? data‑definitions? functions? metadata?
compile‑unit‑header → cu ( compile‑unit‑id , md‑struct‑ref )
compile‑unit‑id → hexnum | number | id
type‑declarations → types { type‑declaration* }
type‑declaration → str‑type‑id = type (structure‑type | array‑type | function‑type)
str‑type‑id → (type‑identifier | primitive‑type‑name) **
structure‑type → { ((str‑type‑id (: offset = number)?) % ,) } (size = number , alignment = number)?
array‑type → [ number id str‑type‑id ] (size = number , alignment = number)?
function‑type → function str‑type‑id ( (str‑type‑id % ,)? )
data‑definitions → data { data‑definition* }
data‑definition → type‑expr once? id (; | = constant)
functions → function*
function → function‑header { basic‑block* }
function‑header → function type‑expr once? id md‑struct‑ref?
basic‑block → label instructions
label → @ number
instructions → instruction (md‑struct‑ref)?+
instruction → store‑instruction | arg‑instruction | jump‑instruction | branch‑instruction | procedure‑call‑instruction | ret‑instruction | switch‑instruction | value‑instruction | no‑operation‑instruction | save‑instruction
store‑instruction → store type‑expr typed‑value , type‑expr typed‑value
arg‑instruction → arg type‑expr typed‑value
jump‑instruction → jmp label
branch‑instruction → branch type‑expr typed‑value , label , label
procedure‑call‑instruction → call type‑expr typed‑value
ret‑instruction → ret (void − (void *) | type‑expr typed‑value)
switch‑instruction → switch type‑expr typed‑value label , [ (type‑expr typed‑value , label % :) ]
value‑instruction → type‑expr typed‑value = operation
operation → unary‑instruction | binary‑instruction | param‑instruction | local‑instruction | load‑instruction | elem‑addr‑instruction | ptr‑offset‑instruction | ptr‑diff‑instruction | function‑call‑instruction | trap‑instruction
unary‑instruction → unary‑inst operand
unary‑inst → not | neg | signextend | zeroextend | truncate | bitcast | inttofloat | floattoint | inttoptr | ptrtoint
binary‑instruction → binary‑inst operand , operand
binary‑inst → add | sub | mul | div | mod | and | or | xor | shl | shr | equal | less
param‑instruction → param
local‑instruction → local type‑expr
load‑instruction → load operand
elem‑addr‑instruction → elemaddr operand , operand
ptr‑offset‑instruction → ptroffset operand , operand
ptr‑diff‑instruction → ptrdiff operand , operand
function‑call‑instruction → call type‑expr typed‑value
trap‑instruction → trap type‑expr typed‑value , type‑expr typed‑value , type‑expr typed‑value
no‑operation‑instruction → nop
save‑instruction → save
operand → type‑expr typed‑value
type‑expr → postfix‑type‑expr
postfix‑type‑expr → primary‑type‑expr **
primary‑type‑expr → type‑id | primitive‑type
type‑id → type‑identifier
primitive‑type → void | bool | sbyte | byte | short | ushort | int | uint | long | ulong | float | double
primitive‑type‑name → void | bool | sbyte | byte | short | ushort | int | uint | long | ulong | float | double
typed‑value → id‑value | symbol‑value | literal‑value
id‑value → $ number
symbol‑value → @ id
literal‑value → true | false | null | number | id
constant → conversion‑constant | cls‑id‑constant | ptr‑constant | symbol‑constant | bool‑constant | sbyte‑constant | byte‑constant | short‑constant | ushort‑constant | int‑constant | uint‑constant | long‑constant | ulong‑constant | float‑constant | double‑constant | array‑constant | structure‑constant | string‑constant | string‑array‑constant
conversion‑constant → type‑expr conv ( constant )
cls‑id‑constant → type‑expr cls‑id
ptr‑constant → type‑expr null | type‑expr literal‑value
symbol‑constant → type‑expr symbol‑value
bool‑constant → bool (true | false)
sbyte‑constant → sbyte number
byte‑constant → byte number
short‑constant → short number
ushort‑constant → ushort number
int‑constant → int number
uint‑constant → uint number
long‑constant → long number
ulong‑constant → ulong number
float‑constant → float number
double‑constant → double number
array‑constant → [ (constant % ,)? ]
structure‑constant → { (constant % ,)? }
string‑constant → string
string‑array‑constant → string‑array‑prefix [ (constant % ,)? ]
string‑array‑prefix → id
metadata → metadata { md‑struct* }
md‑item → md‑bool | md‑long | md‑string | md‑struct‑ref
md‑bool → true | false
md‑long → number
md‑string → string
md‑struct‑ref → ! number
md‑struct → ! number = { (md‑field % ,)? }
md‑field → id : md‑item