forked from AU-COBRA/ConCert
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackInterpreter.v
More file actions
143 lines (121 loc) · 4.69 KB
/
StackInterpreter.v
File metadata and controls
143 lines (121 loc) · 4.69 KB
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
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 Stdlib Require Import List. Import ListNotations.
From Stdlib Require Import Notations.
From Stdlib Require Import String.
From Stdlib Require Import ZArith.
Import DeriveSer.
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 Ser.
Global Instance instruction_serializable : Serializable instruction := Derive Ser.
Global Instance value_serializable : Serializable value := Derive Ser.
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.