source: proto/Compiler/pablo2Streams.py @ 3432

Last change on this file since 3432 was 3432, checked in by ksherdy, 6 years ago

Added semi

File size: 11.9 KB
Line 
1# Ken Herdy
2# Sept. 19, 2012
3#
4# Quick and dirty script to automate the translation of
5# 'Pablo' Python language syntax to 'PabloS' language syntax.
6#
7import unparse, ast, sys
8
9def readfile(filename):
10    f = open(filename, 'r')
11    contents = f.read() 
12    f.close()
13    return contents
14
15def writefile(filename, code):
16    f=open(filename, 'w')
17    f.write(code)
18    f.close()
19
20class ScopeStack():
21    def __init__(self):
22        self.stack = []
23        self.depth = -1
24       
25    def openScope(self):
26        self.depth = self.depth + 1
27        self.stack.append([])
28           
29    def closeScope(self):
30        self.stack.pop()
31        self.depth = self.depth - 1
32                       
33    def append(self,item):
34        self.stack[self.depth].append(item)           
35   
36    def inScope(self,t):
37        for li in self.stack: 
38            if t in li: 
39                return True
40        return False
41   
42class Py2Pablo(unparse.Unparser):
43    def __init__(self, tree, file = sys.stdout, indent = 1):
44       
45        self.base_indent = indent       
46        self.inClassDef = False
47        self.scopeStack = ScopeStack()
48       
49        super(Py2Pablo, self).__init__(tree, file)
50             
51    def gen(self, t):
52        self.Ccode = ""
53        self._indent = self.base_indent
54        self.dispatch(t)
55        return self.Ccode         
56       
57    def enterClassDef(self):
58        self.inClassDef = True
59   
60    def leaveClassDef(self):
61        self.inClassDef = False   
62   
63    def enterFunctionDef(self):
64        self.scopeStack.openScope()
65       
66    def leaveFunctionDef(self):
67        self.scopeStack.closeScope()
68           
69    def enterScope(self):
70        self.scopeStack.openScope()
71       
72    def leaveScope(self):   
73        self.scopeStack.closeScope()
74       
75    def isFunctionParameter(self, name):
76        if isinstance(name, ast.Name) and isinstance(name.ctx, ast.Param):
77            if not self.scopeStack.inScope(name.id):
78                return True
79        return False   
80                               
81    def isLocalDecl(self, target):
82        if isinstance(target, ast.Name) and isinstance(target.ctx, ast.Store):
83            if not self.scopeStack.inScope(target.id):
84                return True
85        return False
86
87    def exitNodeNotSupported(self, t):
88        sys.stdout.write('\n\nError:  ' + ast.dump(t))
89        if (isinstance(t,ast.Expr) or isinstance(t,ast.stmt)):
90            sys.stdout.write(', Line: '   + str(t.lineno))
91            sys.stdout.write(', Column: ' + str(t.col_offset))
92        sys.stdout.write(' not supported for translation to Pablo.\n')
93        sys.exit(0)       
94         
95    def do_block(self, suite):
96        "Print '{', and increase the indentation."
97        self.scopeStack.openScope()
98        self.write("{")
99        self._indent += 1
100        for s in suite:
101            self.dispatch(s)
102        self._indent -= 1
103        self.fill("}")         
104        self.scopeStack.closeScope()
105       
106    def _Module(self, tree):
107        for stmt in tree.body:
108            self.dispatch(stmt)
109
110    def _Expr(self, tree):
111        self.fill()
112        self.dispatch(tree.value)
113        self.write(";")
114         
115    def _ClassDef(self, t):
116        self.enterClassDef() 
117        self.write("\n")
118        self.fill("struct "+t.name)
119        if t.bases:
120            self.write("(")
121            for a in t.bases:
122                self.dispatch(a)
123                self.write(", ")
124            self.write(")")
125        self.do_block(t.body)
126        self.write(";")
127        self.leaveClassDef()
128                         
129    def _FunctionDef(self, t):
130        self.enterFunctionDef()
131        self.write("\n")
132        if t.name == 'Main':
133          self.fill("graph ")
134        else:
135          self.fill("kernel " + t.name + "(")
136       
137          for name in t.args.args:
138            self.isFunctionParameter(name)       
139
140          self.dispatch(t.args)
141          self.write(") ")
142        self.do_block(t.body)
143        self.leaveFunctionDef()
144             
145    def _If(self, t):
146        self.fill("if (")
147        self.dispatch(t.test)
148        self.write(") ")
149        self.do_block(t.body)
150#       
151#   Support the translation of only 'if else'.
152#       
153#        # collapse nested ifs into equivalent elifs.
154#        while (t.orelse and len(t.orelse) == 1 and
155#               isinstance(t.orelse[0], ast.If)):
156#            t = t.orelse[0]
157#            self.fill("else if (")
158#            self.dispatch(t.test)
159#            self.write(") ")
160#            self.do_block(t.body)
161#        # final else
162        if t.orelse:
163            self.fill("else ")
164            self.do_block(t.orelse)
165             
166    def _While(self, t):
167        self.fill("while (")
168        self.dispatch(t.test)
169        self.write(") ")
170        self.do_block(t.body)
171        if t.orelse:
172            self.fill("else ")
173            self.do_block(t.orelse)
174             
175    def _Return(self, t):
176        self.fill("return")
177        if t.value:
178            print "return"
179            self.write(" ")
180            self.dispatch(t.value)
181            self.write(";")       
182       
183#    def isLocalVar(self, name):
184#        self.write(name)
185#        return (name.find('.') > 0)   
186       
187    def _Assign(self, t):       
188        self.fill()
189        for target in t.targets:
190            if self.inClassDef:
191                self.write("stream ")
192            elif self.isLocalDecl(target):
193                self.write("stream ")
194                self.scopeStack.append(target.id) 
195            self.dispatch(target)
196            if not self.inClassDef:
197                self.write(" = ")
198        if not self.inClassDef: 
199                if isinstance(t.value, ast.Num) and isinstance(t.value.n, int) and t.value.n == 0:
200                                                self.write("streams.constant<1>(0)")#self.write("pablo.Mask(1," + str(t.value.n) + ")")
201                else:     
202                        self.dispatch(t.value)
203        self.write(";")       
204       
205    def _AugAssign(self, t):
206        self.fill()
207        if self.isLocalDecl(t.target):
208            self.write("stream ")
209            self.scopeStack.append(t.target.id)
210        self.dispatch(t.target)
211        self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
212        self.dispatch(t.value)
213        self.write(";")
214
215    unop = {"Invert":"~", "USub":"-"}
216    def Cgen_UnaryOp(self, t):
217        self.write("(")
218        self.write(self.unop[t.op.__class__.__name__])
219        self.write(" ")
220        # If we're applying unary minus to a number, parenthesize the number.
221        # This is necessary: -2147483648 is different from -(2147483648) on
222        # a 32-bit machine (the first is an int, the second a long), and
223        # -7j is different from -(7j).  (The first has real part 0.0, the second
224        # has real part -0.0.)
225        if isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num):
226            self.write("(")
227            self.dispatch(t.operand)
228            self.write(")")
229        else:
230            self.dispatch(t.operand)
231        self.write(")")
232
233    binop = { "BitOr":"|", "BitXor":"^", "BitAnd":"&"}
234    def Cgen_BinOp(self, t):
235        self.write("(")
236        self.dispatch(t.left)
237        self.write(" " + self.binop[t.op.__class__.__name__] + " ")
238        self.dispatch(t.right)
239        self.write(")")
240
241    def Cgen_Compare(self, t):
242        self.exitNodeNotSupported(t)
243       
244    def Cgen_BoolOp(self, t):
245        self.exitNodeNotSupported(t)
246
247    def _Attribute(self,t):
248        self.dispatch(t.value)
249        # Special case: 3.__abs__() is a syntax error, so if t.value
250        # is an integer literal then we need to either parenthesize
251        # it or add an extra space to get 3 .__abs__().
252        if isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
253            self.write(" ")
254        self.write(".")
255        self.write(t.attr)
256
257    def _Call(self, t):
258        self.dispatch(t.func)
259        self.write("(")
260        comma = False
261        for e in t.args:
262            if comma: self.write(", ")
263            else: comma = True
264            self.dispatch(e)
265        self.write(")")
266
267    def _arguments(self, t):
268        first = True
269        # normal arguments
270        defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults
271        for a,d in zip(t.args, defaults):
272            if first:first = False
273            else: self.write(", ")
274            self.write("struct ")   #Assume struct type
275            self.write(str(a.id[0]).upper() + str(a.id[1:]) + " ")
276            self.dispatch(a),
277            if d:
278                self.write("=")
279                self.dispatch(d)
280
281    def _Str(self, tree):
282        self.write('"%s"' % tree.s)
283 
284    def _Name(self, t):
285        self.write(t.id)
286       
287    def  _Num(self, t):
288        repr_n = repr(t.n)
289        # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2.
290        if repr_n.startswith("-"):
291            self.write("(" + repr_n + ")")
292        else: self.write(repr_n)
293
294    def _Import(self, t):
295        self.exitNodeNotSupported(t)
296    def _ImportFrom(self, t):
297        self.exitNodeNotSupported(t)
298    def _Pass(self, t):
299        self.exitNodeNotSupported(t)
300    def _Break(self, t):
301        self.exitNodeNotSupported(t)
302    def _Continue(self, t):
303        self.exitNodeNotSupported(t)       
304    def _Delete(self, t):
305        self.exitNodeNotSupported(t)
306    def _Assert(self, t):
307        self.exitNodeNotSupported(t)
308    def _Exec(self, t):
309        self.exitNodeNotSupported(t)
310    def _Print(self, t):
311        self.exitNodeNotSupported(t)   
312    def _Global(self, t):
313        self.exitNodeNotSupported(t)
314    def _Yield(self, t):
315        self.exitNodeNotSupported(t)
316    def _Raise(self, t):
317        self.exitNodeNotSupported(t)
318    def _TryExcept(self, t):
319        self.exitNodeNotSupported(t)       
320    def _TryFinally(self, t):
321        self.exitNodeNotSupported(t)       
322    def _ExceptHandler(self, t):
323        self.exitNodeNotSupported(t)       
324    def _For(self, t):
325        self.exitNodeNotSupported(t)
326    def _With(self, t):
327        self.exitNodeNotSupported(t)
328    def _Repr(self, t):
329        self.exitNodeNotSupported(t)
330    def _List(self, t):
331        self.exitNodeNotSupported(t)
332    def _ListComp(self, t):
333        self.exitNodeNotSupported(t)
334    def _GeneratorExp(self, t):
335        self.exitNodeNotSupported(t)
336    def _SetComp(self, t):
337        self.exitNodeNotSupported(t)
338    def _DictComp(self, t):
339        self.exitNodeNotSupported(t)
340    def _comprehension(self, t):
341        self.exitNodeNotSupported(t)
342    def _Set(self, t):
343        self.exitNodeNotSupported(t)
344    def _Dict(self, t):
345        self.exitNodeNotSupported(t)
346    def _Tuple(self, t):
347        self.exitNodeNotSupported(t)
348    def _Subscript(self, t):
349        self.exitNodeNotSupported(t)
350    def _Ellipsis(self, t):
351        self.exitNodeNotSupported(t)
352    def _Index(self, t):
353        self.exitNodeNotSupported(t)
354    def _Slice(self, t):
355        self.exitNodeNotSupported(t)
356    def _ExtSlice(self, t):
357        self.exitNodeNotSupported(t)
358    def _keyword(self, t):
359        self.exitNodeNotSupported(t)
360    def _Lambda(self, t):
361        self.exitNodeNotSupported(t)
362    def _alias(self, t):
363        self.exitNodeNotSupported(t)
364
365import optparse
366
367def get_option_parser():
368    """Return an C{optparse.OptionParser} instance tied to this configuration."""
369   
370    parser = optparse.OptionParser(usage='python %prog <input file> [-o output_filename]',
371                    version='1.0',
372                    )
373   
374    parser.add_option('-o', '--output', 
375              dest='output_filename', 
376              type='string',
377              default='code.pablos',
378              help='default:code.pablos',
379              )
380   
381    return parser
382   
383if __name__ == '__main__':   
384   
385    option_parser = get_option_parser() 
386    options, args = option_parser.parse_args(sys.argv[1:])
387
388    # Positional arguments
389    if len(args) != 1:
390        option_parser.print_usage()
391        sys.exit()
392
393    infile = args[0]   
394    s = ast.parse(readfile(infile))
395   
396    if options.output_filename:
397        Py2Pablo(s, open(options.output_filename, "w")) 
398    else: 
399        Py2Pablo(s)
400   
Note: See TracBrowser for help on using the repository browser.