Skip to content

Commit 815f27d

Browse files
committed
more wip
1 parent 80e9f5e commit 815f27d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+352784
-2
lines changed

.github/workflows/rust.yml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,20 @@ jobs:
9292
cp ../../rust-toolchain ./
9393
cd crates
9494
# We compile each library twice to avoid errors. TODO: investigate why this is needed
95+
# context
96+
cd context
97+
cargo coq-of-rust
98+
touch src/lib.rs
99+
cargo coq-of-rust --with-json
100+
rsync -acv src/ ../../../../CoqOfRust/revm/translations/context/ --include='*/' --include='*.v' --include='*.json' --exclude='*'
101+
cd ..
102+
# context/interface
103+
cd context/interface
104+
cargo coq-of-rust
105+
touch src/lib.rs
106+
cargo coq-of-rust --with-json
107+
rsync -acv src/ ../../../../../CoqOfRust/revm/translations/context/interface/ --include='*/' --include='*.v' --include='*.json' --exclude='*'
108+
cd ../..
95109
# interpreter
96110
cd interpreter
97111
cargo coq-of-rust
@@ -124,8 +138,8 @@ jobs:
124138
cd specification
125139
cargo coq-of-rust
126140
touch src/lib.rs
127-
cargo coq-of-rust
128-
rsync -acv src/ ../../../../CoqOfRust/revm/translations/specification/ --include='*/' --include='*.v' --exclude='*'
141+
cargo coq-of-rust --with-json
142+
rsync -acv src/ ../../../../CoqOfRust/revm/translations/specification/ --include='*/' --include='*.v' --include='*.json' --exclude='*'
129143
cd ..
130144
cd ../../..
131145
endGroup

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@
2929

3030
# Generated files for the smart contracts
3131
contracts/generated
32+
33+
# Python
34+
__pycache__/

CoqOfRust/revm/of_json/common.v

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Require Import CoqOfRust.CoqOfRust.
2+
Require Import simulations.M.
3+
4+
Module ruint.
5+
Module Uint.
6+
Definition t (BITS LIMBS : Z) : Set :=
7+
Z.
8+
End Uint.
9+
End ruint.

CoqOfRust/revm/of_json/context.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import json
2+
import of_json as o
3+
4+
crate = "context"
5+
6+
def interface_host():
7+
input = json.load(open('../translations/context/interface/host.json'))
8+
output = o.get_header([])
9+
output += "\n"
10+
output += o.pp_top_level_item(*o.find_top_level_item_by_name(crate, input, "SStoreResult"))
11+
with open('context/interface/host.v', 'w') as f:
12+
f.write(output)
13+
14+
interface_host()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
(* Generated file. Do not edit. *)
2+
Require Import CoqOfRust.CoqOfRust.
3+
Require Import simulations.M.
4+
5+
Module SStoreResult.
6+
Record t : Set := {
7+
original_value: ruint.Uint.t 256 4;
8+
present_value: ruint.Uint.t 256 4;
9+
new_value: ruint.Uint.t 256 4;
10+
}.
11+
12+
Definition current_to_value (x: t) : Value.t :=
13+
match x with
14+
| Build_t original_value present_value new_value =>
15+
Value.StructRecord "context::host::SStoreResult" [
16+
("original_value", to_value original_value);
17+
("present_value", to_value present_value);
18+
("new_value", to_value new_value)
19+
]
20+
end.
21+
22+
Global Instance IsLink : Link t := {
23+
to_ty := Ty.path "context::host::SStoreResult";
24+
to_value := to_value
25+
}.
26+
End SStoreResult.

CoqOfRust/revm/of_json/of_json.py

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
"""
2+
Utility functions to generate Coq files from the JSON generated by `coq-of-rust`.
3+
"""
4+
5+
6+
from typing import Any, Tuple
7+
8+
9+
def find_top_level_item(prefix: list[str], top_level, condition) -> Tuple[list[str], Any] | None:
10+
for entry in top_level:
11+
item = entry["item"]
12+
if condition(item):
13+
return (prefix, item)
14+
if "Module" in item:
15+
module = item["Module"]
16+
result = find_top_level_item(prefix + [module["name"]], module["body"], condition)
17+
if result:
18+
return result
19+
20+
21+
def find_top_level_item_by_name(crate: str, top_level, name: str) -> Tuple[list[str], Any]:
22+
def item_has_name(item):
23+
if isinstance(item, dict):
24+
item = next(iter(item.values()))
25+
return "name" in item and item["name"] == name
26+
return False
27+
28+
result = find_top_level_item(
29+
[crate],
30+
top_level,
31+
item_has_name,
32+
)
33+
if result:
34+
return result
35+
raise Exception("Item not found: " + name)
36+
37+
38+
def get_header(imports: list[str]) -> str:
39+
return """(* Generated file. Do not edit. *)
40+
Require Import CoqOfRust.CoqOfRust.
41+
Require Import simulations.M.
42+
""" + "".join("Require " + import_ + ".\n" for import_ in imports)
43+
44+
45+
def indent(s: str) -> str:
46+
return "\n".join(
47+
# We do not indent empty lines
48+
" " + line if len(line) > 0 else ""
49+
for line in s.split("\n")
50+
)
51+
52+
53+
def paren(with_paren: bool, s: str) -> str:
54+
if with_paren:
55+
return "(" + s + ")"
56+
return s
57+
58+
59+
def pp_path(path) -> str:
60+
return ".".join(path)
61+
62+
63+
def pp_const(const) -> str:
64+
if "Literal" in const:
65+
const = const["Literal"]
66+
if "Integer" in const:
67+
integer = const["Integer"]
68+
return str(integer["value"])
69+
return "Unknown literal " + str(const)
70+
return "Unknown const " + str(const)
71+
72+
73+
74+
def pp_type(with_paren: bool, item) -> str:
75+
if "Var" in item:
76+
item = item["Var"]
77+
return item["name"]
78+
if "Path" in item:
79+
item = item["Path"]
80+
path = item["path"]
81+
if path == ["*const"]:
82+
return "Ref.t Pointer.Kind.ConstPointer"
83+
if path == ["bool"]:
84+
return "bool"
85+
return pp_path(path) + ".t"
86+
if "Application" in item:
87+
item = item["Application"]
88+
return paren(
89+
with_paren and len(item["consts"]) + len(item["tys"]) > 0,
90+
" ".join(
91+
[pp_type(True, item["func"])] +
92+
[pp_const(const) for const in item["consts"]] +
93+
[pp_type(True, ty) for ty in item["tys"]]
94+
)
95+
)
96+
if "Tuple" in item:
97+
item = item["Tuple"]
98+
return paren(
99+
with_paren,
100+
" * ".join(pp_type(True, ty) for ty in item["tys"])
101+
)
102+
return "Unknown type " + str(item)
103+
104+
105+
def pp_type_struct_struct(prefix: list[str], item) -> str:
106+
def get_ty_params(is_implicit: bool) -> str:
107+
if len(item["ty_params"]) != 0:
108+
return \
109+
("{" if is_implicit else "(") + \
110+
" ".join(item["ty_params"]) + \
111+
": Set" + \
112+
("}" if is_implicit else ")") + \
113+
" "
114+
else:
115+
return ""
116+
117+
def get_applied_ty() -> str:
118+
if len(item["ty_params"]) != 0:
119+
return "t" + "".join(" " + ty_param for ty_param in item["ty_params"])
120+
else:
121+
return "t"
122+
123+
ty_params_links = "".join("`{Link " + ty_param + "} " for ty_param in item["ty_params"])
124+
full_name = "::".join(prefix + [item["name"]])
125+
return pp_module(item["name"],
126+
"Record t " + get_ty_params(True) + ": Set := {\n" +
127+
indent("".join(
128+
field[0] + ": " + pp_type(False, field[1]) + ";\n"
129+
for field in item["fields"]
130+
)) +
131+
"}.\n" +
132+
("Arguments Build_t {" + " ".join(["_"] * len(item["ty_params"])) + "}.\n" +
133+
"Arguments t : clear implicits.\n"
134+
if len(item["ty_params"]) > 0
135+
else ""
136+
) +
137+
"\n" +
138+
f"Definition current_to_value {get_ty_params(True)}(x: {get_applied_ty()}) : Value.t :=\n" +
139+
indent(
140+
"match x with\n" +
141+
"| Build_t" + "".join(" " + field[0] for field in item["fields"]) + " =>\n" +
142+
indent(
143+
f"Value.StructRecord \"{full_name}\" [\n" +
144+
indent(";\n".join(
145+
"(\"" + field[0] + "\", to_value " + field[0] + ")"
146+
for field in item["fields"]
147+
)) + "\n" +
148+
"]\n"
149+
) +
150+
"end.\n"
151+
) +
152+
"\n" +
153+
"Global Instance IsLink " + get_ty_params(True) + ty_params_links + ": Link " +
154+
paren(len(item["ty_params"]) > 0, " ".join(["t"] + item["ty_params"])) +
155+
" := {\n" +
156+
indent(
157+
"to_ty := Ty.path \"" + full_name + "\";\n" +
158+
"to_value := to_value\n"
159+
) +
160+
"}."
161+
)
162+
163+
164+
def pp_type_struct_tuple(prefix: list[str], item) -> str:
165+
if len(item["ty_params"]) != 0:
166+
ty_params = "(" + " ".join(item["ty_params"]) + ": Set) "
167+
else:
168+
ty_params = ""
169+
ty_params_links = "".join("`{Link " + ty_param + "} " for ty_param in item["ty_params"])
170+
return pp_module(item["name"],
171+
"Inductive t " + ty_params + ": Set :=\n" +
172+
"| Make :" +
173+
"".join(
174+
" " + pp_type(False, field) + " ->"
175+
for field in item["fields"]
176+
) +
177+
" t" + "".join(" " + ty_param for ty_param in item["ty_params"]) + ".\n" +
178+
("Arguments Make {" + " ".join(["_"] * len(item["ty_params"])) + "}.\n"
179+
if len(item["ty_params"]) > 0
180+
else ""
181+
) +
182+
"\n" +
183+
"Global Instance IsLink " + ty_params + ty_params_links + ": Link " +
184+
paren(len(item["ty_params"]) > 0, " ".join(["t"] + item["ty_params"])) +
185+
" := {\n" +
186+
indent(
187+
"to_ty := Ty.path \"" + "::".join(prefix + [item["name"]]) + "\";\n" +
188+
"to_value '(Make" + "".join(" x" + str(index) for index in range(len(item["fields"]))) + ") :=\n" +
189+
indent(
190+
"Value.StructTuple \"" + "::".join(prefix + [item["name"]]) + "\" [" +
191+
"; ".join("to_value x" + str(index) for index in range(len(item["fields"]))) + "];\n"
192+
)
193+
) +
194+
"}."
195+
)
196+
197+
198+
def pp_type_enum(prefix: list[str], item) -> str:
199+
name = item["name"]
200+
variants = item["variants"]
201+
202+
if len(item["ty_params"]) != 0:
203+
ty_params = "(" + " ".join(item["ty_params"]) + ": Set) "
204+
ty_params_args = "".join(" " + ty_param for ty_param in item["ty_params"])
205+
else:
206+
ty_params = ""
207+
ty_params_args = ""
208+
209+
# Generate the inductive type definition
210+
inductive_def = f"Inductive t {ty_params}: Set :=\n"
211+
for variant in variants:
212+
variant_name = variant["name"]
213+
if "Tuple" in variant["item"] and len(variant["item"]["Tuple"]["tys"]) == 0:
214+
inductive_def += f"| {variant_name}\n"
215+
else:
216+
tys = variant["item"]["tys"]
217+
inductive_def += f"| {variant_name} : {' -> '.join(pp_type(False, ty) for ty in tys)} -> t{ty_params_args}\n"
218+
inductive_def += "."
219+
220+
# Generate the Arguments line if there are type parameters
221+
arguments_line = (f"Arguments {' '.join(variant['name'] for variant in variants)} " +
222+
"{" + " ".join(["_"] * len(item["ty_params"])) + "}.\n"
223+
) if len(item["ty_params"]) > 0 else ""
224+
225+
return pp_module(name,
226+
inductive_def +
227+
arguments_line
228+
)
229+
230+
231+
def pp_top_level_item(prefix: list[str], item) -> str:
232+
if "TypeStructStruct" in item:
233+
item = item["TypeStructStruct"]
234+
return pp_type_struct_struct(prefix, item)
235+
if "TypeStructTuple" in item:
236+
item = item["TypeStructTuple"]
237+
return pp_type_struct_tuple(prefix, item)
238+
if "TypeEnum" in item:
239+
item = item["TypeEnum"]
240+
return pp_type_enum(prefix, item)
241+
return "Unknown item type " + str(item)
242+
243+
244+
def pp_module(name: str, content: str) -> str:
245+
return \
246+
"Module " + name + ".\n" + \
247+
indent(content) + "\n" + \
248+
"End " + name + "."
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import json
2+
import of_json as o
3+
4+
crate = "specification"
5+
6+
def hardfork():
7+
input = json.load(open('../translations/specification/hardfork.json'))
8+
output = o.get_header([])
9+
output += "\n"
10+
output += o.pp_top_level_item(*o.find_top_level_item_by_name(crate, input, "SpecId"))
11+
with open('specification/hardfork.v', 'w') as f:
12+
f.write(output)
13+
14+
hardfork()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
(* Generated file. Do not edit. *)
2+
Require Import CoqOfRust.CoqOfRust.
3+
Require Import simulations.M.
4+
5+
Module SpecId.
6+
Inductive t : Set :=
7+
| FRONTIER
8+
| FRONTIER_THAWING
9+
| HOMESTEAD
10+
| DAO_FORK
11+
| TANGERINE
12+
| SPURIOUS_DRAGON
13+
| BYZANTIUM
14+
| CONSTANTINOPLE
15+
| PETERSBURG
16+
| ISTANBUL
17+
| MUIR_GLACIER
18+
| BERLIN
19+
| LONDON
20+
| ARROW_GLACIER
21+
| GRAY_GLACIER
22+
| MERGE
23+
| SHANGHAI
24+
| CANCUN
25+
| PRAGUE
26+
| OSAKA
27+
| LATEST
28+
.
29+
End SpecId.

0 commit comments

Comments
 (0)