File: ccg.py

package info (click to toggle)
cryptominisat 5.11.4%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,432 kB
  • sloc: cpp: 55,148; ansic: 9,642; python: 8,899; sh: 1,336; php: 477; sql: 403; javascript: 173; xml: 34; makefile: 15
file content (198 lines) | stat: -rw-r--r-- 6,075 bytes parent folder | download | duplicates (3)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Copyright (C) 2009-2020 Authors of CryptoMiniSat, see AUTHORS file
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

import ast

BINOP_SYMBOLS = {}
BINOP_SYMBOLS[ast.Add] = '+'
BINOP_SYMBOLS[ast.Sub] = '-'
BINOP_SYMBOLS[ast.Mult] = '*'
BINOP_SYMBOLS[ast.Div] = '/'
BINOP_SYMBOLS[ast.Mod] = '%'
BINOP_SYMBOLS[ast.Pow] = '**'
BINOP_SYMBOLS[ast.LShift] = '<<'
BINOP_SYMBOLS[ast.RShift] = '>>'
BINOP_SYMBOLS[ast.BitOr] = '|'
BINOP_SYMBOLS[ast.BitXor] = '^'
BINOP_SYMBOLS[ast.BitAnd] = '&'
BINOP_SYMBOLS[ast.FloorDiv] = '//'

BOOLOP_SYMBOLS = {}
BOOLOP_SYMBOLS[ast.And] = 'and'
BOOLOP_SYMBOLS[ast.Or] = 'or'

CMPOP_SYMBOLS = {}
CMPOP_SYMBOLS[ast.Eq] = '=='
CMPOP_SYMBOLS[ast.NotEq] = '!='
CMPOP_SYMBOLS[ast.Lt] = '<'
CMPOP_SYMBOLS[ast.LtE] = '<='
CMPOP_SYMBOLS[ast.Gt] = '>'
CMPOP_SYMBOLS[ast.GtE] = '>='
CMPOP_SYMBOLS[ast.Is] = 'is'
CMPOP_SYMBOLS[ast.IsNot] = 'is not'
CMPOP_SYMBOLS[ast.In] = 'in'
CMPOP_SYMBOLS[ast.NotIn] = 'not in'

class ccg:
    def fix_feat_name(x):
        return "df[\"%s\"]" % x


    def to_source(node, updater=fix_feat_name):
        """This function can convert a node tree back into python sourcecode.
        This is useful for debugging purposes, especially if you're dealing with
        custom asts not generated by python itself.

        It could be that the sourcecode is evaluable when the AST itself is not
        compilable / evaluable.  The reason for this is that the AST contains some
        more data than regular sourcecode does, which is dropped during
        conversion.
        """
        generator = ccg.SourceGenerator()
        generator.update=updater
        generator.visit(node)

        return ''.join(generator.result)

    class SourceGenerator(ast.NodeVisitor):
        """This visitor is able to transform a well formed syntax tree into python
        sourcecode.  For more details have a look at the docstring of the
        `node_to_source` function.
        """

        def __init__(self):
            self.result = []

        def write(self, x):
            self.result.append(x)

        def body(self, statements):
            for stmt in statements:
                self.visit(stmt)

        def body_or_else(self, node):
            self.body(node.body)
            if node.orelse:
                self.write('else:')
                self.body(node.orelse)

        def signature(self, node):
            want_comma = []
            def write_comma():
                if want_comma:
                    self.write(', ')
                else:
                    want_comma.append(True)

            padding = [None] * (len(node.args) - len(node.defaults))
            for arg, default in zip(node.args, padding + node.defaults):
                write_comma()
                self.visit(arg)
                if default is not None:
                    self.write('=')
                    self.visit(default)
            if node.vararg is not None:
                write_comma()
                self.write('*' + node.vararg)
            if node.kwarg is not None:
                write_comma()
                self.write('**' + node.kwarg)

        # Statements

        def visit_Expr(self, node):
            self.write("(")
            self.generic_visit(node)
            self.write(")")

        # Expressions

        def visit_Attribute(self, node):
            x = self.update(node.value.id + '.' + node.attr)
            self.write(x)


        # visiting functions. only log2
        # should be: df[divisor].apply(np.log2)
        def visit_Call(self, node):
            if node.func.id != "log2":
                self.visit(node.func)
            self.write('(')

            for arg in node.args:
                self.visit(arg)
            for keyword in node.keywords:
                self.write(keyword.arg + '=')
                self.visit(keyword.value)

            self.write(".apply(np.log2)")
            self.write(')')


        def visit_Name(self, node):
            #print("type:", type(node.id))
            if node.id != "log2":
                x = self.update(node.id)
            else:
                x = node.id

            self.write(x)

        def visit_Str(self, node):
            self.write(repr(node.s))

        def visit_Bytes(self, node):
            self.write(repr(node.s))

        def visit_Num(self, node):
            self.write(repr(node.n))

        def visit_BinOp(self, node):
            self.write('(')
            self.visit(node.left)
            self.write(' %s ' % BINOP_SYMBOLS[type(node.op)])
            self.visit(node.right)
            self.write(')')

        def visit_BoolOp(self, node):
            self.write('(')
            for idx, value in enumerate(node.values):
                if idx:
                    self.write(' %s ' % BOOLOP_SYMBOLS[type(node.op)])
                self.visit(value)
            self.write(')')

        def visit_Compare(self, node):
            self.write('(')
            self.visit(node.left)
            for op, right in zip(node.ops, node.comparators):
                self.write(' %s ' % CMPOP_SYMBOLS[type(op)])
                self.visit(right)
            self.write(')')

        # Helper Nodes

        def visit_alias(self, node):
            self.write(node.name)
            if node.asname is not None:
                self.write(' as ' + node.asname)

        def visit_arguments(self, node):
            self.signature(node)