Completed
Pull Request — master (#1)
by Valentin
02:24
created

CLikeTranspiler.visit_NameConstant()   A

Complexity

Conditions 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 3
dl 0
loc 7
rs 9.4285
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_NameConstant(self, node):
52
        if node.value is True:
53
            return "true"
54
        elif node.value is False:
55
            return "false"
56
        else:
57
            return node.value
58
59
    def visit_Num(self, node):
60
        return str(node.n)
61
62
    def visit_Str(self, node):
63
        return '"{0}"'.format(node.s)
64
65
    def visit_Return(self, node):
66
        if node.value:
67
            return 'return {0};'.format(self.visit(node.value))
68
        return 'return;'
69
70
    def visit_If(self, node):
71
        buf = []
72
        buf.append('if({0}) {{'.format(self.visit(node.test)))
73
        buf.extend([self.visit(child) for child in node.body])
74
75
        orelse = [self.visit(child) for child in node.orelse]
76
        if orelse:
77
            buf.append('} else {')
78
            buf.extend(orelse)
79
            buf.append("}")
80
        else:
81
            buf.append('}')
82
83
        return '\n'.join(buf)
84
85
    def visit_While(self, node):
86
        buf = []
87
        buf.append("while ({0}) {{".format(self.visit(node.test)))
88
        buf.extend([self.visit(n) for n in node.body])
89
        buf.append("}")
90
        return '\n'.join(buf)
91
92
    def visit_Compare(self, node):
93
        left = self.visit(node.left)
94
        op = self.visit(node.ops[0])
95
        right = self.visit(node.comparators[0])
96
        return "{0} {1} {2}".format(left, op, right)
97
98
    def visit_BoolOp(self, node):
99
        op = self.visit(node.op)
100
        return op.join([self.visit(v) for v in node.values])
101
102
    def visit_BinOp(self, node):
103
        if isinstance(node.op, ast.Pow):
104
            return "std::pow({0}, {1})".format(self.visit(node.left),
105
                                               self.visit(node.right))
106
107
        return " ".join([self.visit(node.left),
108
                         self.visit(node.op),
109
                         self.visit(node.right)])
110
111
    def visit_AugAssign(self, node):
112
        target = self.visit(node.target)
113
        op = self.visit(node.op)
114
        val = self.visit(node.value)
115
        return "{0} {1}= {2};".format(target, op, val)
116