python-cc 0.0.2__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.
pcc/__init__.py ADDED
File without changes
pcc/__main__.py ADDED
@@ -0,0 +1,3 @@
1
+ if __name__ == '__main__':
2
+ from .pcc import main
3
+ main()
pcc/ast/__init__.py ADDED
File without changes
pcc/ast/ast.py ADDED
@@ -0,0 +1,179 @@
1
+
2
+ # AST hierarchy
3
+ class ASTNode(object):
4
+ def dump(self, indent=0):
5
+ raise NotImplementedError
6
+
7
+
8
+ class ExprAST(ASTNode):
9
+ pass
10
+
11
+
12
+ class NumberExprAST(ExprAST):
13
+ def __init__(self, val):
14
+ self.val = val
15
+
16
+ def dump(self, indent=0):
17
+ return '{0}{1}[{2}]'.format(
18
+ ' ' * indent, self.__class__.__name__, self.val)
19
+
20
+
21
+ class VariableExprAST(ExprAST):
22
+ def __init__(self, name):
23
+ self.name = name
24
+
25
+ def dump(self, indent=0):
26
+ return '{0}{1}[{2}]'.format(
27
+ ' ' * indent, self.__class__.__name__, self.name)
28
+
29
+
30
+ class VarExprAST(ExprAST):
31
+ def __init__(self, vars, body):
32
+ # vars is a sequence of (name, init) pairs
33
+ self.vars = vars
34
+ self.body = body
35
+
36
+ def dump(self, indent=0):
37
+ prefix = ' ' * indent
38
+ s = '{0}{1}\n'.format(prefix, self.__class__.__name__)
39
+ for name, init in self.vars:
40
+ s += '{0} {1}'.format(prefix, name)
41
+ if init is None:
42
+ s += '\n'
43
+ else:
44
+ s += '=\n' + init.dump(indent+2) + '\n'
45
+ s += '{0} Body:\n'.format(prefix)
46
+ s += self.body.dump(indent + 2)
47
+ return s
48
+
49
+
50
+ class UnaryExprAST(ExprAST):
51
+ def __init__(self, op, operand):
52
+ self.op = op
53
+ self.operand = operand
54
+
55
+ def dump(self, indent=0):
56
+ s = '{0}{1}[{2}]\n'.format(
57
+ ' ' * indent, self.__class__.__name__, self.op)
58
+ s += self.operand.dump(indent + 2)
59
+ return s
60
+
61
+
62
+ class BinaryExprAST(ExprAST):
63
+ def __init__(self, op, lhs, rhs):
64
+ self.op = op
65
+ self.lhs = lhs
66
+ self.rhs = rhs
67
+
68
+ def dump(self, indent=0):
69
+ s = '{0}{1}[{2}]\n'.format(
70
+ ' ' * indent, self.__class__.__name__, self.op)
71
+ s += self.lhs.dump(indent + 2) + '\n'
72
+ s += self.rhs.dump(indent + 2)
73
+ return s
74
+
75
+
76
+ class IfExprAST(ExprAST):
77
+ def __init__(self, cond_expr, then_expr, else_expr):
78
+ self.cond_expr = cond_expr
79
+ self.then_expr = then_expr
80
+ self.else_expr = else_expr
81
+
82
+ def dump(self, indent=0):
83
+ prefix = ' ' * indent
84
+ s = '{0}{1}\n'.format(prefix, self.__class__.__name__)
85
+ s += '{0} Condition:\n{1}\n'.format(
86
+ prefix, self.cond_expr.dump(indent + 2))
87
+ s += '{0} Then:\n{1}\n'.format(
88
+ prefix, self.then_expr.dump(indent + 2))
89
+ s += '{0} Else:\n{1}'.format(
90
+ prefix, self.else_expr.dump(indent + 2))
91
+ return s
92
+
93
+
94
+ class ForExprAST(ExprAST):
95
+ def __init__(self, id_name, start_expr, end_expr, step_expr, body):
96
+ self.id_name = id_name
97
+ self.start_expr = start_expr
98
+ self.end_expr = end_expr
99
+ self.step_expr = step_expr
100
+ self.body = body
101
+
102
+ def dump(self, indent=0):
103
+ prefix = ' ' * indent
104
+ s = '{0}{1}\n'.format(prefix, self.__class__.__name__)
105
+ s += '{0} Start [{1}]:\n{2}\n'.format(
106
+ prefix, self.id_name, self.start_expr.dump(indent + 2))
107
+ s += '{0} End:\n{1}\n'.format(
108
+ prefix, self.end_expr.dump(indent + 2))
109
+ s += '{0} Step:\n{1}\n'.format(
110
+ prefix, self.step_expr.dump(indent + 2))
111
+ s += '{0} Body:\n{1}\n'.format(
112
+ prefix, self.body.dump(indent + 2))
113
+ return s
114
+
115
+
116
+ class CallExprAST(ExprAST):
117
+ def __init__(self, callee, args):
118
+ self.callee = callee
119
+ self.args = args
120
+
121
+ def dump(self, indent=0):
122
+ s = '{0}{1}[{2}]\n'.format(
123
+ ' ' * indent, self.__class__.__name__, self.callee)
124
+ for arg in self.args:
125
+ s += arg.dump(indent + 2) + '\n'
126
+ return s[:-1] # snip out trailing '\n'
127
+
128
+
129
+ class PrototypeAST(ASTNode):
130
+ def __init__(self, name, argnames, isoperator=False, prec=0):
131
+ self.name = name
132
+ self.argnames = argnames
133
+ self.isoperator = isoperator
134
+ self.prec = prec
135
+
136
+ def is_unary_op(self):
137
+ return self.isoperator and len(self.argnames) == 1
138
+
139
+ def is_binary_op(self):
140
+ return self.isoperator and len(self.argnames) == 2
141
+
142
+ def get_op_name(self):
143
+ assert self.isoperator
144
+ return self.name[-1]
145
+
146
+ def dump(self, indent=0):
147
+ s = '{0}{1} {2}({3})'.format(
148
+ ' ' * indent, self.__class__.__name__, self.name,
149
+ ', '.join(self.argnames))
150
+ if self.isoperator:
151
+ s += '[operator with prec={0}]'.format(self.prec)
152
+ return s
153
+
154
+
155
+ class FunctionAST(ASTNode):
156
+ def __init__(self, proto, body):
157
+ self.proto = proto
158
+ self.body = body
159
+
160
+ _anonymous_function_counter = 0
161
+
162
+ @classmethod
163
+ def create_anonymous(klass, expr):
164
+ """Create an anonymous function to hold an expression."""
165
+ klass._anonymous_function_counter += 1
166
+ return klass(
167
+ PrototypeAST('_anon{0}'.format(klass._anonymous_function_counter),
168
+ []),
169
+ expr)
170
+
171
+ def is_anonymous(self):
172
+ return self.proto.name.startswith('_anon')
173
+
174
+ def dump(self, indent=0):
175
+ s = '{0}{1}[{2}]\n'.format(
176
+ ' ' * indent, self.__class__.__name__, self.proto.dump())
177
+ s += self.body.dump(indent + 2) + '\n'
178
+ return s
179
+
@@ -0,0 +1,106 @@
1
+ #------------------------------------------------------------------------------
2
+ # pycparser: ast_transforms.py
3
+ #
4
+ # Some utilities used by the parser to create a friendlier AST.
5
+ #
6
+ # Copyright (C) 2008-2015, Eli Bendersky
7
+ # License: BSD
8
+ #------------------------------------------------------------------------------
9
+
10
+ from . import c_ast
11
+
12
+
13
+ def fix_switch_cases(switch_node):
14
+ """ The 'case' statements in a 'switch' come out of parsing with one
15
+ child node, so subsequent statements are just tucked to the parent
16
+ Compound. Additionally, consecutive (fall-through) case statements
17
+ come out messy. This is a peculiarity of the C grammar. The following:
18
+
19
+ switch (myvar) {
20
+ case 10:
21
+ k = 10;
22
+ p = k + 1;
23
+ return 10;
24
+ case 20:
25
+ case 30:
26
+ return 20;
27
+ default:
28
+ break;
29
+ }
30
+
31
+ Creates this tree (pseudo-dump):
32
+
33
+ Switch
34
+ ID: myvar
35
+ Compound:
36
+ Case 10:
37
+ k = 10
38
+ p = k + 1
39
+ return 10
40
+ Case 20:
41
+ Case 30:
42
+ return 20
43
+ Default:
44
+ break
45
+
46
+ The goal of this transform it to fix this mess, turning it into the
47
+ following:
48
+
49
+ Switch
50
+ ID: myvar
51
+ Compound:
52
+ Case 10:
53
+ k = 10
54
+ p = k + 1
55
+ return 10
56
+ Case 20:
57
+ Case 30:
58
+ return 20
59
+ Default:
60
+ break
61
+
62
+ A fixed AST node is returned. The argument may be modified.
63
+ """
64
+ assert isinstance(switch_node, c_ast.Switch)
65
+ if not isinstance(switch_node.stmt, c_ast.Compound):
66
+ return switch_node
67
+
68
+ # The new Compound child for the Switch, which will collect children in the
69
+ # correct order
70
+ new_compound = c_ast.Compound([], switch_node.stmt.coord)
71
+
72
+ # The last Case/Default node
73
+ last_case = None
74
+
75
+ # Goes over the children of the Compound below the Switch, adding them
76
+ # either directly below new_compound or below the last Case as appropriate
77
+ for child in switch_node.stmt.block_items:
78
+ if isinstance(child, (c_ast.Case, c_ast.Default)):
79
+ # If it's a Case/Default:
80
+ # 1. Add it to the Compound and mark as "last case"
81
+ # 2. If its immediate child is also a Case or Default, promote it
82
+ # to a sibling.
83
+ new_compound.block_items.append(child)
84
+ _extract_nested_case(child, new_compound.block_items)
85
+ last_case = new_compound.block_items[-1]
86
+ else:
87
+ # Other statements are added as children to the last case, if it
88
+ # exists.
89
+ if last_case is None:
90
+ new_compound.block_items.append(child)
91
+ else:
92
+ last_case.stmts.append(child)
93
+
94
+ switch_node.stmt = new_compound
95
+ return switch_node
96
+
97
+
98
+ def _extract_nested_case(case_node, stmts_list):
99
+ """ Recursively extract consecutive Case statements that are made nested
100
+ by the parser and add them to the stmts_list.
101
+ """
102
+ if isinstance(case_node.stmts[0], (c_ast.Case, c_ast.Default)):
103
+ stmts_list.append(case_node.stmts.pop())
104
+ _extract_nested_case(stmts_list[-1], stmts_list)
105
+
106
+