Source file Operations.ml
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
open AST
open ASTUtils
open Error
let value_as_int pos = function
| L_Int i -> (
try Z.to_int i
with Z.Overflow ->
failwith "Cannot slice with an integer more than machine size.")
| v ->
fatal_from pos (Error.MismatchType (PP.literal_to_string v, [ integer' ]))
let is_positive z = Z.sign z != -1
let is_strict_positive z = Z.sign z = 1
let bv_same_length b1 b2 = Bitvector.(length b1 = length b2)
let exp_real q z =
if Q.sign q = 0 then (
assert (Z.sign z >= 0) ;
if Z.sign z = 0 then Q.one else Q.zero)
else
let q, z = if is_positive z then (q, z) else (Q.inv q, Z.neg z) in
let num = Q.num q and den = Q.den q in
let i = Z.to_int z in
let res_num = Z.pow num i and res_den = Z.pow den i in
Q.(res_num /// res_den)
let binop_values pos t op v1 v2 =
match (op, v1, v2) with
| PLUS, L_Int v1, L_Int v2 -> L_Int (Z.add v1 v2)
| MUL, L_Int v1, L_Int v2 -> L_Int (Z.mul v1 v2)
| MINUS, L_Int v1, L_Int v2 -> L_Int (Z.sub v1 v2)
| DIV, L_Int v1, L_Int v2 when is_strict_positive v2 && Z.divisible v1 v2 ->
L_Int (Z.divexact v1 v2)
| DIVRM, L_Int v1, L_Int v2 when is_strict_positive v2 ->
L_Int (Z.fdiv v1 v2)
| MOD, L_Int v1, L_Int v2 when is_strict_positive v2 ->
L_Int Z.(sub v1 (mul v2 (fdiv v1 v2)))
| POW, L_Int v1, L_Int v2 when is_positive v2 -> L_Int Z.(pow v1 (to_int v2))
| SHL, L_Int v1, L_Int v2 when is_positive v2 ->
L_Int Z.(shift_left v1 (to_int v2))
| SHR, L_Int v1, L_Int v2 when is_positive v2 ->
L_Int Z.(shift_right v1 (to_int v2))
| EQ_OP, L_Int v1, L_Int v2 -> L_Bool (Z.equal v1 v2)
| NEQ, L_Int v1, L_Int v2 -> L_Bool (not (Z.equal v1 v2))
| LEQ, L_Int v1, L_Int v2 -> L_Bool (Z.leq v1 v2)
| LT, L_Int v1, L_Int v2 -> L_Bool (Z.lt v1 v2)
| GEQ, L_Int v1, L_Int v2 -> L_Bool (Z.geq v1 v2)
| GT, L_Int v1, L_Int v2 -> L_Bool (Z.gt v1 v2)
| BAND, L_Bool b1, L_Bool b2 -> L_Bool (b1 && b2)
| BOR, L_Bool b1, L_Bool b2 -> L_Bool (b1 || b2)
| BEQ, L_Bool b1, L_Bool b2 -> L_Bool (b1 == b2)
| IMPL, L_Bool b1, L_Bool b2 -> L_Bool ((not b1) || b2)
| EQ_OP, L_Bool b1, L_Bool b2 -> L_Bool (b1 == b2)
| NEQ, L_Bool b1, L_Bool b2 -> L_Bool (b1 <> b2)
| PLUS, L_Real v1, L_Real v2 -> L_Real (Q.add v1 v2)
| MUL, L_Real v1, L_Real v2 -> L_Real (Q.mul v1 v2)
| MINUS, L_Real v1, L_Real v2 -> L_Real (Q.sub v1 v2)
| RDIV, L_Real v1, L_Real v2 -> L_Real (Q.div v1 v2)
| POW, L_Real q1, L_Int z2 when not (Q.sign q1 = 0 && Z.sign z2 < 0) ->
L_Real (exp_real q1 z2)
| EQ_OP, L_Real v1, L_Real v2 -> L_Bool (Q.equal v1 v2)
| NEQ, L_Real v1, L_Real v2 -> L_Bool (not (Q.equal v1 v2))
| LEQ, L_Real v1, L_Real v2 -> L_Bool (Q.leq v1 v2)
| LT, L_Real v1, L_Real v2 -> L_Bool (Q.lt v1 v2)
| GEQ, L_Real v1, L_Real v2 -> L_Bool (Q.geq v1 v2)
| GT, L_Real v1, L_Real v2 -> L_Bool (Q.gt v1 v2)
| EQ_OP, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_Bool (Bitvector.equal b1 b2)
| NEQ, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_Bool (not @@ Bitvector.equal b1 b2)
| OR, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_BitVector (Bitvector.logor b1 b2)
| AND, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_BitVector (Bitvector.logand b1 b2)
| EOR, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_BitVector (Bitvector.logxor b1 b2)
| PLUS, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_BitVector
Bitvector.(
of_z (length b1) (Z.add (to_z_unsigned b1) (to_z_unsigned b2)))
| MINUS, L_BitVector b1, L_BitVector b2 when bv_same_length b1 b2 ->
L_BitVector
Bitvector.(
of_z (length b1) (Z.sub (to_z_unsigned b1) (to_z_unsigned b2)))
| BV_CONCAT, L_BitVector b1, L_BitVector b2 ->
L_BitVector (Bitvector.concat [ b1; b2 ])
| PLUS, L_BitVector b1, L_Int z2 ->
L_BitVector Bitvector.(of_z (length b1) (Z.add (to_z_unsigned b1) z2))
| MINUS, L_BitVector b1, L_Int z2 ->
L_BitVector Bitvector.(of_z (length b1) (Z.sub (to_z_unsigned b1) z2))
| EQ_OP, L_String s1, L_String s2 -> L_Bool (String.equal s1 s2)
| NEQ, L_String s1, L_String s2 -> L_Bool (not (String.equal s1 s2))
| EQ_OP, L_Label s1, L_Label s2 -> L_Bool (String.equal s1 s2)
| NEQ, L_Label s1, L_Label s2 -> L_Bool (not (String.equal s1 s2))
| _ -> fatal_from pos (Error.UnsupportedBinop (t, op, v1, v2))
let unop_values pos t op v =
match (op, v) with
| NEG, L_Int i -> L_Int (Z.neg i)
| NEG, L_Real r -> L_Real (Q.neg r)
| BNOT, L_Bool b -> L_Bool (not b)
| NOT, L_BitVector bv -> L_BitVector (Bitvector.lognot bv)
| _ -> fatal_from pos (Error.UnsupportedUnop (t, op, v))