#!/usr/bin/env python """ 6D programming language Copyright (C) 2011 Danny Milosavljevic This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ import ast """ X <_ast.Index object at 0x7f36440374d0> Load <_ast.Load object at 0x7f36440a0b10> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_attributes', '_fields'] X <_ast.Subscript object at 0x7f3644037610> X <_ast.Index object at 0x7f3644037690> Load <_ast.Load object at 0x7f36440a0b10> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_attributes', '_fields'] X None """ class CXXPrinter(ast.NodeVisitor): def visitl(self, sep, list): return sep.join([self.visit(item) for item in list]) def visitb(self, list): return "\n".join(["%s;" % (self.visit(item), ) for item in list]) def visit_Import(self, node): return "" # TODO def visit_ImportFrom(self, node): return "" # TODO def visit_TryExcept(self, node): # body, handlers return self.visitb(node.body) # TODO except block (handlers) def visit_Assign(self, node): assert len(node.targets) == 1 target = node.targets[0] return "%s = %s" % (self.visit(target), self.visit(node.value)) def visit_Expr(self, node): return self.visit(node.value) def visit_Str(self, node): if len(node.s) > 1: return ("%r" % (node.s, )).replace("'", '"') # FIXME C++ escaping else: return ("%r" % (node.s, )) def visit_FunctionDef(self, node): #args', 'defaults', 'kwarg', 'vararg argnames = node.args.args # TODO argtypes return "static NodeT %s(%s) {\n%s\n}\n" % (self.visit(ast.Name(node.name, {})), self.visitl(",", argnames), self.visitb(node.body)) def visit_If(self, node): # test, body, orelse if node.orelse: return "if(%s) {\n%s\n} else {\n%s\n}" % (self.visit(node.test), self.visitb(node.body), self.visitb(node.orelse)) else: return "if(%s) {\n%s\n}" % (self.visit(node.test), self.visitb(node.body)) def visit_For(self, node): assert node.orelse == [] #F ['body', 'col_offset', 'iter', 'lineno', 'orelse', 'target'] return "for(%s in %s) {\n%s}\n" % (self.visit(node.target), self.visit(node.iter), self.visitb(node.body)) def visit_Tuple(self, node): # col_offset', 'ctx', 'elts', 'lineno # name, name return (",".join([self.visit(item) for item in node.elts])) def visit_Store(self, node): pass def visit_Return(self, node): return "return %s" % (self.visit(node.value), ) def visit_Name(self, node): return node.id def visit_BoolOp(self, node): return "(%s)" % (self.visitl(self.visit(node.op), node.values),) def visit_And(self, node): return " && " def visit_Or(self, node): return " || " def visit_Compare(self, node): #print "COMPARE", dir(node), node.comparators, node.left, node.ops #comparators', 'left', 'lineno', 'ops assert len(node.comparators) == 1 assert len(node.ops) == 1 comparator = node.comparators[0] op = node.ops[0] return "%s%s%s" % (self.visit(node.left), self.visit(op), self.visit(comparator)) def visit_Lt(self, node): return " < " def visit_LtE(self, node): return " <= " def visit_Gt(self, node): return " > " def visit_GtE(self, node): return " >= " def visit_List(self, node): return "[%s]" % (self.visitl(",", node.elts),) def visit_Num(self, node): return str(node.n) # TODO C++ def visit_IfExp(self, node): #body', 'col_offset', 'lineno', 'orelse', 'test return "(%s) ? (%s) : (%s)" % (self.visit(node.test), self.visit(node.body), self.visit(node.orelse)) def visit_Assert(self, node): # TODO msg return "assert(%s)" % (self.visit(node.test), ) def visit_Call(self, node): assert node.starargs is None assert node.keywords == [] assert node.kwargs is None #args', 'col_offset', 'func', 'keywords', 'kwargs', 'lineno', 'starargs return "%s(%s)" % (self.visit(node.func), self.visitl(",", node.args)) def visit_UnaryOp(self, node): #print "UNARY OP", dir(node), node.lineno, node.op, node.operand return "%s%s" % (self.visit(node.op), self.visit(node.operand)) def visit_Not(self, node): return " ! " def visit_Eq(self, node): return " == " def visit_NotEq(self, node): return " != " def visit_Break(self, node): return "break;" def visit_Load(self, node): print "Load", node,dir(node) def visit_Attribute(self, node): #print "ATT", node.value, node.attr #return "%s.%s" % (self.visit(node.value), self.visit(node.attr)) return "%s.%s" % (self.visit(node.value), self.visit(ast.Name(node.attr, ""))) def visit_While(self, node): assert node.orelse == [] return "while(%s) {\n%s\n}\n" % (self.visit(node.test), self.visitb(node.body)) def visit_Add(self, node): return " + " def visit_Is(self, node): return " == " # FIXME def visit_IsNot(self, node): return " != " # FIXME def visit_AugAssign(self, node): #print "AUG", dir(node) #op', 'target', 'value #print node.op, node.target, node.value assert isinstance(node.op, ast.Add) return "%s += %s" % (self.visit(node.target), self.visit(node.value)) def visit_Yield(self, node): # TODO nicer? return "result.push_back(/*yield*/%s);" % (self.visit(node.value), ) def visit_In(self, node): return "??? FIXME" def visit_Subscript(self, node): print node.lineno #assert isinstance(node.slice, ast.Index) try: ns = self.visit_Num(node.slice.value) # Num return "%s[%s]" % (self.visit(node.value), ns) except: return "??? FIXME" #def visit_Index(self, node): # print "INDEX", node, dir(node) def visit_None(self, node): return "NULL" def visit_Lambda(self, node): print "LAMBDA", dir(node), node.args, node.body return "???" def generic_visit(self, node): if isinstance(node, ast.Str): return self.visit_Str(node) elif isinstance(node, ast.Name): return self.visit_Name(node) elif isinstance(node, ast.Tuple): return self.visit_Tuple(node) elif isinstance(node, ast.List): return self.visit_List(node) elif isinstance(node, ast.Num): return self.visit_Num(node) elif node is None: return self.visit_None(node) else: print "X", node, type(node) return ast.NodeVisitor.generic_visit(self, node) pass def unitTestP(x): return isinstance(x, ast.If) # FIXME more detailed #m = ast.parse(open("scanner.py","r").read(), "scanner.py") m = ast.parse(open("shuntingyard.py","r").read(), "scanner.py") x = CXXPrinter().visitb([x for x in m.body if not unitTestP(x)]) print x