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,77 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
import ply.lex as lex
|
|
5
|
+
import ply.yacc as yacc
|
|
6
|
+
|
|
7
|
+
from . import grammar
|
|
8
|
+
from . import lexer
|
|
9
|
+
|
|
10
|
+
__author__ = 'rjs'
|
|
11
|
+
|
|
12
|
+
def buildLexer(options):
|
|
13
|
+
logging.debug("buildLexer")
|
|
14
|
+
if options.verbose:
|
|
15
|
+
sys.stderr.write("Building lexer...")
|
|
16
|
+
# Build the lexer and parser
|
|
17
|
+
|
|
18
|
+
lx = lex.lex(lexer)
|
|
19
|
+
if options.verbose:
|
|
20
|
+
sys.stderr.write("done\n")
|
|
21
|
+
|
|
22
|
+
return lx
|
|
23
|
+
|
|
24
|
+
def tokenize(data, lexer):
|
|
25
|
+
'''Lex the data and exit.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
data: The data to be lexed.
|
|
29
|
+
lexer: The lexer instance to do the lexing.
|
|
30
|
+
'''
|
|
31
|
+
# Give the lexer some input
|
|
32
|
+
lexer.input(data)
|
|
33
|
+
|
|
34
|
+
# Tokenize
|
|
35
|
+
while 1:
|
|
36
|
+
tok = lexer.token()
|
|
37
|
+
if not tok: break # No more input
|
|
38
|
+
print(tok)
|
|
39
|
+
# Running the lexer twice on the same input screws up the line numbers, so stop here.
|
|
40
|
+
sys.exit(0)
|
|
41
|
+
|
|
42
|
+
# The LALR tables are expensive to build but identical for every parse, so the
|
|
43
|
+
# parser is constructed once and cached. write_tables=False keeps construction
|
|
44
|
+
# entirely in memory: when owl_basic is installed as a wheel the grammar module
|
|
45
|
+
# lives in a possibly read-only site-packages, where writing parsetab/parser.out
|
|
46
|
+
# would either fail or litter the install.
|
|
47
|
+
_basic_parser = None
|
|
48
|
+
|
|
49
|
+
def buildParser(options):
|
|
50
|
+
logging.debug("buildParser")
|
|
51
|
+
global _basic_parser
|
|
52
|
+
if _basic_parser is None:
|
|
53
|
+
if options.verbose:
|
|
54
|
+
sys.stderr.write("Building parser... ")
|
|
55
|
+
_basic_parser = yacc.yacc(module=grammar, write_tables=False, debug=False)
|
|
56
|
+
if options.verbose:
|
|
57
|
+
sys.stderr.write("done\n")
|
|
58
|
+
|
|
59
|
+
return _basic_parser
|
|
60
|
+
|
|
61
|
+
def parse(data, options):
|
|
62
|
+
logging.debug("parse")
|
|
63
|
+
if options.verbose:
|
|
64
|
+
sys.stderr.write("Parsing...")
|
|
65
|
+
|
|
66
|
+
lexer = buildLexer(options)
|
|
67
|
+
|
|
68
|
+
if options.debug_lex:
|
|
69
|
+
tokenize(data, lexer)
|
|
70
|
+
|
|
71
|
+
parser = buildParser(options)
|
|
72
|
+
|
|
73
|
+
parse_tree = parser.parse(data, lexer=lexer, tracking=True)
|
|
74
|
+
if options.verbose:
|
|
75
|
+
sys.stderr.write("done\n")
|
|
76
|
+
|
|
77
|
+
return parse_tree
|
owl_basic/utility.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Miscellaneous utility functions
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
def underscoresToCamelCase(s):
|
|
6
|
+
"Converts 'text_separated_like_this' to 'textSeparatedLikeThis'"
|
|
7
|
+
t = s.replace('_', ' ').title().replace(' ', '')
|
|
8
|
+
u = t[0].lower() + t[1:]
|
|
9
|
+
return u
|
|
10
|
+
|
|
11
|
+
def camelCaseToUnderscores(s):
|
|
12
|
+
"Converts 'textSeparatedLikeThis' to 'text_separated_like_this'"
|
|
13
|
+
return re.sub(r'([a-z])([A-Z])', r'\1_\2', s).lower()
|
|
14
|
+
|
|
15
|
+
def hasprop(cls, name):
|
|
16
|
+
"Determines whether the supplied object has a property called 'name'"
|
|
17
|
+
(name in cls.__dict__ and isinstance(cls.__dict__[name], property))
|
|
18
|
+
|
|
19
|
+
if name in cls.__dict__:
|
|
20
|
+
return isinstance(cls.__dict__[name], property)
|
|
21
|
+
for base in cls.__bases__:
|
|
22
|
+
if hasprop(base, name):
|
|
23
|
+
return True
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
|
owl_basic/visitor.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# The Visitor base class
|
|
2
|
+
|
|
3
|
+
class Visitor(object):
|
|
4
|
+
"""
|
|
5
|
+
A base visitor class
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
def visit(self, node):
|
|
9
|
+
"""
|
|
10
|
+
Visits a given node by telling the node to call this Visitor's
|
|
11
|
+
class-specific visitor method. No-op if node is None.
|
|
12
|
+
"""
|
|
13
|
+
if node is not None:
|
|
14
|
+
return node.accept(self)
|
|
15
|
+
|
|
16
|
+
class Visitable(object):
|
|
17
|
+
"""
|
|
18
|
+
A mixin for classes which are visitable
|
|
19
|
+
"""
|
|
20
|
+
def accept(self, visitor):
|
|
21
|
+
"""
|
|
22
|
+
Accept method for visitor pattern.
|
|
23
|
+
"""
|
|
24
|
+
return self._accept(self.__class__, visitor)
|
|
25
|
+
|
|
26
|
+
def _accept(self, klass, visitor):
|
|
27
|
+
"""
|
|
28
|
+
Recursive accept implementation that calls the right visitor
|
|
29
|
+
method 'overloaded' for the type of AstNode. This is done by
|
|
30
|
+
appending the class name to 'visit' so if the class name is AstNode
|
|
31
|
+
the method called is visitor.visitAstNode. If a method of that name
|
|
32
|
+
does not exist, then it recursively attempts to call the visitor
|
|
33
|
+
method on the superclass.
|
|
34
|
+
"""
|
|
35
|
+
visitor_method = getattr(visitor, "visit%s" % klass.__name__, None)
|
|
36
|
+
if visitor_method is None:
|
|
37
|
+
bases = klass.__bases__
|
|
38
|
+
last = None
|
|
39
|
+
for i in bases:
|
|
40
|
+
last = self._accept(i, visitor)
|
|
41
|
+
return last
|
|
42
|
+
else:
|
|
43
|
+
return visitor_method(self)
|
owl_basic/xml_blocks.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from itertools import chain
|
|
2
|
+
|
|
3
|
+
from owl_basic.syntax.ast import If, OnGoto
|
|
4
|
+
from owl_basic.flow.traversal import depthFirstSearch
|
|
5
|
+
|
|
6
|
+
def dumpXmlBlocks(basic_blocks, filename, options):
|
|
7
|
+
import clr
|
|
8
|
+
clr.AddReference('System.Xml')
|
|
9
|
+
from System.Xml import XmlTextWriter, Formatting
|
|
10
|
+
|
|
11
|
+
writer = XmlTextWriter(filename, None)
|
|
12
|
+
writer.Formatting = Formatting.Indented
|
|
13
|
+
writeHeader(writer)
|
|
14
|
+
|
|
15
|
+
print(basic_blocks)
|
|
16
|
+
|
|
17
|
+
for entry_block in basic_blocks.values():
|
|
18
|
+
for block in depthFirstSearch(entry_block):
|
|
19
|
+
writeBlock(writer, block)
|
|
20
|
+
|
|
21
|
+
for entry_block in basic_blocks.values():
|
|
22
|
+
for block in depthFirstSearch(entry_block):
|
|
23
|
+
for statement in block.statements:
|
|
24
|
+
writeStatementEdges(writer, statement)
|
|
25
|
+
|
|
26
|
+
writeFooter(writer)
|
|
27
|
+
|
|
28
|
+
def writeHeader(writer):
|
|
29
|
+
writer.WriteComment("GraphML representation of the Basic Block Graph")
|
|
30
|
+
|
|
31
|
+
writer.WriteStartElement("graphml")
|
|
32
|
+
writer.WriteAttributeString("xmlns", "http://graphml.graphdrawing.org/xmlns")
|
|
33
|
+
writer.WriteAttributeString("xmlns", "xsi", None, "http://www.w3.org/2001/XMLSchema-instance")
|
|
34
|
+
writer.WriteAttributeString("xmlns", "y", None, "http://www.yworks.com/xml/graphml")
|
|
35
|
+
writer.WriteAttributeString("xsi", "schemaLocation", "http://graphml.graphdrawing.org/xmlns/graphml", "http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd")
|
|
36
|
+
|
|
37
|
+
writer.WriteStartElement("key")
|
|
38
|
+
writer.WriteAttributeString("id", "d0")
|
|
39
|
+
writer.WriteAttributeString("for", "node")
|
|
40
|
+
writer.WriteAttributeString("yfiles.type", "nodegraphics")
|
|
41
|
+
writer.WriteEndElement() # key
|
|
42
|
+
|
|
43
|
+
writer.WriteStartElement("key")
|
|
44
|
+
writer.WriteAttributeString("id", "d1")
|
|
45
|
+
writer.WriteAttributeString("for", "node")
|
|
46
|
+
writer.WriteAttributeString("attr.name", "description")
|
|
47
|
+
writer.WriteAttributeString("attr.type", "string")
|
|
48
|
+
writer.WriteEndElement() # key
|
|
49
|
+
|
|
50
|
+
writer.WriteStartElement("key")
|
|
51
|
+
writer.WriteAttributeString("id", "d3")
|
|
52
|
+
writer.WriteAttributeString("for", "edge")
|
|
53
|
+
writer.WriteAttributeString("yfiles.type", "edgegraphics")
|
|
54
|
+
writer.WriteEndElement() # key
|
|
55
|
+
|
|
56
|
+
writer.WriteStartElement("key")
|
|
57
|
+
writer.WriteAttributeString("id", "d4")
|
|
58
|
+
writer.WriteAttributeString("for", "graphml")
|
|
59
|
+
writer.WriteAttributeString("yfiles.type", "resources")
|
|
60
|
+
writer.WriteEndElement() # key
|
|
61
|
+
|
|
62
|
+
writer.WriteStartElement("graph")
|
|
63
|
+
writer.WriteAttributeString("id", "CFG")
|
|
64
|
+
writer.WriteAttributeString("edgedefault", "directed")
|
|
65
|
+
|
|
66
|
+
def writeBlock(writer, block):
|
|
67
|
+
writer.WriteStartElement("node")
|
|
68
|
+
writer.WriteAttributeString("id", str(block.id))
|
|
69
|
+
|
|
70
|
+
writer.WriteStartElement("data")
|
|
71
|
+
writer.WriteAttributeString("key", "d0") # Shape and label
|
|
72
|
+
writer.WriteStartElement("y:ShapeNode")
|
|
73
|
+
writer.WriteStartElement("y:NodeLabel")
|
|
74
|
+
writer.WriteString(str(block.topological_order))
|
|
75
|
+
writer.WriteEndElement() # y:NodeLabel
|
|
76
|
+
writer.WriteEndElement() # y:ShapeNode
|
|
77
|
+
writer.WriteEndElement() # data
|
|
78
|
+
|
|
79
|
+
writer.WriteStartElement("graph")
|
|
80
|
+
writer.WriteAttributeString("edgedefault", "directed")
|
|
81
|
+
|
|
82
|
+
for statement in block.statements:
|
|
83
|
+
writeStatementNode(writer, statement)
|
|
84
|
+
|
|
85
|
+
writer.WriteEndElement() # graph
|
|
86
|
+
writer.WriteEndElement() # node
|
|
87
|
+
|
|
88
|
+
def writeStatementNode(writer, statement):
|
|
89
|
+
writer.WriteStartElement("node")
|
|
90
|
+
writer.WriteAttributeString("id", str(statement.block.id) + '::' + str(statement.id))
|
|
91
|
+
|
|
92
|
+
writer.WriteStartElement("data")
|
|
93
|
+
writer.WriteAttributeString("key", "d0") # Shape and label
|
|
94
|
+
writer.WriteStartElement("y:ShapeNode")
|
|
95
|
+
writer.WriteStartElement("y:NodeLabel")
|
|
96
|
+
writer.WriteString(str(statement.lineNum) + ": "+ str(statement.description))
|
|
97
|
+
writer.WriteEndElement() # y:NodeLabel
|
|
98
|
+
writer.WriteStartElement("y:Shape")
|
|
99
|
+
if hasattr(statement, "entryPoint"):
|
|
100
|
+
writer.WriteAttributeString("type", "hexagon")
|
|
101
|
+
elif isinstance(statement, If) or isinstance(statement, OnGoto):
|
|
102
|
+
writer.WriteAttributeString("type", "diamond")
|
|
103
|
+
else:
|
|
104
|
+
writer.WriteAttributeString("type", "roundrectangle")
|
|
105
|
+
writer.WriteEndElement() # y:Shape
|
|
106
|
+
writer.WriteEndElement() # y:ShapeNode
|
|
107
|
+
writer.WriteEndElement()
|
|
108
|
+
|
|
109
|
+
writer.WriteStartElement("data")
|
|
110
|
+
writer.WriteAttributeString("key", "d1") # description
|
|
111
|
+
writer.WriteString(statement.description)
|
|
112
|
+
writer.WriteEndElement()
|
|
113
|
+
|
|
114
|
+
writer.WriteEndElement() # node
|
|
115
|
+
|
|
116
|
+
def writeStatementEdges(writer, statement):
|
|
117
|
+
for target in chain(statement.outEdges, statement.loopBackEdges):
|
|
118
|
+
writer.WriteStartElement("edge")
|
|
119
|
+
writer.WriteAttributeString("source", str(statement.block.id) + '::' + str(statement.id))
|
|
120
|
+
writer.WriteAttributeString("target", str(target.block.id) + '::' + str(target.id))
|
|
121
|
+
writer.WriteStartElement("data")
|
|
122
|
+
writer.WriteAttributeString("key", "d3")
|
|
123
|
+
writer.WriteStartElement("y:PolyLineEdge")
|
|
124
|
+
writer.WriteStartElement("y:Arrows")
|
|
125
|
+
writer.WriteAttributeString("source", "none")
|
|
126
|
+
writer.WriteAttributeString("target", "standard")
|
|
127
|
+
writer.WriteEndElement() # y:Arrows
|
|
128
|
+
writer.WriteEndElement() # y:PolyLineEdge
|
|
129
|
+
writer.WriteEndElement() # data
|
|
130
|
+
writer.WriteEndElement() # edge
|
|
131
|
+
|
|
132
|
+
def writeFooter(writer):
|
|
133
|
+
writer.WriteEndElement() # graph
|
|
134
|
+
writer.WriteEndElement() # graphml
|
|
135
|
+
writer.Flush()
|
|
136
|
+
writer.Close()
|
|
137
|
+
|
owl_basic/xml_visitor.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# A visitor implementation that creates an XML representation of the abstract syntax tree
|
|
2
|
+
|
|
3
|
+
from owl_basic.visitor import Visitor
|
|
4
|
+
|
|
5
|
+
class XmlVisitor(Visitor):
|
|
6
|
+
"""
|
|
7
|
+
AST visitor for converting the AST into an XML representation.
|
|
8
|
+
"""
|
|
9
|
+
def __init__(self, filename):
|
|
10
|
+
# .NET Framework
|
|
11
|
+
import clr
|
|
12
|
+
clr.AddReference('System.Xml')
|
|
13
|
+
from System.Xml import XmlTextWriter, Formatting
|
|
14
|
+
|
|
15
|
+
self.writer = XmlTextWriter(filename, None)
|
|
16
|
+
self.writer.Formatting = Formatting.Indented
|
|
17
|
+
self.writer.WriteComment("XML Parse Tree")
|
|
18
|
+
|
|
19
|
+
def close(self):
|
|
20
|
+
self.writer.Flush()
|
|
21
|
+
self.writer.Close()
|
|
22
|
+
|
|
23
|
+
def beginElement(self, node):
|
|
24
|
+
name = node.__class__.__name__
|
|
25
|
+
self.writer.WriteStartElement(name)
|
|
26
|
+
|
|
27
|
+
def endElement(self):
|
|
28
|
+
self.writer.WriteEndElement()
|
|
29
|
+
|
|
30
|
+
def childElement(self, name, node):
|
|
31
|
+
self.writer.WriteStartElement(name)
|
|
32
|
+
if node is None:
|
|
33
|
+
self.childNoneElement()
|
|
34
|
+
else:
|
|
35
|
+
self.visit(node)
|
|
36
|
+
self.writer.WriteEndElement()
|
|
37
|
+
|
|
38
|
+
def childNodeElement(self, name, node):
|
|
39
|
+
self.writer.WriteStartElement(name)
|
|
40
|
+
if node is None:
|
|
41
|
+
self.childNoneElement()
|
|
42
|
+
else:
|
|
43
|
+
if name in node.parent.child_infos:
|
|
44
|
+
#print "node = %s, name = %s" % (node, name)
|
|
45
|
+
#print "node.parent.child_infos = %s" % str(node.parent.child_infos)
|
|
46
|
+
# TODO: Next if is temporary
|
|
47
|
+
if not isinstance(node.parent.child_infos[name], list):
|
|
48
|
+
if node.parent.child_infos[name].nodeType is not None:
|
|
49
|
+
self.childAttribute("node_type", str(node.parent.child_infos[name].nodeType))
|
|
50
|
+
if node.parent.child_infos[name].formalType is not None:
|
|
51
|
+
self.childAttribute("formal_type", str(node.parent.child_infos[name].formalType))
|
|
52
|
+
self.visit(node)
|
|
53
|
+
self.writer.WriteEndElement()
|
|
54
|
+
|
|
55
|
+
def childListElement(self, name, nodes):
|
|
56
|
+
self.writer.WriteStartElement(name)
|
|
57
|
+
for node in nodes:
|
|
58
|
+
if node is None:
|
|
59
|
+
self.childNoneElement()
|
|
60
|
+
else:
|
|
61
|
+
self.visit(node)
|
|
62
|
+
self.writer.WriteEndElement()
|
|
63
|
+
|
|
64
|
+
def childTextElement(self, name, text):
|
|
65
|
+
self.writer.WriteStartElement(name)
|
|
66
|
+
self.writer.WriteString(str(text))
|
|
67
|
+
self.writer.WriteEndElement()
|
|
68
|
+
|
|
69
|
+
def childNoneElement(self):
|
|
70
|
+
self.writer.WriteStartElement("None")
|
|
71
|
+
self.writer.WriteEndElement()
|
|
72
|
+
|
|
73
|
+
def childAttribute(self, name, value):
|
|
74
|
+
self.writer.WriteStartAttribute(name)
|
|
75
|
+
if isinstance(value, type):
|
|
76
|
+
if hasattr(value, '__doc__'):
|
|
77
|
+
self.writer.WriteString(value.__doc__)
|
|
78
|
+
else:
|
|
79
|
+
self.writer.WriteString(value.__name__)
|
|
80
|
+
else:
|
|
81
|
+
if not isinstance(value, basestring):
|
|
82
|
+
# TODO: Yuck rebinding!
|
|
83
|
+
value = str(value)
|
|
84
|
+
self.writer.WriteString(value.encode('ascii', 'xmlcharrefreplace'))
|
|
85
|
+
self.writer.WriteEndAttribute()
|
|
86
|
+
|
|
87
|
+
def visitAstNode(self, node):
|
|
88
|
+
self.beginElement(node)
|
|
89
|
+
for name, value in node.options.items():
|
|
90
|
+
if value is not None:
|
|
91
|
+
self.childAttribute(name, value)
|
|
92
|
+
for name, child in node.children.items():
|
|
93
|
+
#print "child = %s" % child
|
|
94
|
+
if isinstance(child, list):
|
|
95
|
+
#print "child!"
|
|
96
|
+
self.childListElement(name, child)
|
|
97
|
+
else:
|
|
98
|
+
#print "node!"
|
|
99
|
+
self.childNodeElement(name, child)
|
|
100
|
+
self.endElement()
|
|
101
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: owl-basic
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: A BBC BASIC compiler for the .NET CLR, with pluggable code-generation backends.
|
|
5
|
+
Author-email: Robert Smallshire <rob@sixty-north.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/rob-smallshire/owl-basic
|
|
8
|
+
Project-URL: Issues, https://github.com/rob-smallshire/owl-basic/issues
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
18
|
+
Requires-Python: >=3.14
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
License-File: THIRD-PARTY-NOTICES.md
|
|
22
|
+
Requires-Dist: ply>=3.11
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
A BBC BASIC compiler for the .NET CLR and Mono, written in IronPython and C#.
|
|
26
|
+
|
|
27
|
+
What it does
|
|
28
|
+
============
|
|
29
|
+
|
|
30
|
+
Allows you to write BBC BASIC code and run it with a similar performance profile to C#.
|
|
31
|
+
|
|
32
|
+
Is it finished?
|
|
33
|
+
===============
|
|
34
|
+
|
|
35
|
+
No. OWL BASIC compiles some simple programs and some complex commercial programs,
|
|
36
|
+
including Acornsoft's Sphinx adventure. There are still many features to be added, bugs
|
|
37
|
+
to be fixed and improvements to be made.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
owl_basic/__init__.py,sha256=j2K_xIyPSRComPNYyMZymf15Q1z1par3rKOzkIHqdqs,106
|
|
2
|
+
owl_basic/algorithms.py,sha256=qHpsjHz8bzZ4L99uRPGm_u74YTilFbi1aiD-T0RdX_k,773
|
|
3
|
+
owl_basic/ast_utils.py,sha256=mtmmNB0VD37uEwItf84HxSOFdWI8y4VbEEgUPmAwhpo,6938
|
|
4
|
+
owl_basic/basic_visitor.py,sha256=h0N8Jp3_cEDGtnlFJAkCFACSnyF4skWO66Uph7Zu_Oc,1621
|
|
5
|
+
owl_basic/cfg_vertex.py,sha256=Uw11v5afx7NDDWP782oRvHfmyYymQppmqvKHyf1_6V0,2131
|
|
6
|
+
owl_basic/correlation_visitor.py,sha256=HlOtaCnKRoWnRqZKqFGHkZ1n3GFwA8QYFCZblVky64o,5207
|
|
7
|
+
owl_basic/data_visitor.py,sha256=rnvcIaqTrDLRc1ngx2el04ZTfYf7hiUTQzswSVijZ-U,2325
|
|
8
|
+
owl_basic/decoder.py,sha256=aZFqkdWhhOLDDFYEjHbUDkVa1i2C8SUEfU-_GVNhd8c,13467
|
|
9
|
+
owl_basic/errors.py,sha256=hZbu7K_XeqApPXV7JYQJNsdt6V8COnW32nmnxfw2AB4,430
|
|
10
|
+
owl_basic/gml_visitor.py,sha256=XpeHIw1lVQoKxMGPT9V1gzgSAR2l_JcOmZFROw6Rfpo,7203
|
|
11
|
+
owl_basic/line_mapper.py,sha256=kM-ANszawPrpyzfEIXoF3tznmVMSowIm0TDXVLTrkeY,1991
|
|
12
|
+
owl_basic/line_number_visitor.py,sha256=zhToYoGEvJctCtWiKidl-0yZWTj1O628_hgwFKfo2JU,2005
|
|
13
|
+
owl_basic/main.py,sha256=EJZWkxyxwmLmRqBKZRofUwLFikzLdC7kHSjV9lzHzxg,14271
|
|
14
|
+
owl_basic/node.py,sha256=S0mPDq4wJ05C_2Zsuiuh6ynVJIsfB3AgB7vxSapV2Mg,563
|
|
15
|
+
owl_basic/options.py,sha256=fTzQmaRKS1zQHmo0FQqw95j0H7MImal-JIsEzE76zaI,514
|
|
16
|
+
owl_basic/parent_visitor.py,sha256=quLYU7Ef67uBnC5PC12jnisD9rb4z1Gb146DAGamdgM,1393
|
|
17
|
+
owl_basic/process.py,sha256=siQF_hIUtit4xNBpvKubkwuHE26Cid3l1N4ynWt9XT8,1120
|
|
18
|
+
owl_basic/separation_visitor.py,sha256=ES1tKOv9jCffRYEIWSt7AtOCD6vRgmPGPzRNdJDP9W0,4134
|
|
19
|
+
owl_basic/sigil.py,sha256=ela67wnNiPSmgdb5XmuMaHHOiPjazFLuu2xQiruL9tQ,1022
|
|
20
|
+
owl_basic/simplify_visitor.py,sha256=Le3Q_Lammt-4H19Ty_RSMF_q6cYrsxtckcaUcdhmlWY,8319
|
|
21
|
+
owl_basic/singleton.py,sha256=TFCnU3WlNLZeiHgRpsPgcx7qBQM6jEYijtLf9uax9xA,4771
|
|
22
|
+
owl_basic/source_debugging.py,sha256=cbTZF2t6oJdIZb12QpalfelpP52yEuvEE65IY10Rzdw,5702
|
|
23
|
+
owl_basic/symbol_table_visitor.py,sha256=jwY0S3p6uHWmC0TFKYx7SdfhsMBEEAhFOQ4D_M6dXSw,10483
|
|
24
|
+
owl_basic/symbol_tables.py,sha256=ZX23shJnZwn2H9puSQoOVUWhOUzeeZTUQNbl06hKfb0,8675
|
|
25
|
+
owl_basic/utility.py,sha256=Z78ayx8LvBc8YYsID1dkehU8Ven7xlGKw9_KWbi70Js,779
|
|
26
|
+
owl_basic/visitor.py,sha256=IRlzo3uzxWfJNnp5znyjC0gkqE8TXn3c5Cp_gNyyByY,1375
|
|
27
|
+
owl_basic/xml_blocks.py,sha256=YG_NbiRCBz5zCYsr6PrZ-2tfGAw3TyOfbgFMqc3MgpA,5416
|
|
28
|
+
owl_basic/xml_visitor.py,sha256=MxOa6iqW0mAllg5LOBj-uOit_hBCmnIw2QLPzyopEGw,3677
|
|
29
|
+
owl_basic/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
owl_basic/codegen/clr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
owl_basic/codegen/clr/cil_visitor.py,sha256=4_wWxEEqJpIglVeciUh4eupg37WOGwL4oF5YkkNeUWI,63051
|
|
32
|
+
owl_basic/codegen/clr/cts.py,sha256=aEuItTmiYu9k-Ivv_FR7xTXjUKygMFqhIA_2BZdcUl0,1835
|
|
33
|
+
owl_basic/codegen/clr/emitters.py,sha256=VFe2SNubR06JsuZBJBPhTwLIrrusOCkKSZNNtjA3znE,2966
|
|
34
|
+
owl_basic/codegen/clr/generate.py,sha256=w-SmuDkO-uzhkucoU0nhHyVng6IWsE3fODuSUXSoK8I,26741
|
|
35
|
+
owl_basic/flow/__init__.py,sha256=XFq1bAcVKnS4PqpDFe1d18baJROQ14MRFyoeGosmyfk,607
|
|
36
|
+
owl_basic/flow/basic_block.py,sha256=f-ZS8euYsW_qtoxJdnNK8m1BBZe_tDpsoitsTlh5O9M,1161
|
|
37
|
+
owl_basic/flow/basic_block_identifier.py,sha256=-Y8V4TQdSnrnedrlgJSdLqYmQducCfB3xF8Yy1gK4bE,3287
|
|
38
|
+
owl_basic/flow/basic_block_orderer.py,sha256=PDQu-k6zUVPfNKyNflgfDrX9hAobb3VNnIP61GcB584,975
|
|
39
|
+
owl_basic/flow/connectors.py,sha256=tzJiA3m9UUQazUE5ch2XPTvYGUAaVQsrra78NAVatto,549
|
|
40
|
+
owl_basic/flow/convert_sub_visitor.py,sha256=0PEgs8H6IJS_nVoXzfyHrx1sfbPAopMssf_Q-PH6EVc,977
|
|
41
|
+
owl_basic/flow/entry_point_locator.py,sha256=XJq-WZ3QTAIWaUoh-SobYDwyJ8vun3YcUQJtvKPBmLU,2541
|
|
42
|
+
owl_basic/flow/entry_point_visitor.py,sha256=vvsbE81cBd6mEqGq_WuaMZ96KnOiq8Zf7RWlMWml27o,1625
|
|
43
|
+
owl_basic/flow/flow_analysis.py,sha256=2SEAHz_eELAGJJqcfeen0nijcRxdS1HPK__kDXn4-T8,1879
|
|
44
|
+
owl_basic/flow/flow_graph_creator.py,sha256=01MJse23VraUszfBLWsToVIhuyB74MEjs_SIxr5pSV8,388
|
|
45
|
+
owl_basic/flow/flowgraph_visitor.py,sha256=9TxWnLvz2BoI1PQOI4Pg81QBPqjdLe09lgwb2P-6wNE,7265
|
|
46
|
+
owl_basic/flow/longjump_converter.py,sha256=_xDSGW_I_19PyZu1BDHlJHS7MBp6WrHoUdf9Z3nFxNw,596
|
|
47
|
+
owl_basic/flow/longjump_visitor.py,sha256=_hRpaJzi8fSK4o1pNk-p_Zpo038_yYmS1JIDqWrC1Kk,1843
|
|
48
|
+
owl_basic/flow/subroutine_converter.py,sha256=8zeHrbdKCn4OVPyP0fYCav0WbfurM3Y346u9x1QYFbo,1532
|
|
49
|
+
owl_basic/flow/traversal.py,sha256=tmddMP9wBOxu8krW8dY5lrC8zL6g3hg3K2u7IDtSaDc,4340
|
|
50
|
+
owl_basic/owltyping/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
51
|
+
owl_basic/owltyping/function_type_inferer.py,sha256=VQceiUDetKHvFj7oLIvpQo6Kn2EgJc_eXnMQ06dCbnw,2259
|
|
52
|
+
owl_basic/owltyping/hindley_milner.py,sha256=3y69sAyQtnU_Z-aXFoxi7Hb_jaJgPg-h989CUDz7UHw,15477
|
|
53
|
+
owl_basic/owltyping/set_function_type_visitor.py,sha256=VoHE2tc47SMG-eVWlgW4_1TJqydHerFSll6hd2-ls7c,886
|
|
54
|
+
owl_basic/owltyping/type_system.py,sha256=HNWq71v0lTTsVCVep8L4Gosy95Dgsdsluy-w0DU-710,5910
|
|
55
|
+
owl_basic/owltyping/typecheck.py,sha256=4QRuCy-V90gt04YUgo6UEWj-X9H1NP8L4F-1WUarRZw,2169
|
|
56
|
+
owl_basic/owltyping/typecheck_visitor.py,sha256=SPow5jg3vA121JrX-EOi162MDrJBiz-FZInRieG3b8o,21529
|
|
57
|
+
owl_basic/syntax/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
+
owl_basic/syntax/ast.py,sha256=o8kbg9aeJjeU_b3CKnoANKfry4hfNJyz0X4jl7tEOfI,29058
|
|
59
|
+
owl_basic/syntax/ast_meta.py,sha256=Fij-7qognPVFiPnEjCY7o9xW7KN-RVkhC6seEKkeb-8,8445
|
|
60
|
+
owl_basic/syntax/grammar.py,sha256=leolpm9CSgqsXLwMMB9CmvoheLnJw3KNG92GyPrrvV4,62946
|
|
61
|
+
owl_basic/syntax/lexer.py,sha256=ORCyQm2tkHLwE4bBem6mQiu-s9m3qsOcEeUX6XmkbjQ,13806
|
|
62
|
+
owl_basic/syntax/parser.py,sha256=xnJ5DzDPzz01_pRy631-5Pv5-DNq8FeqQoAwbHwW2fE,2064
|
|
63
|
+
owl_basic-0.6.0.dist-info/licenses/LICENSE,sha256=teoepIpqtwcGjmw82_JHvgVr8p_PhvGnNpG5aveFOoY,1106
|
|
64
|
+
owl_basic-0.6.0.dist-info/licenses/THIRD-PARTY-NOTICES.md,sha256=asX4kTzwW3shbySl2H_HWmNO5M5DQGqrRZvHW2CTR8w,2630
|
|
65
|
+
owl_basic-0.6.0.dist-info/METADATA,sha256=gnsZB3s_88rjlTggdme_N7xHKI8W57C1OfezOZL3xwE,1398
|
|
66
|
+
owl_basic-0.6.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
67
|
+
owl_basic-0.6.0.dist-info/entry_points.txt,sha256=lf0ZrIHD8y9C4W3C75siJwQinxAROMM2h1nCo4Mqbpg,50
|
|
68
|
+
owl_basic-0.6.0.dist-info/top_level.txt,sha256=BXtZ-rUkfzavlVA6Gb8vK_nrn5C7Z_LcWeTotgucxDk,10
|
|
69
|
+
owl_basic-0.6.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2007-2026 Robert Smallshire and OWL BASIC contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
OWL BASIC is licensed under the MIT License (see `LICENSE`). It additionally
|
|
4
|
+
incorporates, or derives from, third-party material whose attribution and
|
|
5
|
+
licensing terms are preserved below. Nothing here imposes copyleft; each item
|
|
6
|
+
is compatible with OWL BASIC's permissive licensing, subject to the credit
|
|
7
|
+
being retained.
|
|
8
|
+
|
|
9
|
+
## BBC BASIC detokenizer — `src/owl_basic/decoder.py`
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
(c) 2007 Matt Godbolt.
|
|
13
|
+
Updated 2008 Ian Smallshire.
|
|
14
|
+
Original: http://xania.org/200711/bbc-basic-v-format
|
|
15
|
+
"Use however you like, as long as you put credit where credit's due."
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The detokenizer that converts tokenized BBC BASIC programs to plain text
|
|
19
|
+
originates with Matt Godbolt and was extended by Ian Smallshire (and later
|
|
20
|
+
Robert Smallshire). It is used here under its stated terms, which require that
|
|
21
|
+
credit be preserved. Some of the token-table information was, per the original
|
|
22
|
+
header, obtained from RISC OS Open source code (see below).
|
|
23
|
+
|
|
24
|
+
## Singleton metaclass — `src/owl_basic/singleton.py`
|
|
25
|
+
|
|
26
|
+
By Gary Robinson (grobinson@transpose.com). Explicitly placed in the **public
|
|
27
|
+
domain** ("No rights reserved"). See
|
|
28
|
+
http://www.garyrobinson.net/2004/03/python_singleto.html — no obligations.
|
|
29
|
+
|
|
30
|
+
## RISC OS Open
|
|
31
|
+
|
|
32
|
+
Interface and factual information used by the compiler and runtime — BBC BASIC
|
|
33
|
+
token values, and SWI / VDU variable numbers in the OwlRuntime runtime library
|
|
34
|
+
— was informed by RISC OS Open material (https://www.riscosopen.org/), much of
|
|
35
|
+
which is published under the Apache License 2.0 / Castle shared-source terms.
|
|
36
|
+
These items are interface facts rather than copied code.
|
|
37
|
+
|
|
38
|
+
## Hindley–Milner type inference — `src/owl_basic/owltyping/hindley_milner.py`
|
|
39
|
+
|
|
40
|
+
A Python implementation by Robert Smallshire, based on the Scala code by Andrew
|
|
41
|
+
Forrest, the Perl code by Nikita Borisov, and the paper "Basic Polymorphic
|
|
42
|
+
Typechecking" by Luca Cardelli. This module is currently unused; if it is
|
|
43
|
+
retained in the compiler, the licensing of the upstream example code should be
|
|
44
|
+
confirmed (or the module replaced with a clean-room implementation).
|
|
45
|
+
|
|
46
|
+
## Acorn system font — `OwlRuntime/OwlRuntime/platform/riscos/AcornFont.cs`
|
|
47
|
+
|
|
48
|
+
The 8×8 bitmap glyph data reproduces the appearance of the Acorn / BBC system
|
|
49
|
+
font for VDU emulation. Bitmap font data of this kind derives from Acorn's
|
|
50
|
+
original ROM font. This affects only the .NET (CIL) backend's runtime library,
|
|
51
|
+
not the compiler. It may be retained with this provenance noted, or replaced
|
|
52
|
+
with a freely-licensed equivalent.
|
|
53
|
+
|
|
54
|
+
## PLY (Python Lex-Yacc)
|
|
55
|
+
|
|
56
|
+
Used as a normal dependency (not vendored). PLY is distributed under the BSD
|
|
57
|
+
License. See https://github.com/dabeaz/ply.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
owl_basic
|