#!/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