1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
|
%%% Sail Intermediate Language %%%
% An attempt to precisely document the subset of sail that the
% rewriter is capable of re-writing sail into. It is intended to be a
% strict subset of the Sail AST, and be typecheckable with the full
% typechecker.
%
% Notably, it lacks:
% - Special (bit)vector syntax.
% - Complex l-values.
% - Existential types.
% - Polymorphism, of any kind.
indexvar n , m , i , j ::=
{{ phantom }}
{{ com Index variables for meta-lists }}
metavar num,numZero,numOne ::=
{{ phantom }}
{{ lex numeric }}
{{ ocaml int }}
{{ hol num }}
{{ lem integer }}
{{ com Numeric literals }}
metavar nat ::=
{{ phantom }}
{{ ocaml int }}
{{ lex numeric }}
{{ lem nat }}
metavar string ::=
{{ phantom }}
{{ ocaml string }}
{{ lem string }}
{{ hol string }}
{{ com String literals }}
metavar real ::=
{{ phantom }}
{{ ocaml string }}
{{ lem string }}
{{ hol string }}
{{ com Real number literal }}
embed
{{ ocaml
type text = string
type l = Parse_ast.l
type 'a annot = l * 'a
type loop = While | Until
}}
embed
{{ lem
open import Pervasives
open import Pervasives_extra
open import Map
open import Maybe
open import Set_extra
type l =
| Unknown
| Int of string * maybe l (*internal types, functions*)
| Range of string * nat * nat * nat * nat
| Generated of l (*location for a generated node, where l is the location of the closest original source*)
type annot 'a = l * 'a
val duplicates : forall 'a. list 'a -> list 'a
val set_from_list : forall 'a. list 'a -> set 'a
val subst : forall 'a. list 'a -> list 'a -> bool
type loop = While | Until
}}
metavar x , y , z ::=
{{ ocaml text }}
{{ lem string }}
{{ hol string }}
{{ com identifier }}
{{ ocamlvar "[[x]]" }}
{{ lemvar "[[x]]" }}
grammar
l :: '' ::= {{ phantom }}
{{ ocaml Parse_ast.l }}
{{ lem l }}
{{ hol unit }}
{{ com source location }}
| :: :: Unknown
{{ ocaml Unknown }}
{{ lem Unknown }}
{{ hol () }}
id :: '' ::=
{{ com Identifier }}
{{ aux _ l }}
| x :: :: id
| ( deinfix x ) :: D :: deIid {{ com remove infix status }}
base_effect :: 'BE_' ::=
{{ com effect }}
{{ aux _ l }}
| rreg :: :: rreg {{ com read register }}
| wreg :: :: wreg {{ com write register }}
| rmem :: :: rmem {{ com read memory }}
| rmemt :: :: rmemt {{ com read memory and tag }}
| wmem :: :: wmem {{ com write memory }}
| wmea :: :: eamem {{ com signal effective address for writing memory }}
| exmem :: :: exmem {{ com determine if a store-exclusive (ARM) is going to succeed }}
| wmv :: :: wmv {{ com write memory, sending only value }}
| wmvt :: :: wmvt {{ com write memory, sending only value and tag }}
| barr :: :: barr {{ com memory barrier }}
| depend :: :: depend {{ com dynamic footprint }}
| undef :: :: undef {{ com undefined-instruction exception }}
| unspec :: :: unspec {{ com unspecified values }}
| nondet :: :: nondet {{ com nondeterminism, from $[[nondet]]$ }}
| escape :: :: escape {{ com potential call of $[[exit]]$ }}
| lset :: :: lset {{ com local mutation; not user-writable }}
| lret :: :: lret {{ com local return; not user-writable }}
effect :: 'Effect_' ::=
{{ com effect set, of kind $[[Effect]]$ }}
{{ aux _ l }}
| { base_effect1 , .. , base_effectn } :: :: set {{ com effect set }}
| pure :: M :: pure {{ com sugar for empty effect set }}
{{ lem (Effect_set []) }} {{icho [[{}]] }}
| effect1 u+ .. u+ effectn :: M :: union {{ com union of sets of effects }} {{ icho [] }}
{{ lem (List.foldr effect_union (Effect_aux (Effect_set []) Unknown) [[effect1..effectn]]) }}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Types %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
typ :: 'Typ_' ::=
{{ com type expressions, of kind $[[Type]]$ }}
{{ aux _ l }}
| id :: :: id
{{ com defined type }}
| typ1 -> typ2 effectkw effect :: :: fn
{{ com Function (first-order only in user code) }}
| ( typ1 , .... , typn ) :: :: tup
{{ com Tuple }}
| id < typ_arg1 , .. , typ_argn > :: :: app
{{ com type constructor application }}
typ_arg :: 'Typ_arg_' ::=
{{ com type constructor arguments of all kinds }}
{{ aux _ l }}
| typ :: :: typ
typquant :: 'TypQ_' ::=
{{ com type quantifiers and constraints}}
{{ aux _ l }}
| :: :: no_forall {{ com empty }}
typschm :: 'TypSchm_' ::=
{{ com type scheme }}
{{ aux _ l }}
| typquant typ :: :: ts
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Type definitions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
type_def {{ ocaml 'a type_def }} {{ lem type_def 'a }} :: 'TD_' ::=
{{ ocaml TD_aux of type_def_aux * 'a annot }}
{{ lem TD_aux of type_def_aux * annot 'a }}
| type_def_aux :: :: aux
type_def_aux :: 'TD_' ::=
{{ com type definition body }}
| typedef id = typschm :: :: abbrev
{{ com type abbreviation }} {{ texlong }}
| typedef id = const struct typquant { typ1 id1 ; ... ; typn idn } :: :: record
{{ com struct type definition }} {{ texlong }}
| typedef id = const union typquant { type_union1 ; ... ; type_unionn } :: :: variant
{{ com tagged union type definition}} {{ texlong }}
| typedef id = enumerate { id1 ; ... ; idn } :: :: enum
{{ com enumeration type definition}} {{ texlong }}
% This one is a bit unusual - I think all nexps here must be constant, so replace with num.
| typedef id = register bits [ num : num' ] { index_range1 : id1 ; ... ; index_rangen : idn }
:: :: register {{ com register mutable bitfield type definition }} {{ texlong }}
type_union :: 'Tu_' ::=
{{ com type union constructors }}
{{ aux _ l }}
| id :: :: id
| typ id :: :: ty_id
index_range :: 'BF_' ::= {{ com index specification, for bitfields in register types}}
{{ aux _ l }}
| num :: :: 'single' {{ com single index }}
| num1 '..' num2 :: :: range {{ com index range }}
| index_range1 , index_range2 :: :: concat {{ com concatenation of index ranges }}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Literals %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
lit :: 'L_' ::=
{{ com literal constant }}
{{ aux _ l }}
| ( ) :: :: unit {{ com $() : [[unit]]$ }}
| bitzero :: :: zero {{ com $[[bitzero]] : [[bit]]$ }}
| bitone :: :: one {{ com $[[bitone]] : [[bit]]$ }}
| true :: :: true {{ com $[[true]] : [[bool]]$ }}
| false :: :: false {{ com $[[false]] : [[bool]]$ }}
| num :: :: num {{ com natural number constant }}
% Need to represent as a function call, e.g. sil#hex_string "0xFFFF".
% | hex :: :: hex {{ com bit vector constant, C-style }}
% | bin :: :: bin {{ com bit vector constant, C-style }}
| string :: :: string {{ com string constant }}
| undefined :: :: undef {{ com undefined-value constant }}
| real :: :: real {{ com real number }}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Patterns %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pat :: 'P_' ::=
{{ com pattern }}
{{ aux _ annot }} {{ auxparam 'a }}
| _ :: :: wild
{{ com wildcard }}
| ( pat as id ) :: :: as
{{ com named pattern }}
| ( typ ) pat :: :: typ
{{ com typed pattern }}
| id :: :: id
{{ com identifier }}
| id ( pat1 , .. , patn ) :: :: app
{{ com union constructor pattern }}
| { fpat1 ; ... ; fpatn } :: :: record
{{ com struct pattern }}
| ( pat1 , .... , patn ) :: :: tup
{{ com tuple pattern }}
| [|| pat1 , .. , patn ||] :: :: list
{{ com list pattern }}
| ( pat ) :: S :: paren
{{ ichlo [[pat]] }}
| pat1 '::' pat2 :: :: cons
{{ com Cons patterns }}
fpat :: 'FP_' ::=
{{ com field pattern }}
{{ aux _ annot }} {{ auxparam 'a }}
| id = pat :: :: Fpat
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Expressions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
loop :: loop ::= {{ phantom }}
| while :: :: while
| until :: :: until
exp :: 'E_' ::=
{{ com expression }}
{{ aux _ annot }} {{ auxparam 'a }}
| { exp1 ; ... ; expn } :: :: block {{ com sequential block }}
| nondet { exp1 ; ... ; expn } :: :: nondet {{ com nondeterministic block }}
| id :: :: id
{{ com identifier }}
| lit :: :: lit
{{ com literal constant }}
% Purely an annotation as all casting is resolved by type checker, can
% be evaluated by simply dropping the type.
| ( typ ) exp :: :: cast
{{ com cast }}
| id ( exp1 , .. , expn ) :: :: app
{{ com function application }}
| ( exp1 , .... , expn ) :: :: tuple
{{ com tuple }}
| if exp1 then exp2 else exp3 :: :: if
{{ com conditional }}
| loop exp1 exp2 :: :: loop
{{ com while or until loop }}
| foreach ( id from exp1 to exp2 by exp3 in order ) exp4 :: :: for
{{ com for loop }}
| [|| exp1 , .. , expn ||] :: :: list
{{ com list }}
| exp1 '::' exp2 :: :: cons
{{ com cons }}
| { fexps } :: :: record
{{ com struct }}
| { exp with fexps } :: :: record_update
{{ com functional update of struct }}
| exp . id :: :: field
{{ com field projection from struct }}
| switch exp { case pexp1 ... case pexpn } :: :: case
{{ com pattern matching }}
| letbind in exp :: :: let
{{ com let expression }}
| lexp := exp :: :: assign
{{ com imperative assignment }}
| return exp :: :: return
{{ com return $[[exp]]$ from current function }}
| exit exp :: :: exit
{{ com halt all current execution }}
| value :: I :: value
{{ com For internal use in interpreter to wrap pre-evaluated values when returning an action }}
lexp :: 'LEXP_' ::= {{ com lvalue expression }}
{{ aux _ annot }} {{ auxparam 'a }}
| id :: :: id
{{ com identifier }}
| ( typ ) id :: :: cast
{{ com cast }}
| ( lexp0 , .. , lexpn ) :: :: tup {{ com multiple (non-memory) assignment }}
% SIL: Not sure how much to rewrite L-expressions.
% | lexp [ exp ] :: :: vector {{ com vector element }}
% | lexp [ exp1 '..' exp2 ] :: :: vector_range {{ com subvector }}
% | lexp . id :: :: field {{ com struct field }}
fexp :: 'FE_' ::=
{{ com field expression }}
{{ aux _ annot }} {{ auxparam 'a }}
| id = exp :: :: Fexp
fexps :: 'FES_' ::=
{{ com field expression list }}
{{ aux _ annot }} {{ auxparam 'a }}
| fexp1 ; ... ; fexpn :: :: Fexps
pexp :: 'Pat_' ::=
{{ com pattern match }}
{{ aux _ annot }} {{ auxparam 'a }}
| pat -> exp :: :: exp
| pat when exp1 -> exp :: :: when
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function definitions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tannot_opt :: 'Typ_annot_opt_' ::=
{{ com optional type annotation for functions}}
{{ aux _ l }}
| :: :: none
| typquant typ :: :: some
rec_opt :: 'Rec_' ::=
{{ com optional recursive annotation for functions }}
{{ aux _ l }}
| :: :: nonrec {{ com non-recursive }}
| rec :: :: rec {{ com recursive }}
effect_opt :: 'Effect_opt_' ::=
{{ com optional effect annotation for functions }}
{{ aux _ l }}
| :: :: pure {{ com sugar for empty effect set }}
| effectkw effect :: :: effect
funcl :: 'FCL_' ::=
{{ com function clause }}
{{ aux _ annot }} {{ auxparam 'a }}
| id pat = exp :: :: Funcl
fundef :: 'FD_' ::=
{{ com function definition}}
{{ aux _ annot }} {{ auxparam 'a }}
| function rec_opt tannot_opt effect_opt funcl1 and ... and funcln :: :: function {{ texlong }}
letbind :: 'LB_' ::=
{{ com let binding }}
{{ aux _ annot }} {{ auxparam 'a }}
| let pat = exp :: :: val
{{ com let, implicit type ($[[pat]]$ must be total)}}
val_spec {{ ocaml 'a val_spec }} {{ lem val_spec 'a }} :: 'VS_' ::=
{{ ocaml VS_aux of val_spec_aux * 'a annot }}
{{ lem VS_aux of val_spec_aux * annot 'a }}
| val_spec_aux :: :: aux
val_spec_aux :: 'VS_' ::=
{{ com value type specification }}
{{ ocaml VS_val_spec of typschm * id * (string -> string option) * bool }}
{{ lem VS_val_spec of typschm * id * maybe string * bool }}
| val typschm id :: S :: val_spec
{{ com specify the type of an upcoming definition }}
{{ ocaml (VS_val_spec [[typschm]] [[id]] None false) }} {{ lem }}
default_spec :: 'DT_' ::=
{{ com default kinding or typing assumption }}
{{ aux _ l }}
| default Order order :: :: order
reg_id :: 'RI_' ::=
{{ aux _ annot }} {{ auxparam 'a }}
| id :: :: id
alias_spec :: 'AL_' ::=
{{ com register alias expression forms }}
{{ aux _ annot }} {{ auxparam 'a }}
| reg_id . id :: :: subreg
| reg_id [ exp ] :: :: bit
| reg_id [ exp '..' exp' ] :: :: slice
| reg_id : reg_id' :: :: concat
dec_spec :: 'DEC_' ::=
{{ com register declarations }}
{{ aux _ annot }} {{ auxparam 'a }}
| register typ id :: :: reg
| register alias id = alias_spec :: :: alias
| register alias typ id = alias_spec :: :: typ_alias
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Top-level definitions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
prec :: '' ::=
| infix :: :: Infix
| infixl :: :: InfixL
| infixr :: :: InfixR
def :: 'DEF_' ::=
{{ com top-level definition }}
{{ auxparam 'a }}
| type_def :: :: type
{{ com type definition }}
| fundef :: :: fundef
{{ com function definition }}
| letbind :: :: val
{{ com value definition }}
| val_spec :: :: spec
{{ com top-level type constraint }}
| fix prec num id :: :: fixity
{{ com fixity declaration }}
| overload id [ id1 ; ... ; idn ] :: :: overload
{{ com operator overload specification }}
| default_spec :: :: default
{{ com default kind and type assumptions }}
| dec_spec :: :: reg_dec
{{ com register declaration }}
defs :: '' ::=
{{ com definition sequence }}
{{ auxparam 'a }}
| def1 .. defn :: :: Defs
|