-
Notifications
You must be signed in to change notification settings - Fork 0
/
instr_types.py
127 lines (94 loc) · 3.58 KB
/
instr_types.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
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
import ast
from typing import Optional
class Type:
def __init__(self, annotation: Optional[str] = None):
self.annotation = annotation
pass
def __eq__(self, o):
return type(self) == type(o)
class Unit(Type):
def __str__(self):
return "unit"
class Int(Type):
def __str__(self):
return "int"
class Mutez(Type):
def __str__(self):
return "mutez"
class String(Type):
def __str__(self):
return "string"
class Bool(Type):
def __str__(self):
return "bool"
class Address(Type):
def __str__(self):
return "address"
class Operation(Type):
def __str__(self):
return "operation"
class List(Type):
def __init__(self, element_type: Type, annotation: Optional[str] = None):
super().__init__(annotation)
self.element_type = element_type
class Dict(Type):
def __init__(self, key_type: Type, value_type: Type, annotation: Optional[str] = None):
super().__init__(annotation)
self.key_type = key_type
self.value_type = value_type
class Callable(Type):
def __init__(self, param_type: Type, return_type: Type, annotation: Optional[str] = None):
super().__init__(annotation)
self.param_type = param_type
self.return_type = return_type
class Contract(Type):
def __init__(self, param_type: Type, annotation: Optional[str] = None):
super().__init__(annotation)
self.param_type = param_type
class TypeParser:
def __init__(self):
pass
def parse_name(self, name: ast.Name, e, annotation: Optional[str] = None) -> Type:
if name.id == 'int':
return Int(annotation)
if name.id == 'str':
return String(annotation)
if name.id == 'address':
return Address(annotation)
if name.id == 'bool':
return Bool(annotation)
if name.id == 'unit':
return Unit(annotation)
if name.id == 'mutez':
return Mutez(annotation)
if name.id in e.records.keys():
return e.records[name.id].get_type()
raise NotImplementedError
def parse_dict(self, dictionary: ast.Subscript, e, annotation):
key_type = self.parse(dictionary.slice.value.elts[0], e)
value_type = self.parse(dictionary.slice.value.elts[1], e)
return Dict(key_type, value_type, annotation)
def parse_callable(self, dictionary: ast.Subscript, e, annotation):
key_type = self.parse(dictionary.slice.value.elts[0], e)
value_type = self.parse(dictionary.slice.value.elts[1], e)
return Callable(key_type, value_type, annotation)
def parse_contract(self, contract: ast.Subscript, e, annotation):
param_type = self.parse(contract.slice.value, e)
return Contract(param_type)
def parse_subscript(self, subscript: ast.Dict, e, annotation):
if subscript.value.id == "Dict":
return self.parse_dict(subscript, e, annotation)
if subscript.value.id == "Callable":
return self.parse_callable(subscript, e, annotation)
if subscript.value.id == "Contract":
return self.parse_contract(subscript, e, annotation)
else:
raise NotImplementedError
def parse(self, type_ast, e, annotation: Optional[str] = None) -> Type:
if type(type_ast) == ast.Name:
return self.parse_name(type_ast, e, annotation)
if type(type_ast) == ast.Subscript:
return self.parse_subscript(type_ast, e, annotation)
if type_ast == None:
return Unit()
raise NotImplementedError