-
Notifications
You must be signed in to change notification settings - Fork 9
/
kvyper.py
61 lines (45 loc) · 1.73 KB
/
kvyper.py
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
#!/usr/bin/env python3.6
import sys
import os
import subprocess
import re
from scripts.vyper_parser import main as parse # string -> string
from scripts.op2byte import encode as op2byte # string list -> bytes
path = os.path.dirname(os.path.realpath(__file__))
def krun(kdir, pgm): # string * string -> string
try:
p = subprocess.run(['krun', '-d', os.path.join(path, kdir), '-cPGM=' + pgm, '-pPGM=kast -e', '--debug'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')
except FileNotFoundError as e:
print("Error: subprocess.run() ended with FileNotFoundError for file: " + str(e.filename), file=sys.stderr)
raise e
if p.returncode == 0:
return p.stdout
else:
raise RuntimeError(p.stderr)
def viper2lll(ast): # string -> string
out = krun('vyper-lll', ast)
if "<k> . </k>" in out:
lll = re.search(r'<lll> (.*) </lll>', out).group(1)
return lll
else:
raise RuntimeError("vyper-lll computation got stuck:\n\n" + out + "\n\n")
def lll2evm(lll): # string -> string list
out = krun('lll-evm', lll)
if "<k> . </k>" in out:
evm = re.compile(r' \) ListItem \( ').sub(' ', re.search(r'<evm> ListItem \( (.*) \) </evm>', out).group(1))
return evm.split(' ')
else:
raise RuntimeError("lll-evm computation got stuck:\n\n" + out + "\n\n")
def compile(code): # string -> bytes
ast = parse(code)
lll = viper2lll(ast)
evm = lll2evm(lll) # list of opcodes
return op2byte(evm)
if __name__ == '__main__':
if len(sys.argv) < 2:
print("no input file")
sys.exit(1)
with open(sys.argv[1], "r") as fin:
code = fin.read()
print('0x' + compile(code).hex())