forked from AU-COBRA/ConCert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
StackInterpreter.v
142 lines (123 loc) · 4.82 KB
/
StackInterpreter.v
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
From ConCert.Execution Require Import Blockchain.
From ConCert.Execution Require Import Containers.
From ConCert.Execution Require Import Serializable.
From ConCert.Execution Require Import ResultMonad.
From Coq Require Import List. Import ListNotations.
From Coq Require Import Notations.
From Coq Require Import String.
From Coq Require Import ZArith.
Local Open Scope string_scope.
Section StackInterpreter.
Context {Base : ChainBase}.
Definition map_key_type := string * Z.
Inductive op : Set := Add | Sub | Mult | Lt | Le | Equal.
Inductive instruction :=
| IPushZ : Z -> instruction
| IPushB : bool -> instruction
| IObs : string * Z -> instruction
| IIf : instruction
| IElse : instruction
| IEndIf : instruction
| IOp : op -> instruction.
Inductive value : Set := BVal : bool -> value | ZVal : Z -> value.
Global Instance op_serializable : Serializable op :=
Derive Serializable op_rect <Add, Sub, Mult, Lt, Le, Equal>.
Global Instance instruction_serializable : Serializable instruction :=
Derive Serializable instruction_rect <IPushZ, IPushB, IObs, IIf, IElse, IEndIf, IOp>.
Global Instance value_serializable : Serializable value :=
Derive Serializable value_rect <BVal, ZVal>.
Definition ext_map := FMap (string * Z) value.
Definition lookup (k : string * Z) (m : ext_map) := FMap.find k m.
Definition storage := list value.
Definition Error : Type := nat.
Definition default_error : Error := 1%nat.
Definition init (chain : Chain)
(ctx : ContractCallContext)
(setup : unit)
: result storage Error :=
Ok [].
Definition msg := list instruction * ext_map.
Open Scope Z.
Definition continue_ (i : Z) := (i =? 0)%Z.
Definition bool_to_cond (b : bool) : Z :=
if b then 0 else 1.
Definition flip (i : Z) : Z :=
if (i =? 0) then 1 else if (i =? 1) then 0 else i.
Definition reset_decrement (i : Z) : Z :=
if (i <=? 1) then 0 else i-1.
Fixpoint interp (ext : ext_map)
(insts : list instruction)
(s : storage)
(cond : Z)
: result storage Error :=
match insts with
| [] => Ok s
| hd :: inst0 =>
match hd with
| IPushZ i => if continue_ cond then
interp ext inst0 (ZVal i :: s) cond
else interp ext inst0 s cond
| IPushB b => if continue_ cond then
interp ext inst0 (BVal b :: s) cond
else interp ext inst0 s cond
| IIf => if cond =? 0 then
match s with
| BVal b :: s0 => interp ext inst0 s0 (bool_to_cond b)
| _ => Err default_error
end else interp ext inst0 s (1 + cond)%Z
| IElse => interp ext inst0 s (flip cond)
| IEndIf => interp ext inst0 s (reset_decrement cond)
| IObs p =>
if continue_ cond then
match lookup p ext with
| Some v => interp ext inst0 (v :: s) cond
| None => Err default_error
end
else interp ext inst0 s cond
| IOp op =>
if continue_ cond then
match op with
| Add => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (ZVal (i+j) :: s0)%Z cond
| _ => Err default_error
end
| Sub => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (ZVal (i-j) :: s0)%Z cond
| _ => Err default_error
end
| Mult => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (ZVal (i*j) :: s0)%Z cond
| _ => Err default_error
end
| Le => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (BVal (i<=?j) :: s0)%Z cond
| _ => Err default_error
end
| Lt => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (BVal (i<?j) :: s0)%Z cond
| _ => Err default_error
end
| Equal => match s with
| ZVal i :: ZVal j :: s0 => interp ext inst0 (BVal (i =? j) :: s0)%Z cond
| _ => Err default_error
end
end
else interp ext inst0 s cond
end
end.
Definition receive (chain : Chain)
(ctx : ContractCallContext)
(s : storage)
(msg : option msg)
: result (storage * list ActionBody) Error :=
match msg with
| None => Err default_error
| Some (insts, ext) =>
match interp ext insts [] 0 with
| Ok v => Ok (v, [])
| Err e => Err e
end
end.
Definition contract : Contract unit msg storage Error :=
build_contract init receive.
End StackInterpreter.