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.
Files changed (69) hide show
  1. owl_basic/__init__.py +3 -0
  2. owl_basic/algorithms.py +29 -0
  3. owl_basic/ast_utils.py +204 -0
  4. owl_basic/basic_visitor.py +55 -0
  5. owl_basic/cfg_vertex.py +65 -0
  6. owl_basic/codegen/__init__.py +0 -0
  7. owl_basic/codegen/clr/__init__.py +0 -0
  8. owl_basic/codegen/clr/cil_visitor.py +1296 -0
  9. owl_basic/codegen/clr/cts.py +56 -0
  10. owl_basic/codegen/clr/emitters.py +94 -0
  11. owl_basic/codegen/clr/generate.py +539 -0
  12. owl_basic/correlation_visitor.py +119 -0
  13. owl_basic/data_visitor.py +62 -0
  14. owl_basic/decoder.py +339 -0
  15. owl_basic/errors.py +22 -0
  16. owl_basic/flow/__init__.py +17 -0
  17. owl_basic/flow/basic_block.py +34 -0
  18. owl_basic/flow/basic_block_identifier.py +66 -0
  19. owl_basic/flow/basic_block_orderer.py +29 -0
  20. owl_basic/flow/connectors.py +19 -0
  21. owl_basic/flow/convert_sub_visitor.py +28 -0
  22. owl_basic/flow/entry_point_locator.py +55 -0
  23. owl_basic/flow/entry_point_visitor.py +48 -0
  24. owl_basic/flow/flow_analysis.py +56 -0
  25. owl_basic/flow/flow_graph_creator.py +14 -0
  26. owl_basic/flow/flowgraph_visitor.py +178 -0
  27. owl_basic/flow/longjump_converter.py +20 -0
  28. owl_basic/flow/longjump_visitor.py +53 -0
  29. owl_basic/flow/subroutine_converter.py +38 -0
  30. owl_basic/flow/traversal.py +110 -0
  31. owl_basic/gml_visitor.py +151 -0
  32. owl_basic/line_mapper.py +43 -0
  33. owl_basic/line_number_visitor.py +65 -0
  34. owl_basic/main.py +381 -0
  35. owl_basic/node.py +21 -0
  36. owl_basic/options.py +22 -0
  37. owl_basic/owltyping/__init__.py +1 -0
  38. owl_basic/owltyping/function_type_inferer.py +50 -0
  39. owl_basic/owltyping/hindley_milner.py +524 -0
  40. owl_basic/owltyping/set_function_type_visitor.py +25 -0
  41. owl_basic/owltyping/type_system.py +220 -0
  42. owl_basic/owltyping/typecheck.py +60 -0
  43. owl_basic/owltyping/typecheck_visitor.py +471 -0
  44. owl_basic/parent_visitor.py +37 -0
  45. owl_basic/process.py +36 -0
  46. owl_basic/separation_visitor.py +98 -0
  47. owl_basic/sigil.py +30 -0
  48. owl_basic/simplify_visitor.py +204 -0
  49. owl_basic/singleton.py +127 -0
  50. owl_basic/source_debugging.py +124 -0
  51. owl_basic/symbol_table_visitor.py +220 -0
  52. owl_basic/symbol_tables.py +195 -0
  53. owl_basic/syntax/__init__.py +0 -0
  54. owl_basic/syntax/ast.py +1081 -0
  55. owl_basic/syntax/ast_meta.py +228 -0
  56. owl_basic/syntax/grammar.py +1972 -0
  57. owl_basic/syntax/lexer.py +943 -0
  58. owl_basic/syntax/parser.py +77 -0
  59. owl_basic/utility.py +26 -0
  60. owl_basic/visitor.py +43 -0
  61. owl_basic/xml_blocks.py +137 -0
  62. owl_basic/xml_visitor.py +101 -0
  63. owl_basic-0.6.0.dist-info/METADATA +37 -0
  64. owl_basic-0.6.0.dist-info/RECORD +69 -0
  65. owl_basic-0.6.0.dist-info/WHEEL +5 -0
  66. owl_basic-0.6.0.dist-info/entry_points.txt +2 -0
  67. owl_basic-0.6.0.dist-info/licenses/LICENSE +21 -0
  68. owl_basic-0.6.0.dist-info/licenses/THIRD-PARTY-NOTICES.md +57 -0
  69. owl_basic-0.6.0.dist-info/top_level.txt +1 -0
owl_basic/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """OWL BASIC — a BBC BASIC compiler for the .NET CLR with pluggable backends."""
2
+
3
+ __version__ = "0.6.0"
@@ -0,0 +1,29 @@
1
+ def all_equal(vals):
2
+ '''
3
+ Check if all elements of a list are equal.
4
+ :param vals: a sequence of items
5
+ '''
6
+ if vals:
7
+ i = iter(vals)
8
+ first = i.next()
9
+ for item in i:
10
+ if first != item:
11
+ return False
12
+ return True
13
+
14
+ def representative(s):
15
+ '''
16
+ Return an arbitrary value from the set s
17
+ :param s: A set
18
+ :returns: A representative value from s
19
+ '''
20
+ return iter(s).next()
21
+
22
+ def all_indices(string, sub, listindex=[], offset=0):
23
+ # call as l = allindices(string, sub)
24
+ # http://code.activestate.com/recipes/499314-find-all-indices-of-a-substring-in-a-given-string/
25
+ i = string.find(sub, offset)
26
+ while i >= 0:
27
+ listindex.append(i)
28
+ i = string.find(sub, i + 1)
29
+ return listindex
owl_basic/ast_utils.py ADDED
@@ -0,0 +1,204 @@
1
+ import logging
2
+ from owl_basic import errors
3
+ from owl_basic.utility import camelCaseToUnderscores
4
+
5
+ def elideNode(node, liftFormalTypes=False):
6
+ """
7
+ Removes a node from the AST, assigning the contents of its only attribute
8
+ attribute to the owning attribute, thereby simplifying the AST structure. If
9
+ liftFormalTypes is true, the formal type of the child is propagates to the
10
+ new owner of the data.
11
+ """
12
+ # TODO: Refactor! D.R.Y.
13
+ assert len(node.child_infos) == 1
14
+ #print node
15
+ #print node.child_infos
16
+ if isinstance(node.child_infos.values()[0], list):
17
+ prop = node.child_infos.keys()[0] # TODO: Rename list_property
18
+ #print prop
19
+
20
+ for item in getattr(node, prop):
21
+ if item is not None:
22
+ item.parent = node.parent
23
+ item.parent_property = node.parent_property
24
+ # Note: item.parent_index remains unchanged
25
+ else:
26
+ prop = node.child_infos.keys()[0]
27
+ assert not isinstance(prop, list)
28
+ item = getattr(node, prop)
29
+ if item is not None:
30
+ item.parent = node.parent
31
+ item.parent_property = node.parent_property
32
+ # Note: item.parent_index remains unchanged
33
+ assert hasattr(node.parent, node.parent_property)
34
+ if liftFormalTypes:
35
+ node.parent.child_infos[camelCaseToUnderscores(node.parent_property)] = node.child_infos[prop]
36
+ node.parent.setProperty(getattr(node, prop), node.parent_property)
37
+
38
+ def findFollowingStatement(statement):
39
+ """
40
+ Given a statement, locates the following statement or None
41
+ """
42
+ if statement.parent is None:
43
+ return None
44
+
45
+ if statement.parent_index is None:
46
+ return None
47
+
48
+ parent_list = getattr(statement.parent, statement.parent_property)
49
+
50
+ if isinstance(parent_list, list):
51
+ logging.debug("statement.parent_index = %s", statement.parent_index)
52
+ if statement.parent_index < (len(parent_list) - 1):
53
+ return parent_list[statement.parent_index + 1]
54
+
55
+ return findFollowingStatement(statement.parent)
56
+
57
+ def findRoot(node):
58
+ """
59
+ Given an AST node find the root node of the AST.
60
+ """
61
+ n = node
62
+ while n.parent is not None:
63
+ n = n.parent
64
+ return n
65
+
66
+ def findNode(node, predicate):
67
+ """
68
+ Given an AST node, search up the tree until a node matching the
69
+ predicate function is found. Returns the Node or None
70
+ """
71
+ n = node
72
+ while n is not None:
73
+ if predicate(n):
74
+ return n
75
+ n = n.parent
76
+ return None
77
+
78
+ def insertStatementBefore(statement, target):
79
+ """
80
+ Insert target before statement in the AST, and correct the AST and CFG references to match
81
+ """
82
+ # TODO: Does this need to correct incoming GOTOs or is that handled by adjusting the AST edges
83
+
84
+ if statement.parent is None:
85
+ errors.fatalError("Cannot insert statement before %s at line %s" % (statement, statement.lineNum))
86
+
87
+ parent_list = getattr(statement.parent, statement.parent_property)
88
+
89
+ if isinstance(parent_list, list):
90
+ parent_list.insert(statement.parent_index, target)
91
+ target.parent = statement.parent
92
+ target.parent_property = statement.parent_property
93
+ target.parent_index = statement.parent_index
94
+ statement.parent_index += 1
95
+
96
+ else:
97
+ errors.fatalError("Cannot insert statement into non-list %s at line %s" % (statement, statement.lineNum))
98
+ return
99
+
100
+ # Reconnect CFG
101
+ for prior_stmt in statement.inEdges:
102
+ assert statement in prior_stmt.outEdges
103
+ prior_stmt.outEdges.remove(statement)
104
+ prior_stmt.outEdges.add(target)
105
+ target.inEdges.add(prior_stmt)
106
+
107
+ statement.clearInEdges()
108
+ statement.addInEdge(target)
109
+
110
+ target.clearOutEdges()
111
+ target.addOutEdge(statement)
112
+
113
+ def insertStatementAfter(statement, target):
114
+ """
115
+ Insert target after statement in the AST, and correct the AST and CFG references to match
116
+ """
117
+ # TODO: Does this need to correct incoming GOTOs or is that handled by adjusting the AST edges
118
+
119
+ if statement.parent is None:
120
+ errors.fatalError("Cannot insert statement before %s at line %s" % (statement, statement.lineNum))
121
+
122
+ parent_list = getattr(statement.parent, statement.parent_property)
123
+
124
+ if isinstance(parent_list, list):
125
+ target_index = statement.parent_index + 1
126
+ parent_list.insert(target_index, target)
127
+ target.parent = statement.parent
128
+ target.parent_property = statement.parent_property
129
+ target.parent_index = target_index
130
+
131
+ else:
132
+ errors.fatalError("Cannot insert statement into non-list %s at line %s" % (statement, statement.lineNum))
133
+ return
134
+
135
+ # Reconnect CFG
136
+ for next_stmt in statement.outEdges:
137
+ assert statement in next_stmt.inEdges
138
+ next_statement.inEdges.remove(statement)
139
+ next_statement.inEdges.add(target)
140
+ target.outEdges.add(next_stmt)
141
+
142
+ statement.clearOutEdges()
143
+ statement.addOutEdge(target)
144
+
145
+ target.clearInEdges()
146
+ target.addInEdge(statement)
147
+
148
+ def removeStatement(statement):
149
+ """
150
+ Remove the statement from the AST
151
+ """
152
+ if statement.parent is None:
153
+ errors.fatalError("Cannot remove statement %s at line %s" % (statement, statement.lineNum))
154
+
155
+ # Remove from the parent list
156
+ parent_list = getattr(statement.parent, statement.parent_property)
157
+ parent_list.remove(statement)
158
+
159
+ # Reconnect CFG
160
+ for prior_stmt in statement.inEdges:
161
+ assert statement in prior_stmt.outEdges
162
+ prior_stmt.outEdges.remove(statement)
163
+ prior_stmt.outEdges.update(statement.outEdges)
164
+
165
+ for next_stmt in statement.outEdges:
166
+ assert statement in next_stmt.inEdges
167
+ next_stmt.inEdges.remove(statement)
168
+ next_stmt.inEdges.update(statement.inEdges)
169
+
170
+ statement.clearInEdges()
171
+ statement.clearOutEdges()
172
+
173
+ def replaceStatement(old, new):
174
+ '''
175
+ Replace old with new in the AST and CFG
176
+ '''
177
+ insertStatementBefore(old, new)
178
+ removeStatement(old)
179
+
180
+ def deParentNode(node):
181
+ '''
182
+ Disconnect a node from its parent
183
+ :returns: The node
184
+ '''
185
+ raise "Not implemented"
186
+
187
+ def parentNode(node, parent, parent_property):
188
+ '''
189
+ Parent a node the the given property
190
+ '''
191
+ raise "Not implemented"
192
+
193
+ def reParentnode(node, new_parent, parent_property=None):
194
+ '''
195
+ :param node: The node to be reparented
196
+ :param new_parent: The new parent for node
197
+ :paraent_property: The property of the parent to which the node will be attached. If not
198
+ supplied this will use the parent_property as the original parent.
199
+ '''
200
+ if parent_property is None:
201
+ parent_property = node.parent_property
202
+
203
+ deParentNode(node)
204
+ parentNode(node, new_parent, parent_property)
@@ -0,0 +1,55 @@
1
+ from owl_basic.visitor import Visitor
2
+
3
+ class BasicVisitor(Visitor):
4
+ """
5
+ AST visitor for converting the AST into back into OWL BASIC.
6
+ """
7
+ def __init__(self):
8
+ pass
9
+
10
+ def visitLiteralInteger(self, integer):
11
+ sys.stdout.write(str(integer.value))
12
+
13
+ def visitCircle(self, circle):
14
+ sys.stdout.write("CIRCLE ")
15
+ if circle.fill:
16
+ sys.stdout.write("FILL ")
17
+ self.visit(circle.xCoord)
18
+ sys.stdout.write(", ")
19
+ self.visit(circle.yCoord)
20
+ sys.stdout.write(", ")
21
+ self.visit(circle.radius)
22
+ sys.stdout.write('\n')
23
+
24
+ def visitMidStrFunc(self, mid_str_func):
25
+ sys.stdout.write("MID$(")
26
+ self.visit(mid_str_func.source)
27
+ sys.stdout.write(", ")
28
+ self.visit(mid_str_func.position)
29
+ if mid_str_func.length is not None:
30
+ sys.stdout.write(", ")
31
+ self.visit(mid_str_func.length)
32
+ sys.stdout.write(")")
33
+
34
+ def visitTrueFunc(self, true_func):
35
+ sys.stdout.write("TRUE ")
36
+
37
+ def visitAcsFunc(self, acs_func):
38
+ sys.stdout.write("ACS ")
39
+
40
+ def visitAdvalFunc(self, adval_func):
41
+ sys.stdout.write("ADVAL ")
42
+ sys.stdout.write(adval_func.factor)
43
+
44
+ def visitAsnFunc(self, Asn_func):
45
+ sys.stdout.write("ASN ")
46
+
47
+ def visitAtnFunc(self, atn_func):
48
+ sys.stdout.write("ATN ")
49
+
50
+ def visitStrStringFunc(self, str_string_func):
51
+ sys.stdout.write("STR$")
52
+ if str_string_func.base == 16:
53
+ sys.stdout.write("~")
54
+ self.visit(str_string_func.factor)
55
+
@@ -0,0 +1,65 @@
1
+ # Control Flow Graph Node
2
+
3
+ class CfgVertex(object):
4
+ __counter = 0
5
+
6
+ def __init__(self):
7
+ self.__in_edges = set()
8
+ self.__out_edges = set()
9
+ self.__come_from_gosub_edges = set()
10
+ self.__loop_back_edges = set()
11
+ self.__loop_from_edges = set()
12
+ self.__entry_points = set()
13
+
14
+ CfgVertex.__counter += 1
15
+ self.__id = CfgVertex.__counter
16
+
17
+ self.block = None
18
+
19
+ id = property(lambda self: self.__id)
20
+ inEdges = property(lambda self: self.__in_edges)
21
+ outEdges = property(lambda self: self.__out_edges)
22
+ comeFromGosubEdges = property(lambda self: self.__come_from_gosub_edges)
23
+ loopBackEdges = property(lambda self: self.__loop_back_edges)
24
+ loopFromEdges = property(lambda self: self.__loop_from_edges)
25
+ entryPoints = property(lambda self: self.__entry_points)
26
+
27
+ def clearInEdges(self):
28
+ self.__in_edges = set()
29
+
30
+ def clearOutEdges(self):
31
+ self.__out_edges = set()
32
+
33
+ def clearComeFromGosubEdges(self):
34
+ self.__come_from_gosub_edges = set()
35
+
36
+ def clearLoopBackEdges(self):
37
+ self.__loop_back_edges = set()
38
+
39
+ def clearLoopFromEdges(self):
40
+ self.__loop_from_edges = set()
41
+
42
+ def clearEntryPoints(self):
43
+ self.__entry_points.clear()
44
+
45
+ def addInEdge(self, from_vertex):
46
+ self.inEdges.add(from_vertex)
47
+
48
+ def addOutEdge(self, to_vertex):
49
+ self.outEdges.add(to_vertex)
50
+
51
+ def addComeFromGosubEdge(self, from_vertex):
52
+ self.comeFromGosubEdges.add(from_vertex)
53
+
54
+ def addLoopBackEdge(self, to_vertex):
55
+ self.loopBackEdges.add(to_vertex)
56
+
57
+ def addLoopFromEdge(self, to_vertex):
58
+ self.loopFromEdges.add(to_vertex)
59
+
60
+ def addEntryPoint(self, name):
61
+ self.entryPoints.add(name)
62
+
63
+ inDegree = property(lambda self: len(self.inEdges) + len(self.comeFromGosubEdges) + len(self.loopFromEdges))
64
+ outDegree = property(lambda self: len(self.outEdges) + len(self.loopBackEdges))
65
+
File without changes
File without changes