owl-basic 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- owl_basic/__init__.py +3 -0
- owl_basic/algorithms.py +29 -0
- owl_basic/ast_utils.py +204 -0
- owl_basic/basic_visitor.py +55 -0
- owl_basic/cfg_vertex.py +65 -0
- owl_basic/codegen/__init__.py +0 -0
- owl_basic/codegen/clr/__init__.py +0 -0
- owl_basic/codegen/clr/cil_visitor.py +1296 -0
- owl_basic/codegen/clr/cts.py +56 -0
- owl_basic/codegen/clr/emitters.py +94 -0
- owl_basic/codegen/clr/generate.py +539 -0
- owl_basic/correlation_visitor.py +119 -0
- owl_basic/data_visitor.py +62 -0
- owl_basic/decoder.py +339 -0
- owl_basic/errors.py +22 -0
- owl_basic/flow/__init__.py +17 -0
- owl_basic/flow/basic_block.py +34 -0
- owl_basic/flow/basic_block_identifier.py +66 -0
- owl_basic/flow/basic_block_orderer.py +29 -0
- owl_basic/flow/connectors.py +19 -0
- owl_basic/flow/convert_sub_visitor.py +28 -0
- owl_basic/flow/entry_point_locator.py +55 -0
- owl_basic/flow/entry_point_visitor.py +48 -0
- owl_basic/flow/flow_analysis.py +56 -0
- owl_basic/flow/flow_graph_creator.py +14 -0
- owl_basic/flow/flowgraph_visitor.py +178 -0
- owl_basic/flow/longjump_converter.py +20 -0
- owl_basic/flow/longjump_visitor.py +53 -0
- owl_basic/flow/subroutine_converter.py +38 -0
- owl_basic/flow/traversal.py +110 -0
- owl_basic/gml_visitor.py +151 -0
- owl_basic/line_mapper.py +43 -0
- owl_basic/line_number_visitor.py +65 -0
- owl_basic/main.py +381 -0
- owl_basic/node.py +21 -0
- owl_basic/options.py +22 -0
- owl_basic/owltyping/__init__.py +1 -0
- owl_basic/owltyping/function_type_inferer.py +50 -0
- owl_basic/owltyping/hindley_milner.py +524 -0
- owl_basic/owltyping/set_function_type_visitor.py +25 -0
- owl_basic/owltyping/type_system.py +220 -0
- owl_basic/owltyping/typecheck.py +60 -0
- owl_basic/owltyping/typecheck_visitor.py +471 -0
- owl_basic/parent_visitor.py +37 -0
- owl_basic/process.py +36 -0
- owl_basic/separation_visitor.py +98 -0
- owl_basic/sigil.py +30 -0
- owl_basic/simplify_visitor.py +204 -0
- owl_basic/singleton.py +127 -0
- owl_basic/source_debugging.py +124 -0
- owl_basic/symbol_table_visitor.py +220 -0
- owl_basic/symbol_tables.py +195 -0
- owl_basic/syntax/__init__.py +0 -0
- owl_basic/syntax/ast.py +1081 -0
- owl_basic/syntax/ast_meta.py +228 -0
- owl_basic/syntax/grammar.py +1972 -0
- owl_basic/syntax/lexer.py +943 -0
- owl_basic/syntax/parser.py +77 -0
- owl_basic/utility.py +26 -0
- owl_basic/visitor.py +43 -0
- owl_basic/xml_blocks.py +137 -0
- owl_basic/xml_visitor.py +101 -0
- owl_basic-0.6.0.dist-info/METADATA +37 -0
- owl_basic-0.6.0.dist-info/RECORD +69 -0
- owl_basic-0.6.0.dist-info/WHEEL +5 -0
- owl_basic-0.6.0.dist-info/entry_points.txt +2 -0
- owl_basic-0.6.0.dist-info/licenses/LICENSE +21 -0
- owl_basic-0.6.0.dist-info/licenses/THIRD-PARTY-NOTICES.md +57 -0
- owl_basic-0.6.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from owl_basic.utility import underscoresToCamelCase, hasprop
|
|
5
|
+
from owl_basic.node import Node
|
|
6
|
+
from owl_basic.options import Option, TypeOption, IntegerOption
|
|
7
|
+
from owl_basic.visitor import Visitable
|
|
8
|
+
|
|
9
|
+
class AstMeta(type):
|
|
10
|
+
def __new__(cls, name, bases, dict):
|
|
11
|
+
# Allocate child infos
|
|
12
|
+
dict["child_infos"] = {}
|
|
13
|
+
for base in bases:
|
|
14
|
+
if "child_infos" in base.__dict__:
|
|
15
|
+
dict["child_infos"].update(base.__dict__["child_infos"])
|
|
16
|
+
|
|
17
|
+
# Allocate option infos
|
|
18
|
+
dict["option_infos"] = {}
|
|
19
|
+
for base in bases:
|
|
20
|
+
if "option_infos" in base.__dict__:
|
|
21
|
+
dict["option_infos"].update(base.__dict__["option_infos"])
|
|
22
|
+
|
|
23
|
+
if '__doc__' in dict:
|
|
24
|
+
dict["_description"] = dict['__doc__']
|
|
25
|
+
else:
|
|
26
|
+
dict["_description"] = name
|
|
27
|
+
|
|
28
|
+
return type.__new__(cls, name, bases, dict)
|
|
29
|
+
|
|
30
|
+
def __init__(cls, name, bases, dict):
|
|
31
|
+
"""
|
|
32
|
+
Configure the class that is being created by introspecting its
|
|
33
|
+
'declaration' and creating getters, setters and properties for its
|
|
34
|
+
data members.
|
|
35
|
+
"""
|
|
36
|
+
cls._createChildProperties(name, bases, dict)
|
|
37
|
+
cls._createChildListProperties(name, bases, dict)
|
|
38
|
+
cls._createOptionProperties(name, bases, dict)
|
|
39
|
+
super(AstMeta, cls).__init__(name, bases, dict)
|
|
40
|
+
|
|
41
|
+
# TODO: These methods have a lot of common code.
|
|
42
|
+
|
|
43
|
+
def _createChildProperties(cls, name, bases, dict):
|
|
44
|
+
"""
|
|
45
|
+
Introspect the class being created to look for class members which
|
|
46
|
+
contain 'declarative' Node objects. Move these declarations into the
|
|
47
|
+
child_infos class member, and create getters, setters and properties
|
|
48
|
+
to provide access to each of the child members.
|
|
49
|
+
"""
|
|
50
|
+
node_infos = {}
|
|
51
|
+
for info_name, v in dict.items():
|
|
52
|
+
if isinstance(v, Node):
|
|
53
|
+
node_infos[info_name] = v
|
|
54
|
+
|
|
55
|
+
removal = []
|
|
56
|
+
for info_name in node_infos.keys():
|
|
57
|
+
property_name = underscoresToCamelCase(info_name)
|
|
58
|
+
if info_name != property_name:
|
|
59
|
+
removal.append(info_name)
|
|
60
|
+
def _getProperty(self, info_name=info_name):
|
|
61
|
+
return self._children[info_name]
|
|
62
|
+
def _setProperty(self, value, info_name=info_name):
|
|
63
|
+
self._children[info_name] = value
|
|
64
|
+
if not hasprop(cls, property_name):
|
|
65
|
+
setattr(cls, property_name, property(_getProperty, _setProperty))
|
|
66
|
+
|
|
67
|
+
for info_name in removal:
|
|
68
|
+
delattr(cls, info_name)
|
|
69
|
+
|
|
70
|
+
cls.child_infos.update(node_infos)
|
|
71
|
+
|
|
72
|
+
def _createChildListProperties(cls, name, bases, dict):
|
|
73
|
+
"""
|
|
74
|
+
Introspect the class being created to look for class members which
|
|
75
|
+
contain 'declarative' [Node] objects. Move these declarations into the
|
|
76
|
+
child_infos class member, and create getters, setters and properties
|
|
77
|
+
to provide access to each of the child members.
|
|
78
|
+
"""
|
|
79
|
+
list_infos = {}
|
|
80
|
+
for info_name, v in dict.items():
|
|
81
|
+
if isinstance(v, list) and isinstance(v[0], Node):
|
|
82
|
+
list_infos[info_name] = v
|
|
83
|
+
|
|
84
|
+
removal = []
|
|
85
|
+
for info_name in list_infos.keys():
|
|
86
|
+
property_name = underscoresToCamelCase(info_name)
|
|
87
|
+
if info_name != property_name:
|
|
88
|
+
removal.append(info_name)
|
|
89
|
+
def _getProperty(self, info_name=info_name):
|
|
90
|
+
return self._children[info_name]
|
|
91
|
+
def _setProperty(self, value, info_name=info_name):
|
|
92
|
+
self._children[info_name] = value
|
|
93
|
+
if not hasprop(cls, property_name):
|
|
94
|
+
setattr(cls, property_name, property(_getProperty, _setProperty))
|
|
95
|
+
|
|
96
|
+
for info_name in removal:
|
|
97
|
+
delattr(cls, info_name)
|
|
98
|
+
|
|
99
|
+
cls.child_infos.update(list_infos)
|
|
100
|
+
|
|
101
|
+
def _createOptionProperties(cls, name, bases, dict):
|
|
102
|
+
"""
|
|
103
|
+
Introspect the class being created to look for class members which
|
|
104
|
+
contain 'declarative' Option objects. Move these declarations into the
|
|
105
|
+
option_infos class member, and create getters, setters and properties
|
|
106
|
+
to provide access to each of the child members.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
infos = {}
|
|
110
|
+
for info_name, v in dict.items():
|
|
111
|
+
if isinstance(v, Option):
|
|
112
|
+
infos[info_name] = v
|
|
113
|
+
|
|
114
|
+
removal = []
|
|
115
|
+
for info_name in infos.keys():
|
|
116
|
+
property_name = underscoresToCamelCase(info_name)
|
|
117
|
+
if info_name != property_name:
|
|
118
|
+
removal.append(info_name)
|
|
119
|
+
def _getProperty(self, info_name=info_name):
|
|
120
|
+
return self._options[info_name]
|
|
121
|
+
def _setProperty(self, value, info_name=info_name):
|
|
122
|
+
self._options[info_name] = value
|
|
123
|
+
if not hasprop(cls, property_name):
|
|
124
|
+
setattr(cls, property_name, property(_getProperty, _setProperty))
|
|
125
|
+
|
|
126
|
+
for info_name in removal:
|
|
127
|
+
delattr(cls, info_name)
|
|
128
|
+
|
|
129
|
+
cls.option_infos.update(infos)
|
|
130
|
+
|
|
131
|
+
def __call__(cls, *args, **kwargs):
|
|
132
|
+
"""
|
|
133
|
+
Called when instances of classes with this metaclass. i.e. AstNodes.
|
|
134
|
+
Consume keyword arguments with the same name as child properties and options then
|
|
135
|
+
set the appropriate attributes.
|
|
136
|
+
"""
|
|
137
|
+
# First create the object
|
|
138
|
+
obj = type.__call__(cls, *args)
|
|
139
|
+
|
|
140
|
+
for kwarg in kwargs:
|
|
141
|
+
if hasprop(cls, kwarg):
|
|
142
|
+
setattr(obj, kwarg, kwargs[kwarg])
|
|
143
|
+
else:
|
|
144
|
+
raise AttributeError("No such property initialiser as '%s' on '%s'" % (kwarg, cls.__name__))
|
|
145
|
+
|
|
146
|
+
# TODO: Should remove consumed kwargs here
|
|
147
|
+
|
|
148
|
+
return obj
|
|
149
|
+
|
|
150
|
+
class AstNode(Visitable, metaclass=AstMeta):
|
|
151
|
+
formal_type = TypeOption()
|
|
152
|
+
actual_type = TypeOption()
|
|
153
|
+
line_num = IntegerOption()
|
|
154
|
+
|
|
155
|
+
def __init__(self):
|
|
156
|
+
self.parent = None
|
|
157
|
+
|
|
158
|
+
self.__symbol_table = None
|
|
159
|
+
|
|
160
|
+
# Initialise children
|
|
161
|
+
self._children = {}
|
|
162
|
+
for info_name, info in self.child_infos.items():
|
|
163
|
+
if isinstance(info, Node):
|
|
164
|
+
self._children[info_name] = None
|
|
165
|
+
elif isinstance(info, list):
|
|
166
|
+
self._children[info_name] = []
|
|
167
|
+
|
|
168
|
+
self._options = {}
|
|
169
|
+
for info_name, option in self.option_infos.items():
|
|
170
|
+
self._options[info_name] = option.value
|
|
171
|
+
super(AstNode, self).__init__()
|
|
172
|
+
|
|
173
|
+
# Children accessor
|
|
174
|
+
|
|
175
|
+
def _getChildren(self):
|
|
176
|
+
return self._children
|
|
177
|
+
|
|
178
|
+
children = property(_getChildren)
|
|
179
|
+
|
|
180
|
+
# Options accessor
|
|
181
|
+
|
|
182
|
+
def _getOptions(self):
|
|
183
|
+
return self._options
|
|
184
|
+
|
|
185
|
+
options = property(_getOptions)
|
|
186
|
+
|
|
187
|
+
def forEachChild(self, f):
|
|
188
|
+
for child in self.children.values():
|
|
189
|
+
if isinstance(child, list):
|
|
190
|
+
for subchild in child:
|
|
191
|
+
f(subchild)
|
|
192
|
+
else:
|
|
193
|
+
f(child)
|
|
194
|
+
|
|
195
|
+
def findChild(self, search_child):
|
|
196
|
+
"""Locate a child node within this AstNode. Returns a tuple containing
|
|
197
|
+
(property_name, index) where index may be None for non-indexable properties. Returns None
|
|
198
|
+
if the child is not found"""
|
|
199
|
+
for name, child in self.children.items():
|
|
200
|
+
if isinstance(child, list):
|
|
201
|
+
for index, subchild in enumerate(child):
|
|
202
|
+
if subchild is search_child:
|
|
203
|
+
return (underscoresToCamelCase(name), index)
|
|
204
|
+
else:
|
|
205
|
+
if child is search_child:
|
|
206
|
+
return (underscoresToCamelCase(name), None)
|
|
207
|
+
return (None, None)
|
|
208
|
+
|
|
209
|
+
def _getDescription(self):
|
|
210
|
+
return self._description or self.__class__.__name__
|
|
211
|
+
|
|
212
|
+
description = property(_getDescription)
|
|
213
|
+
|
|
214
|
+
def setProperty(self, value, property_name, index=None):
|
|
215
|
+
if index is not None:
|
|
216
|
+
getattr(self, property_name)[index] = value
|
|
217
|
+
else:
|
|
218
|
+
setattr(self, property_name, value)
|
|
219
|
+
|
|
220
|
+
def _getSymbolTable(self):
|
|
221
|
+
return self.__symbol_table
|
|
222
|
+
|
|
223
|
+
def _setSymbolTable(self, table):
|
|
224
|
+
self.__symbol_table = table
|
|
225
|
+
|
|
226
|
+
symbolTable = property(_getSymbolTable, _setSymbolTable)
|
|
227
|
+
|
|
228
|
+
|