CLikeTranspiler   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 71
rs 10
wmc 20

11 Methods

Rating   Name   Duplication   Size   Complexity  
A visit_Return() 0 4 2
A visit_BoolOp() 0 3 2
A visit_While() 0 6 2
A visit_Num() 0 2 1
A visit_If() 0 14 4
A visit_BinOp() 0 8 2
A visit_Str() 0 2 1
A visit_Compare() 0 5 1
A visit_AugAssign() 0 5 1
A visit() 0 5 2
A visit_Name() 0 4 2
1
import ast
2
3
4
symbols = {
5
    ast.Eq: "==",
6
    ast.NotEq: '!=',
7
    ast.Pass: '/*pass*/',
8
    ast.Mult: '*',
9
    ast.Add: '+',
10
    ast.Sub: '-',
11
    ast.Div: '/',
12
    ast.FloorDiv: '/',
13
    ast.Mod: '%',
14
    ast.Lt: '<',
15
    ast.Gt: '>',
16
    ast.GtE: '>=',
17
    ast.LtE: '<=',
18
    ast.LShift: '<<',
19
    ast.RShift: '>>',
20
    ast.BitXor: '^',
21
    ast.BitOr: '|',
22
    ast.BitAnd: '&',
23
    ast.Not: '!',
24
    ast.IsNot: '!=',
25
    ast.USub: '-',
26
    ast.And: '&&',
27
    ast.Or: '||'
28
}
29
30
31
def c_symbol(node):
32
    """Find the equivalent C symbol for a Python ast symbol node"""
33
    symbol_type = type(node)
34
    return symbols[symbol_type]
35
36
37
class CLikeTranspiler(ast.NodeVisitor):
38
    builtin_constants = frozenset(['True', 'False', 'None'])
39
    """Provides a base for C-like programming languages"""
40
    def visit(self, node):
41
        if type(node) in symbols:
42
            return c_symbol(node)
43
        else:
44
            return super(CLikeTranspiler, self).visit(node)
45
46
    def visit_Name(self, node):
47
        if node.id in self.builtin_constants:
48
            return node.id.lower()
49
        return node.id
50
51
    def visit_Num(self, node):
52
        return str(node.n)
53
54
    def visit_Str(self, node):
55
        return '"{0}"'.format(node.s)
56
57
    def visit_Return(self, node):
58
        if node.value:
59
            return 'return {0};'.format(self.visit(node.value))
60
        return 'return;'
61
62
    def visit_If(self, node):
63
        buf = []
64
        buf.append('if({0}) {{'.format(self.visit(node.test)))
65
        buf.extend([self.visit(child) for child in node.body])
66
67
        orelse = [self.visit(child) for child in node.orelse]
68
        if orelse:
69
            buf.append('} else {')
70
            buf.extend(orelse)
71
            buf.append("}")
72
        else:
73
            buf.append('}')
74
75
        return '\n'.join(buf)
76
77
    def visit_While(self, node):
78
        buf = []
79
        buf.append("while ({0}) {{".format(self.visit(node.test)))
80
        buf.extend([self.visit(n) for n in node.body])
81
        buf.append("}")
82
        return '\n'.join(buf)
83
84
    def visit_Compare(self, node):
85
        left = self.visit(node.left)
86
        op = self.visit(node.ops[0])
87
        right = self.visit(node.comparators[0])
88
        return "{0} {1} {2}".format(left, op, right)
89
90
    def visit_BoolOp(self, node):
91
        op = self.visit(node.op)
92
        return op.join([self.visit(v) for v in node.values])
93
94
    def visit_BinOp(self, node):
95
        if isinstance(node.op, ast.Pow):
96
            return "std::pow({0}, {1})".format(self.visit(node.left),
97
                                               self.visit(node.right))
98
99
        return " ".join([self.visit(node.left),
100
                         self.visit(node.op),
101
                         self.visit(node.right)])
102
103
    def visit_AugAssign(self, node):
104
        target = self.visit(node.target)
105
        op = self.visit(node.op)
106
        val = self.visit(node.value)
107
        return "{0} {1}= {2};".format(target, op, val)
108