/* converted on Wed Apr 13, 2022, 13:18 (UTC+02) by bison-to-w3c v0.57 which is Copyright (c) 2011-2022 by Gunther Rademacher <grd@gmx.net> */
defs ::= ( procDef | includeProc | importExtern | structDef | bdDef | typeDef | constDef | includeDef | areaDef | areaImportDef )*
areaDef ::= type const? allocRef
areaImportDef
::= import header type const? allocIdent
header ::= ident ( '/' ident )* '.' ident
includeDef
::= include ident
constDef ::= type? ident '=' exp ';'
procDef ::= type ident '(' args ')' '{' stmts '}' prePostBlk
includeProc
::= import '(' header ',' ident ')' type ident '(' args ')'
importExtern
::= extern header type ident
tyArg ::= type ident
args ::= tyArg? ( ',' tyArg? )*
prePostBlk
::= ( '{' ( prePost ';' )+ '}' )?
prePost ::= ( pre | post ) '(' exp ')'
ptrIdent ::= '*' ident
arrIdent ::= ident '[' ']'
structIdent
::= ident '{' '}'
allocIdent
::= ptrIdent
| arrIdent
| structIdent
allocRef ::= alloc ( ptrIdent ( '=' exp )? | arrIdent ( '=' '{' exps '}' )? | structIdent ( '=' structInit )? ) ';'
simpleStmt
::= ( ( assert | assume | store exp as | assign type? ident '=' ) exp | refCopy ident ident | ivoryMacro | break | return exp? | ident ( expArgs | '<-' ivoryMacro ) ) ';'
| allocRef
ivoryMacro
::= iMacro ident expArgs?
blkStmt ::= ( ( mapArr | ( upTo | downFrom ) exp | ( upFromTo | downFromTo ) '(' exp ',' exp ')' ) ident | forever | if exp '{' stmts '}' else ) '{' stmts '}'
stmts ::= ( simpleStmt | blkStmt )*
expArgs ::= '(' exps ')'
exps ::= exp? ( ',' exp? )*
structInit
::= ivoryMacro
| '{' fieldAssign? ( ',' fieldAssign? )* '}'
fieldAssign
::= ident '=' exp
exp ::= integer
| str
| floatlit
| ident expArgs?
| return
| '(' exp ')'
| ( '*' | '!' | '-' | '~' ) exp
| exp ( ( '@' | '.' | '->' | '||' | '&&' | '|' | '^' | '&' | '<<' | '>>' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '+' | '-' | '*' | '/' | '%' | '?' exp ':' ) exp | '[' exp ']' )
| '&' ident
| libFuncExp
| ivoryMacro
libFuncExp
::= ( abs | signum | expOp | sqrt | log | pow | sin | cos | tan | asin | acos | atan | atan2 | sinh | cosh | tanh | asinh | acosh | atanh | isnan | isinf | round | ceil | floor | const | div | castWith | safeCast | bitCast | twosCompCast | twosCompRep | toIx | fromIx | ixSize | arrayLen | sizeOf | nullPtr | refToPtr | toCArray ) expArgs
typeDef ::= ty tyident '=' type ';'
type ::= baseType
| cType
| '(' type ')'
baseType ::= simpleCType
| tyident
simpleCType
::= bool
| char
| float
| double
| string
| void
| int8_t
| int16_t
| int32_t
| int64_t
| uint8_t
| uint16_t
| uint32_t
| uint64_t
| ix_t integer
szType ::= iMacro tyidentifier
| integer
cType ::= ( const? scopeC '*' | '&' ) type
| baseType ( '[' szType ']' )+
| struct structName
scopeC ::= ( S | G | ident )?
typeHS ::= simpleHSType
| hsType
| tyident
| '(' typeHS ')'
simpleHSType
::= IBool
| IChar
| IFloat
| IDouble
| IString
| '(' ')'
| Sint8
| Sint16
| Sint32
| Sint64
| Uint8
| Uint16
| Uint32
| Uint64
| Ix integer
hsType ::= ( ( Ref | ConstRef ) scopeHS | Array szType | Stored ) typeHS
| Struct structName
scopeHS ::= Stack tyident
| Global
bitType ::= Bit
| Bits integer
| BitArray integer bitType
| '(' bitType ')'
| tyident
structDef
::= struct structName '{' field ( ';' field? )* '}'
| abstract struct structName str
| string struct structName integer
structName
::= tyident
| ident
field ::= ident '::' typeHS
| type ident
bdDef ::= bitdata tyident '::' bitType '=' bdConstr ( '|' bdConstr )*
bdConstr ::= ident bdRecord bdLayout
bdRecord ::= ( '{' bdField ( ',' bdField )* '}' )?
bdField ::= ( ident | '_' ) '::' bitType
bdLayout ::= ( as bdItem ( '#' bdItem )* )?
bdItem ::= ident
| integer
| bitLiteral
bitLiteral
::= bitlit
ident ::= ( tyidentifier '.' )? identifier
tyident ::= tyidentifier ( '.' tyidentifier )?
//Tokens
//\(\w\S+\)\s+{ Located $$ (\S+ \("[^"]+"\).+
//-- Statements
if ::= "if"
else ::= "else"
assert ::= "assert"
assume ::= "assume"
pre ::= "pre"
post ::= "post"
assign ::= "let"
return ::= "return"
alloc ::= "alloc"
store ::= "store"
refCopy ::= "memcpy"
mapArr ::= "map"
upTo ::= "upTo"
upFromTo ::= "upFromTo"
downFrom ::= "downFrom"
downFromTo ::= "downFromTo"
forever ::= "forever"
break ::= "break"
//-- Start of Ivory macros
iMacro ::= "$"
//-- Expressions
abs ::= "abs"
signum ::= "signum"
expOp ::= "exp"
sqrt ::= "sqrt"
log ::= "log"
pow ::= "pow"
div ::= "div"
sin ::= "sin"
cos ::= "cos"
tan ::= "tan"
asin ::= "asin"
acos ::= "acos"
atan ::= "atan"
atan2 ::= "atan2"
sinh ::= "sinh"
cosh ::= "cosh"
tanh ::= "tanh"
asinh ::= "asinh"
acosh ::= "acosh"
atanh ::= "atanh"
isnan ::= "isnan"
isinf ::= "isinf"
round ::= "round"
ceil ::= "ceil"
floor ::= "floor"
const ::= "const"
//-- Casting
safeCast ::= "safeCast"
bitCast ::= "bitCast"
castWith ::= "castWith"
twosCompCast ::= "twosCompCast"
twosCompRep ::= "twosCompRep"
//-- Other internals
fromIx ::= "fromIx"
ixSize ::= "ixSize"
toIx ::= "toIx"
toCArray ::= "toCArray"
arrayLen ::= "arrayLen"
sizeOf ::= "sizeOf"
nullPtr ::= "nullPtr"
refToPtr ::= "refToPtr"
/*
//-- Type
'::' { Located $$ (TokSym "::") }
'?' { Located $$ (TokSym "?") }
':' { Located $$ (TokSym ":") }
//-- Struct field dereference
'.' { Located $$ (TokSym ".") }
'->' { Located $$ (TokSym "->") }
'==' { Located $$ (TokSym "==") }
'!=' { Located $$ (TokSym "!=") }
//-- Used for deref and mult
'*' { Located $$ (TokSym "*") }
'/' { Located $$ (TokSym "/") }
'+' { Located $$ (TokSym "+") }
'-' { Located $$ (TokSym "-") }
'%' { Located $$ (TokSym "%") }
'=' { Located $$ (TokSym "=") }
'<' { Located $$ (TokSym "<") }
'<=' { Located $$ (TokSym "<=") }
'>=' { Located $$ (TokSym ">=") }
'>' { Located $$ (TokSym ">") }
'|' { Located $$ (TokSym "|") }
'&' { Located $$ (TokSym "&") }
'^' { Located $$ (TokSym "^") }
'~' { Located $$ (TokSym "~") }
'!' { Located $$ (TokSym "!") }
'&&' { Located $$ (TokSym "&&") }
'||' { Located $$ (TokSym "||") }
'<<' { Located $$ (TokSym "<<") }
'>>' { Located $$ (TokSym ">>") }
//-- Other symbols
'(' { Located $$ (TokBrack "(") }
')' { Located $$ (TokBrack ")") }
'{' { Located $$ (TokBrack "{") }
'}' { Located $$ (TokBrack "}") }
'[' { Located $$ (TokBrack "[") }
']' { Located $$ (TokBrack "]") }
';' { Located $$ (TokSep ";") }
',' { Located $$ (TokSep ",") }
'@' { Located $$ (TokSym "@") }
'<-' { Located $$ (TokSym "<-") }
*/
//-- Types
bool ::= "bool"
char ::= "char"
float ::= "float"
double ::= "double"
void ::= "void"
int8_t ::= "int8_t"
int16_t ::= "int16_t"
int32_t ::= "int32_t"
int64_t ::= "int64_t"
uint8_t ::= "uint8_t"
uint16_t ::= "uint16_t"
uint32_t ::= "uint32_t"
uint64_t ::= "uint64_t"
S ::= "S"
G ::= "G"
IBool ::= "IBool"
IChar ::= "IChar"
IFloat ::= "IFloat"
IDouble ::= "IDouble"
IString ::= "IString"
Sint8 ::= "Sint8"
Sint16 ::= "Sint16"
Sint32 ::= "Sint32"
Sint64 ::= "Sint64"
Uint8 ::= "Uint8"
Uint16 ::= "Uint16"
Uint32 ::= "Uint32"
Uint64 ::= "Uint64"
Ix ::= "Ix"
ix_t ::= "ix_t"
Ref ::= "Ref"
ConstRef ::= "ConstRef"
Array ::= "Array"
Struct ::= "Struct"
Stored ::= "Stored"
Stack ::= "Stack"
Global ::= "Global"
//-- Keywords
struct ::= "struct"
abstract ::= "abstract"
string ::= "string"
ty ::= "type"
include ::= "include"
import ::= "import"
extern ::= "extern"
//-- Bit data
bitdata ::= "bitdata"
Bit ::= "Bit"
Bits ::= "Bits"
BitArray ::= "BitArray"
as ::= "as"
/*
'_' { Located $$ (TokSym "_") }
'#' { Located $$ (TokSym "#") }
*/
/*
-- Statements
if { Located $$ (TokReserved "if") }
else { Located $$ (TokReserved "else") }
assert { Located $$ (TokReserved "assert") }
assume { Located $$ (TokReserved "assume") }
pre { Located $$ (TokReserved "pre") }
post { Located $$ (TokReserved "post") }
assign { Located $$ (TokReserved "let") }
return { Located $$ (TokReserved "return") }
alloc { Located $$ (TokReserved "alloc") }
store { Located $$ (TokReserved "store") }
refCopy { Located $$ (TokReserved "memcpy") }
mapArr { Located $$ (TokReserved "map") }
upTo { Located $$ (TokReserved "upTo") }
upFromTo { Located $$ (TokReserved "upFromTo") }
downFrom { Located $$ (TokReserved "downFrom") }
downFromTo { Located $$ (TokReserved "downFromTo") }
forever { Located $$ (TokReserved "forever") }
break { Located $$ (TokReserved "break") }
-- Start of Ivory macros
iMacro { Located $$ (TokSym "$") }
-- Expressions
abs { Located $$ (TokReserved "abs") }
signum { Located $$ (TokReserved "signum") }
expOp { Located $$ (TokReserved "exp") }
sqrt { Located $$ (TokReserved "sqrt") }
log { Located $$ (TokReserved "log") }
pow { Located $$ (TokReserved "pow") }
div { Located $$ (TokReserved "div") }
sin { Located $$ (TokReserved "sin") }
cos { Located $$ (TokReserved "cos") }
tan { Located $$ (TokReserved "tan") }
asin { Located $$ (TokReserved "asin") }
acos { Located $$ (TokReserved "acos") }
atan { Located $$ (TokReserved "atan") }
atan2 { Located $$ (TokReserved "atan2") }
sinh { Located $$ (TokReserved "sinh") }
cosh { Located $$ (TokReserved "cosh") }
tanh { Located $$ (TokReserved "tanh") }
asinh { Located $$ (TokReserved "asinh") }
acosh { Located $$ (TokReserved "acosh") }
atanh { Located $$ (TokReserved "atanh") }
isnan { Located $$ (TokReserved "isnan") }
isinf { Located $$ (TokReserved "isinf") }
round { Located $$ (TokReserved "round") }
ceil { Located $$ (TokReserved "ceil") }
floor { Located $$ (TokReserved "floor") }
const { Located $$ (TokReserved "const") }
-- Casting
safeCast { Located $$ (TokReserved "safeCast") }
bitCast { Located $$ (TokReserved "bitCast") }
castWith { Located $$ (TokReserved "castWith") }
twosCompCast { Located $$ (TokReserved "twosCompCast") }
twosCompRep { Located $$ (TokReserved "twosCompRep") }
-- Other internals
fromIx { Located $$ (TokReserved "fromIx") }
ixSize { Located $$ (TokReserved "ixSize") }
toIx { Located $$ (TokReserved "toIx") }
toCArray { Located $$ (TokReserved "toCArray") }
arrayLen { Located $$ (TokReserved "arrayLen") }
sizeOf { Located $$ (TokReserved "sizeOf") }
nullPtr { Located $$ (TokReserved "nullPtr") }
refToPtr { Located $$ (TokReserved "refToPtr") }
-- Type
'::' { Located $$ (TokSym "::") }
'?' { Located $$ (TokSym "?") }
':' { Located $$ (TokSym ":") }
-- Struct field dereference
'.' { Located $$ (TokSym ".") }
'->' { Located $$ (TokSym "->") }
'==' { Located $$ (TokSym "==") }
'!=' { Located $$ (TokSym "!=") }
-- Used for deref and mult
'*' { Located $$ (TokSym "*") }
'/' { Located $$ (TokSym "/") }
'+' { Located $$ (TokSym "+") }
'-' { Located $$ (TokSym "-") }
'%' { Located $$ (TokSym "%") }
'=' { Located $$ (TokSym "=") }
'<' { Located $$ (TokSym "<") }
'<=' { Located $$ (TokSym "<=") }
'>=' { Located $$ (TokSym ">=") }
'>' { Located $$ (TokSym ">") }
'|' { Located $$ (TokSym "|") }
'&' { Located $$ (TokSym "&") }
'^' { Located $$ (TokSym "^") }
'~' { Located $$ (TokSym "~") }
'!' { Located $$ (TokSym "!") }
'&&' { Located $$ (TokSym "&&") }
'||' { Located $$ (TokSym "||") }
'<<' { Located $$ (TokSym "<<") }
'>>' { Located $$ (TokSym ">>") }
-- Other symbols
'(' { Located $$ (TokBrack "(") }
')' { Located $$ (TokBrack ")") }
'{' { Located $$ (TokBrack "{") }
'}' { Located $$ (TokBrack "}") }
'[' { Located $$ (TokBrack "[") }
']' { Located $$ (TokBrack "]") }
';' { Located $$ (TokSep ";") }
',' { Located $$ (TokSep ",") }
'@' { Located $$ (TokSym "@") }
'<-' { Located $$ (TokSym "<-") }
-- Types
bool { Located $$ (TokReserved "bool") }
char { Located $$ (TokReserved "char") }
float { Located $$ (TokReserved "float") }
double { Located $$ (TokReserved "double") }
void { Located $$ (TokReserved "void") }
int8_t { Located $$ (TokReserved "int8_t") }
int16_t { Located $$ (TokReserved "int16_t") }
int32_t { Located $$ (TokReserved "int32_t") }
int64_t { Located $$ (TokReserved "int64_t") }
uint8_t { Located $$ (TokReserved "uint8_t") }
uint16_t { Located $$ (TokReserved "uint16_t") }
uint32_t { Located $$ (TokReserved "uint32_t") }
uint64_t { Located $$ (TokReserved "uint64_t") }
S { Located $$ (TokReserved "S") }
G { Located $$ (TokReserved "G") }
IBool { Located $$ (TokReserved "IBool") }
IChar { Located $$ (TokReserved "IChar") }
IFloat { Located $$ (TokReserved "IFloat") }
IDouble { Located $$ (TokReserved "IDouble") }
IString { Located $$ (TokReserved "IString") }
Sint8 { Located $$ (TokReserved "Sint8") }
Sint16 { Located $$ (TokReserved "Sint16") }
Sint32 { Located $$ (TokReserved "Sint32") }
Sint64 { Located $$ (TokReserved "Sint64") }
Uint8 { Located $$ (TokReserved "Uint8") }
Uint16 { Located $$ (TokReserved "Uint16") }
Uint32 { Located $$ (TokReserved "Uint32") }
Uint64 { Located $$ (TokReserved "Uint64") }
Ix { Located $$ (TokReserved "Ix") }
ix_t { Located $$ (TokReserved "ix_t") }
Ref { Located $$ (TokReserved "Ref") }
ConstRef { Located $$ (TokReserved "ConstRef") }
Array { Located $$ (TokReserved "Array") }
Struct { Located $$ (TokReserved "Struct") }
Stored { Located $$ (TokReserved "Stored") }
Stack { Located $$ (TokReserved "Stack") }
Global { Located $$ (TokReserved "Global") }
-- Keywords
struct { Located $$ (TokReserved "struct") }
abstract { Located $$ (TokReserved "abstract") }
string { Located $$ (TokReserved "string") }
ty { Located $$ (TokReserved "type") }
include { Located $$ (TokReserved "include") }
import { Located $$ (TokReserved "import") }
extern { Located $$ (TokReserved "extern") }
-- Bit data
bitdata { Located $$ (TokReserved "bitdata") }
Bit { Located $$ (TokReserved "Bit") }
Bits { Located $$ (TokReserved "Bits") }
BitArray { Located $$ (TokReserved "BitArray") }
as { Located $$ (TokReserved "as") }
'_' { Located $$ (TokSym "_") }
'#' { Located $$ (TokSym "#") }
*/
//--------------------------------------------------------------------------------
//-- Precedence
%right '#'
%right '?' ':'
%left '||'
%left '&&'
%left '|' '&'
%left '^'
%nonassoc '==' '!='
%nonassoc '<' '<=' '>' '>='
%left '<<' '>>'
%left '+' '-'
%left '*' '/' '%'
%right '*' '~' '!' '-'
//-- '[' assumed to be followed by ']'
%left '.' '@' '->' '[' ']'
%right ADDR
//-- Tighter than normal binding
%right
abs
signum
expOp
sqrt
log
pow
sin
cos
tan
asin
acos
atan
sinh
cosh
tanh
asinh
acosh
atanh
isnan
isinf
round
ceil
floor
const
div
%%
//----------------------------------------
//-- Top-level definitions
//defs :: { [GlobalSym] }
defs : defs procDef { GlobalProc $2 : $1 }
| defs includeProc { GlobalInclProc $2 : $1 }
| defs importExtern { GlobalExtern $2 : $1 }
| defs structDef { GlobalStruct $2 : $1 }
| defs bdDef { GlobalBitData $2 : $1 }
| defs typeDef { GlobalTypeDef $2 : $1 }
| defs constDef { GlobalConstDef $2 : $1 }
| defs includeDef { GlobalInclude $2 : $1 }
| defs areaDef { GlobalArea $2 : $1 }
| defs areaImportDef { GlobalAreaImport $2 : $1 }
| {- empty -} { [] }
//----------------------------------------
//-- Include areas
//areaDef :: { AreaDef }
areaDef :
type allocRef
{ AreaDef False $1 (unLoc $2) (getLoc $2)
}
| type const allocRef
{ AreaDef True $1 (unLoc $3) (getLoc $3)
}
//areaImportDef :: { AreaImportDef }
areaImportDef :
import header type allocIdent
{ AreaImportDef (unLoc $4) False $3 $2
(getLoc $1 <> getLoc $4)
}
| import header type const allocIdent
{ AreaImportDef (unLoc $5) True $3 $2
(getLoc $1 <> getLoc $5)
}
//----------------------------------------
//-- header paths
//filepath :: { [String] }
filepath :
filepath ident '/' { (unLoc $2 ++ "/") : $1 }
| {- empty -} { [] }
//header :: { String }
header :
filepath ident '.' ident
{ concat (reverse $1) ++ unLoc $2 ++ ('.' : unLoc $4) }
//----------------------------------------
//-- Include other modules (Ivory's "depend")
//includeDef :: { IncludeDef }
includeDef : include ident { IncludeDef (unLoc $2) ($1 <> getLoc $2) }
//----------------------------------------
//-- Constant definitions
//constDef :: { ConstDef }
constDef :
ident '=' exp ';' { ConstDef (unLoc $1) $3 Nothing (getLoc $1 <> getLoc $3) }
| type ident '=' exp ';' { ConstDef (unLoc $2) $4 (Just $1) (mconcat [ getLoc $1
, getLoc $2
, getLoc $4]) }
//----------------------------------------
//-- Procs
//-- Defined procedure
//procDef :: { ProcDef }
procDef :
type ident '(' args ')' '{' stmts '}' prePostBlk
{ ProcDef $1 (unLoc $2) (reverse $4) (reverse $7) $9 (mconcat [ getLoc $1
, getLoc $2
, getLoc $7
, getLoc $9
]) }
//-- Externally-defined procedure
//includeProc :: { IncludeProc }
includeProc :
import '(' header ',' ident ')' type ident '(' args ')'
{ IncludeProc $7 (unLoc $8) (reverse $10) ($3, unLoc $5)
(mconcat [ getLoc $1
, getLoc $5
, getLoc $8
]) }
//-- Externally-defined symbols
//importExtern :: { Extern }
importExtern :
extern header type ident
{ Extern (unLoc $4) $2 $3
(mconcat [ getLoc $1, getLoc $4])
}
//tyArg :: { (Type, Var) }
tyArg : type ident { ($1, unLoc $2) }
//-- Zero or more typed arguments, separated by arbitrary many ','s.
//args :: { [(Type, Var)] }
args : args ',' tyArg { $3 : $1 }
| args ',' { $1 }
| tyArg { [$1] }
| {- empty -} { [] }
//-- pre/post conditions
//prePostBlk :: { [PrePost] }
prePostBlk :
'{' prePosts '}' { reverse $2 }
| {- empty -} { [] }
//prePosts :: { [PrePost] }
prePosts :
prePosts prePost ';' { $2 : $1 }
| prePost ';' { [$1] }
//prePost :: { PrePost }
prePost :
pre '(' exp ')' { PreCond $3 }
| post '(' exp ')' { PostCond $3 }
//----------------------------------------
//-- Allocations
//ptrIdent :: { Located RefVar }
ptrIdent : '*' ident { $2 }
//arrIdent :: { Located RefVar }
arrIdent : ident '[' ']' { $1 }
//structIdent :: { Located RefVar }
structIdent : ident '{' '}' { $1 }
//allocIdent :: { Located RefVar }
allocIdent :
ptrIdent { $1 }
| arrIdent { $1 }
| structIdent {$1 }
//allocRef :: { Located AllocRef }
allocRef :
alloc ptrIdent ';' { atBin (AllocBase (unLoc $2) Nothing) $1 $3 }
| alloc ptrIdent '=' exp ';' { atList (AllocBase (unLoc $2) (Just $4))
[$1, getLoc $2, getLoc $4]
}
| alloc arrIdent ';' { atBin (AllocArr (unLoc $2) []) $1 $2 }
| alloc arrIdent '='
'{' exps '}' ';' { atList (AllocArr (unLoc $2) (reverse $5))
[ $1, getLoc $2, getLoc $5]
}
| alloc structIdent ';' { atBin (AllocStruct (unLoc $2) Empty) $1 $2 }
| alloc structIdent '='
structInit ';' { atBin (AllocStruct (unLoc $2) $4) $1 $2 }
//----------------------------------------
//-- Statements
//simpleStmt :: { Stmt }
simpleStmt :
assert exp ';' { LocStmt (atBin (Assert $2) $1 $2) }
| assume exp ';' { LocStmt (atBin (Assume $2) $1 $2) }
| assign ident '=' exp ';' { LocStmt (atList (Assign (unLoc $2) $4 Nothing)
[ $1, getLoc $2, getLoc $4 ]) }
| assign type ident '=' exp ';' { LocStmt (atList (Assign (unLoc $3) $5 (Just $2))
[ $1, getLoc $2, getLoc $3, getLoc $5]) }
| return ';' { LocStmt (ReturnVoid `at` $1) }
| return exp ';' { LocStmt (atBin (Return $2) $1 $2) }
| refCopy ident ident ';' { LocStmt (atList (RefCopy (ExpVar (unLoc $2)) (ExpVar (unLoc $3)))
[$1, getLoc $2, getLoc $3]) }
| allocRef { LocStmt (AllocRef (unLoc $1) `at` (getLoc $1)) }
//-- Storing
| store exp as exp ';' { LocStmt (atList (Store $2 $4) [$1, getLoc $2, getLoc $4]) }
//-- Function calls
| ident expArgs ';' { LocStmt (atBin (NoBindCall (unLoc $1) $2) $1 $2) }
| ivoryMacro ';' { LocStmt ((IvoryMacroStmt Nothing (unLoc $1)) `at` getLoc $1) }
| ident '<-' ivoryMacro ';' { LocStmt (atBin (IvoryMacroStmt (Just (unLoc $1)) (unLoc $3))
$1 $3) }
| break ';' { LocStmt (Break `at` $1) }
//ivoryMacro :: { Located (String, [Exp]) }
ivoryMacro : iMacro ident { atBin (unLoc $2, []) $1 (getLoc $2) }
| iMacro ident expArgs { atList (unLoc $2, $3) [$1, getLoc $2, getLoc $3] }
//blkStmt :: { Stmt }
blkStmt :
mapArr ident '{' stmts '}' { LocStmt (atList (MapArr (unLoc $2) (reverse $4))
[$1, getLoc $2, getLoc $4]) }
| upTo exp ident '{' stmts '}' { LocStmt (atList (UpTo $2 (unLoc $3) (reverse $5))
[$1, getLoc $2, getLoc $3, getLoc $5]) }
| downFrom exp ident '{' stmts '}' { LocStmt (atList (DownFrom $2 (unLoc $3) (reverse $5))
[$1, getLoc $2, getLoc $3, getLoc $5]) }
| upFromTo '(' exp ',' exp ')' ident '{' stmts '}'
{ LocStmt (atList (UpFromTo $3 $5 (unLoc $7) (reverse $9))
[$1, getLoc $3, getLoc $5, getLoc $7, getLoc $9])
}
| downFromTo '(' exp ',' exp ')' ident '{' stmts '}'
{ LocStmt (atList (DownFromTo $3 $5 (unLoc $7) (reverse $9))
[$1, getLoc $3, getLoc $5, getLoc $7, getLoc $9])
}
| forever '{' stmts '}' { LocStmt (atBin (Forever (reverse $3)) $1 $2) }
| if exp '{' stmts '}'
else '{' stmts '}' { LocStmt (atList (IfTE $2 (reverse $4) (reverse $8))
[ getLoc $2, getLoc $4, getLoc $8 ]) }
//-- Zero or more statements.
//stmts :: { [Stmt] }
stmts : stmts simpleStmt { $2 : $1 }
| stmts blkStmt { $2 : $1 }
| {- empty -} { [] }
//expArgs :: { [Exp] }
expArgs : '(' exps ')' { reverse $2 }
//-- Zero or more expressions, separated by arbitrary many ','s.
//exps :: { [Exp] }
exps : exps ',' exp { $3 : $1 }
| exps ',' { $1 }
| exp { [$1] }
| {- empty -} { [] }
//structInit :: { StructInit }
structInit :
ivoryMacro { MacroInit (unLoc $1) }
| '{' fieldAssigns '}' { FieldInits $2 }
//fieldAssigns :: { [(FieldNm, Exp)] }
fieldAssigns :
fieldAssigns ',' fieldAssign { $3 : $1 }
| fieldAssigns ',' { $1 }
| fieldAssign { [$1] }
| {- empty -} { [] }
//fieldAssign :: { (FieldNm, Exp) }
fieldAssign : ident '=' exp { (unLoc $1, $3) }
//----------------------------------------
//-- Expressions
//exp :: { Exp }
exp : integer { let TokInteger i = unLoc $1 in
LocExp (ExpLit (LitInteger i) `at` $1) }
| str { let TokString s = unLoc $1 in
LocExp (ExpLit (LitString s) `at` $1) }
| floatlit { let TokFloat f = unLoc $1 in
LocExp (ExpLit (LitFloat f) `at` $1) }
//-- Works for Haskell values, too!
| ident { LocExp ((ExpVar (unLoc $1)) `at` $1) }
//-- Used only in post-conditions (otherwise, it's a statement).
| return { LocExp (ExpRet `at` $1) }
| '(' exp ')' { $2 }
//-- Areas
| '*' exp { LocExp (atBin (ExpDeref $2) $1 $2) }
| exp '@' exp { LocExp (atBin (ExpArray $1 $3) $1 $3) }
| exp '[' exp ']' { LocExp (atBin (ExpDeref (ExpArray $1 $3)) $1 $3) }
| exp '.' exp { LocExp (atBin (ExpStruct $1 $3) $1 $3) }
| exp '->' exp { LocExp (atBin (ExpDeref (ExpStruct $1 $3)) $1 $3) }
| '&' ident { LocExp (atBin (ExpAddrOf (unLoc $2)) $1 $2) }
| libFuncExp { $1 }
//-- Ivory expression macros
| ivoryMacro { LocExp (IvoryMacroExp `fmap` $1) }
//-- Function calls
| ident expArgs { LocExp (atBin (ExpCall (unLoc $1) $2) $1 $2) }
//-- Unary operators
| '!' exp { LocExp (atBin (ExpOp NotOp [$2]) $1 $2) }
| '-' exp { LocExp (atBin (mkNegate $2) $1 $2) }
| '~' exp { LocExp (atBin (ExpOp BitComplementOp [$2]) $1 $2) }
//-- Binary operators
| exp '||' exp { LocExp (atBin (ExpOp OrOp [$1, $3]) $1 $3) }
| exp '&&' exp { LocExp (atBin (ExpOp AndOp [$1, $3]) $1 $3) }
| exp '|' exp { LocExp (atBin (ExpOp BitOrOp [$1, $3]) $1 $3) }
| exp '^' exp { LocExp (atBin (ExpOp BitXorOp [$1, $3]) $1 $3) }
| exp '&' exp { LocExp (atBin (ExpOp BitAndOp [$1, $3]) $1 $3) }
| exp '<<' exp { LocExp (atBin (ExpOp BitShiftLOp [$1, $3]) $1 $3) }
| exp '>>' exp { LocExp (atBin (ExpOp BitShiftROp [$1, $3]) $1 $3) }
| exp '==' exp { LocExp (atBin (ExpOp EqOp [$1, $3]) $1 $3) }
| exp '!=' exp { LocExp (atBin (ExpOp NeqOp [$1, $3]) $1 $3) }
| exp '<' exp { LocExp (atBin (ExpOp (LtOp False) [$1, $3]) $1 $3) }
| exp '<=' exp { LocExp (atBin (ExpOp (LtOp True) [$1, $3] ) $1 $3)}
| exp '>' exp { LocExp (atBin (ExpOp (GtOp False) [$1, $3]) $1 $3) }
| exp '>=' exp { LocExp (atBin (ExpOp (GtOp True) [$1, $3] ) $1 $3)}
| exp '+' exp { LocExp (atBin (ExpOp AddOp [$1, $3]) $1 $3) }
| exp '-' exp { LocExp (atBin (ExpOp SubOp [$1, $3]) $1 $3) }
| exp '*' exp { LocExp (atBin (ExpOp MulOp [$1, $3]) $1 $3) }
| exp '/' exp { LocExp (atBin (ExpOp DivOp [$1, $3]) $1 $3) }
| exp '%' exp { LocExp (atBin (ExpOp ModOp [$1, $3]) $1 $3) }
//-- Tertiary operators
| exp '?' exp ':' exp { LocExp ((ExpOp CondOp [$1, $3, $5]) `at` (getLoc [$1, $3, $5])) }
//libFuncExp :: { Exp }
libFuncExp :
abs expArgs { LocExp (atBin (ExpOp AbsOp $2) $1 $2) }
| signum expArgs { LocExp (atBin (ExpOp SignumOp $2) $1 $2) }
| expOp expArgs { LocExp (atBin (ExpOp FExpOp $2) $1 $2) }
| sqrt expArgs { LocExp (atBin (ExpOp FSqrtOp $2) $1 $2) }
| log expArgs { LocExp (atBin (ExpOp FLogOp $2) $1 $2) }
| pow expArgs { LocExp (atBin (ExpOp FPowOp $2) $1 $2) }
| sin expArgs { LocExp (atBin (ExpOp FSinOp $2) $1 $2) }
| cos expArgs { LocExp (atBin (ExpOp FCosOp $2) $1 $2) }
| tan expArgs { LocExp (atBin (ExpOp FTanOp $2) $1 $2) }
| asin expArgs { LocExp (atBin (ExpOp FAsinOp $2) $1 $2) }
| acos expArgs { LocExp (atBin (ExpOp FAcosOp $2) $1 $2) }
| atan expArgs { LocExp (atBin (ExpOp FAtanOp $2) $1 $2) }
| atan2 expArgs { LocExp (atBin (ExpOp FAtan2Op $2) $1 $2) }
| sinh expArgs { LocExp (atBin (ExpOp FSinhOp $2) $1 $2) }
| cosh expArgs { LocExp (atBin (ExpOp FCoshOp $2) $1 $2) }
| tanh expArgs { LocExp (atBin (ExpOp FTanhOp $2) $1 $2) }
| asinh expArgs { LocExp (atBin (ExpOp FAsinhOp $2) $1 $2) }
| acosh expArgs { LocExp (atBin (ExpOp FAcoshOp $2) $1 $2) }
| atanh expArgs { LocExp (atBin (ExpOp FAtanhOp $2) $1 $2) }
| isnan expArgs { LocExp (atBin (ExpOp IsNanOp $2) $1 $2) }
| isinf expArgs { LocExp (atBin (ExpOp IsInfOp $2) $1 $2) }
| round expArgs { LocExp (atBin (ExpOp RoundFOp $2) $1 $2) }
| ceil expArgs { LocExp (atBin (ExpOp CeilFOp $2) $1 $2) }
| floor expArgs { LocExp (atBin (ExpOp FloorFOp $2) $1 $2) }
| const expArgs { LocExp (atBin (ExpOp ConstRefOp $2) $1 $2) }
| div expArgs { LocExp (atBin (ExpOp EucDivOp $2) $1 $2) }
| castWith expArgs { LocExp (atBin (ExpOp CastWith $2) $1 $2) }
| safeCast expArgs { LocExp (atBin (ExpOp SafeCast $2) $1 $2) }
| bitCast expArgs { LocExp (atBin (ExpOp BitCast $2) $1 $2) }
| twosCompCast expArgs { LocExp (atBin (ExpOp TwosCompCast $2) $1 $2) }
| twosCompRep expArgs { LocExp (atBin (ExpOp TwosCompRep $2) $1 $2) }
| toIx expArgs { LocExp (atBin (ExpOp ToIx $2) $1 $2) }
| fromIx expArgs { LocExp (atBin (ExpOp FromIx $2) $1 $2) }
| ixSize expArgs { LocExp (atBin (ExpOp IxSize $2) $1 $2) }
| arrayLen expArgs { LocExp (atBin (ExpOp ArrayLen $2) $1 $2) }
| sizeOf expArgs { LocExp (atBin (ExpOp SizeOf $2) $1 $2) }
| nullPtr expArgs { LocExp (atBin (ExpOp NullPtr $2) $1 $2) }
| refToPtr expArgs { LocExp (atBin (ExpOp RefToPtr $2) $1 $2) }
| toCArray expArgs { LocExp (atBin (ExpOp ToCArray $2) $1 $2) }
//----------------------------------------
//-- Types
//typeDef :: { TypeDef }
typeDef :
ty tyident '=' type ';' { TypeDef (unLoc $2) $4 (mconcat [$1, getLoc $2, getLoc $4]) }
//type :: { Type }
type :
baseType { $1 }
| cType { $1 }
| '(' type ')' { $2 }
//baseType :: { Type }
baseType :
simpleCType { $1 }
| tyident { LocTy (TySynonym (unLoc $1) `at` $1) }
//-- C-style types
//simpleCType :: { Type }
simpleCType :
bool { LocTy (TyBool `at` getLoc $1) }
| char { LocTy (TyChar `at` getLoc $1) }
| float { LocTy (TyFloat `at` getLoc $1) }
| double { LocTy (TyDouble `at` getLoc $1) }
| string { LocTy (TyString `at` getLoc $1) }
| void { LocTy (TyVoid `at` getLoc $1) }
| int8_t { LocTy ((TyInt Int8) `at` getLoc $1) }
| int16_t { LocTy ((TyInt Int16) `at` getLoc $1) }
| int32_t { LocTy ((TyInt Int32) `at` getLoc $1) }
| int64_t { LocTy ((TyInt Int64) `at` getLoc $1) }
| uint8_t { LocTy ((TyWord Word8) `at` getLoc $1) }
| uint16_t { LocTy ((TyWord Word16) `at` getLoc $1) }
| uint32_t { LocTy ((TyWord Word32) `at` getLoc $1) }
| uint64_t { LocTy ((TyWord Word64) `at` getLoc $1) }
| ix_t integer { let TokInteger i = unLoc $2 in
LocTy (atBin (TyIx i) $1 $2) }
//idxs :: { [SzType] }
idxs : idxs '[' szType ']' { unLoc $3 : $1 }
| {- empty -} { [] }
//szType :: { Located SzType }
szType : iMacro tyidentifier
{ let TokTyIdent i = unLoc $2 in
Left i `at` $2
}
| integer
{ let TokInteger i = unLoc $1 in
Right i `at` $1
}
//cType :: { Type }
cType :
scopeC '*' type { LocTy (atBin (TyRef (unLoc $1) $3) $1 $3) }
| const scopeC '*' type { LocTy (atList (TyConstRef (unLoc $2) $4)
[$1, getLoc $2, getLoc $4]) }
| baseType '[' szType ']' idxs { LocTy (atBin (tyArray $1 (unLoc $3) $5)
$1 $3)
}
| struct structName { LocTy (atBin (TyStruct (unLoc $2)) $1 $2) }
| '&' type %prec ADDR { LocTy (atBin (TyStored $2) $1 $2) }
//scopeC :: { Located Scope }
scopeC :
S { Stack Nothing `at` $1 }
| G { Global `at` $1 }
| ident { PolyMem (Just (unLoc $1)) `at` (getLoc $1) }
| {- empty -} { PolyMem Nothing `at` NoLoc }
//typeHS :: { Type }
typeHS :
simpleHSType { $1 }
| hsType { $1 }
| tyident { LocTy (TySynonym (unLoc $1) `at` $1) }
| '(' typeHS ')' { $2 }
//-- Haskell-style types
//simpleHSType :: { Type }
simpleHSType :
IBool { LocTy (TyBool `at` getLoc $1) }
| IChar { LocTy (TyChar `at` getLoc $1) }
| IFloat { LocTy (TyFloat `at` getLoc $1) }
| IDouble { LocTy (TyDouble `at` getLoc $1) }
| IString { LocTy (TyString `at` getLoc $1) }
| '(' ')' { LocTy (TyVoid `at` getLoc $1) }
| Sint8 { LocTy ((TyInt Int8) `at` getLoc $1) }
| Sint16 { LocTy ((TyInt Int16) `at` getLoc $1) }
| Sint32 { LocTy ((TyInt Int32)`at` getLoc $1) }
| Sint64 { LocTy ((TyInt Int64) `at` getLoc $1) }
| Uint8 { LocTy ((TyWord Word8) `at` getLoc $1) }
| Uint16 { LocTy ((TyWord Word16) `at` getLoc $1) }
| Uint32 { LocTy ((TyWord Word32) `at` getLoc $1) }
| Uint64 { LocTy ((TyWord Word64) `at` getLoc $1) }
| Ix integer { let TokInteger i = unLoc $2 in
LocTy (atBin (TyIx i) $1 $2) }
//hsType :: { Type }
hsType :
Ref scopeHS typeHS { LocTy (atList (TyRef (unLoc $2) $3) [ getLoc $1
, getLoc $2
, getLoc $3 ]) }
| ConstRef scopeHS typeHS { LocTy (atList (TyConstRef (unLoc $2) $3) [ getLoc $1
, getLoc $2
, getLoc $3 ]) }
| Array szType typeHS { LocTy (atList (TyArray $3 (unLoc $2))
[ getLoc $1, getLoc $2, getLoc $3]) }
| Struct structName { LocTy (atBin (TyStruct (unLoc $2)) $1 $2) }
| Stored typeHS { LocTy (atBin (TyStored $2) $1 $2) }
//scopeHS :: { Located Scope }
scopeHS : Stack tyident { atBin (Stack (Just (unLoc $2))) $1 $2 }
| Global { Global `at` $1 }
//-- Bit types
//bitType :: { BitTy }
bitType :
Bit { LocBitTy (Bit `at` $1) }
| Bits integer { let TokInteger i = unLoc $2 in
LocBitTy (atBin (Bits i) $1 $2) }
| BitArray integer bitType { let TokInteger i = unLoc $2 in
LocBitTy (atList (BitArray i $3) [ getLoc $1
, getLoc $2
, getLoc $3 ]) }
| '(' bitType ')' { $2 }
| tyident { LocBitTy (BitTySynonym `fmap` $1) }
//----------------------------------------
//-- Struct definitions
//structDef :: { StructDef }
structDef :
struct structName '{' fields '}' { StructDef (unLoc $2) (reverse $4) (getLoc $2) }
//-- Remove parsed quotes first
| abstract struct structName str { let TokString f = unLoc $4 in
AbstractDef (unLoc $3) (filter (/= '\"') f) (getLoc $3) }
| string struct structName integer { let TokInteger i = unLoc $4 in
StringDef (unLoc $3) i (getLoc $3) }
//structName :: { Located String }
structName :
tyident { $1 }
| ident { $1 }
//field :: { Field }
field :
//-- Haskell style
ident '::' typeHS { Field (unLoc $1) $3 (getLoc $1 <> getLoc $3) }
//-- C style
| type ident { Field (unLoc $2) $1 (getLoc $1 <> getLoc $2)}
//-- 1 or more fields, separated (but optionally ending with) ';'.
//fields :: { [Field] }
fields :
fields ';' field { $3 : $1 }
| fields ';' { $1 }
| field { [$1] }
//--------------------------------------------------------------------------------
//-- Bit data
//-- Bitdata definition
//bdDef :: { BitDataDef }
bdDef : bitdata tyident '::' bitType
'=' bdConstrs { BitDataDef (unLoc $2) $4 (reverse $6)
(mconcat [ getLoc $1, getLoc $2, getLoc $3, getLoc $6 ]) }
//-- One or more bitdata constructors, separated by '|'
//bdConstrs :: { [Constr] }
bdConstrs :
bdConstrs '|' bdConstr { $3 : $1 }
| bdConstr { [$1] }
//bdConstr :: { Constr }
bdConstr : ident bdRecord bdLayout { Constr (unLoc $1) $2 $3
(mconcat [ getLoc $1, getLoc $2 ]) }
//-- Zero or more fields.
//bdRecord :: { [BitField] }
bdRecord :
'{' bdFields '}' { reverse $2 }
| {- empty -} { [] }
//bdFields :: { [BitField] }
bdFields :
bdFields ',' bdField { $3 : $1 }
| bdField { [$1] }
//bdField :: { BitField }
bdField :
ident '::' bitType { BitField (Just (unLoc $1)) $3 (getLoc $1 <> getLoc $3) }
| '_' '::' bitType { BitField Nothing $3 ($1 <> getLoc $3) }
//bdLayout :: { [LayoutItem] }
bdLayout :
as bdItems { reverse $2 }
| {- empty -} { [] }
//-- One or more items, separated by #
//bdItems :: { [LayoutItem] }
bdItems :
bdItems '#' bdItem { $3 : $1 }
| bdItem { [$1] }
//bdItem :: { LayoutItem }
bdItem :
ident { LayoutField (unLoc $1) }
| integer { let TokInteger i = unLoc $1 in
LayoutConst (BitLitUnknown i) }
| bitLiteral { LayoutConst $1 }
//-- Parse n-bit natural, e.g.,
//--
//-- 8b0 -- 8 0-bits
//--
//-- 2b01 -- 01
//-- First field is width, second is "b[0,1]+"
//bitLiteral :: { BitLiteral }
bitLiteral : bitlit { let TokBitLit bl = unLoc $1 in
BitLitKnown (fst bl) (snd bl) }
//--------------------------------------------------------------------------------
//-- Namespaces
//ident :: { Located String }
ident :
identifier { let TokIdent i = unLoc $1 in
i `at` $1 }
| tyidentifier '.' identifier { let TokTyIdent t = unLoc $1 in
let TokIdent i = unLoc $3 in
atBin (t ++ '.':i) $1 $3 }
//tyident :: { Located String }
tyident :
tyidentifier { let TokTyIdent t = unLoc $1 in
t `at` $1 }
| tyidentifier '.' tyidentifier { let TokTyIdent t0 = unLoc $1 in
let TokTyIdent t1 = unLoc $3 in
atBin (t0 ++ '.':t1) $1 $3 }
//--------------------------------------------------------------------------------
%%
{
mkNegate :: Exp -> Exp
mkNegate e = go e
where
go (ExpLit l) = case l of
LitInteger i -> ExpLit (LitInteger (-i))
LitFloat f -> ExpLit (LitFloat (-f))
_ -> ExpOp NegateOp [e]
go (LocExp x) = go (locValue x)
go _ = ExpOp NegateOp [e]
}
Using this online tool https://www.bottlecaps.de/convert/ to convert the cleaned up
Parser.yin an EBNF understood by https://www.bottlecaps.de/rr/ui and adding the tokens manually we can have a nice railroad diagram (https://en.wikipedia.org/wiki/Syntax_diagram).Copy and paste the EBNF shown bellow at https://www.bottlecaps.de/rr/ui on the tab
Edit Grammarthen click on the tabView Diagram.Cleaned up
Parser.y: