This commit is contained in:
Paul Tagliamonte 2012-12-22 15:49:03 -05:00
parent 7b68b34f53
commit 5da72224f4

View File

@ -4,6 +4,8 @@ import ast
from hy.lang.expression import HYExpression from hy.lang.expression import HYExpression
from hy.lang.number import HYNumber from hy.lang.number import HYNumber
from hy.lang.string import HYString from hy.lang.string import HYString
from hy.lang.symbol import HYSymbol
from hy.lang.list import HYList
from hy.lang.builtins import builtins from hy.lang.builtins import builtins
from hy.lang.natives import natives from hy.lang.natives import natives
@ -30,24 +32,16 @@ def _ast_binop(node, children):
# XXX: Add these folks in # XXX: Add these folks in
inv = node.get_invocation() inv = node.get_invocation()
ops = { ops = { "+": ast.Add, "/": ast.Div, "*": ast.Mult, "-": ast.Sub }
"+": ast.Add,
"/": ast.Div,
"*": ast.Mult,
"-": ast.Sub
}
op = ops[inv['function']] op = ops[inv['function']]
left = children.pop(0) left = children.pop(0)
calc = None calc = None
for child in children: for child in children:
calc = ast.BinOp(left=left, op=op(), right=child) calc = ast.BinOp(left=left, op=op(), right=child)
left = calc left = calc
return calc return calc
special_cases = { special_cases = {
"print": _ast_print, "print": _ast_print,
"+": _ast_binop, "+": _ast_binop,
@ -62,31 +56,93 @@ class AST27Converter(object):
self.table = { self.table = {
HYString: self.render_string, HYString: self.render_string,
HYExpression: self.render_expression, HYExpression: self.render_expression,
HYNumber: self.render_number HYNumber: self.render_number,
HYSymbol: self.render_symbol,
}
self.native_cases = {
"defn": self._defn,
"def": self._def,
} }
def _def(self, node):
inv = node.get_invocation()
args = inv['args']
name = args.pop(0)
# assert args == 1
blob = self.render(args[0])
ret = ast.Assign(
targets=[
ast.Name(id=str(name), ctx=ast.Store())
],
value=blob)
return ret
def _defn(self, node):
inv = node.get_invocation()
args = inv['args']
name = args.pop(0)
sig = args.pop(0)
doc = None
if type(args[0]) == HYString:
doc = args.pop(0)
# verify child count...
c = []
for child in args:
c.append(self.render(child))
ret = ast.FunctionDef(
name=str(name),
args=ast.arguments(
args=[ast.Name(id=str(x), ctx=ast.Param()) for x in sig],
vararg=None,
kwarg=None,
defaults=[]
),
body=[ast.Return(value=c[0])],
decorator_list=[]
)
return ret
def render_string(self, node): def render_string(self, node):
return ast.Str(s=node) return ast.Str(s=str(node))
def render_symbol(self, node):
# the only time we have a bare symbol is if we
# deref it.
return ast.Name(id=str(node), ctx=ast.Load())
def render_number(self, node): def render_number(self, node):
return ast.Num(n=node) return ast.Num(n=node)
def render_expression(self, node): def render_expression(self, node):
inv = node.get_invocation()
if inv['function'] in self.native_cases:
return self.native_cases[inv['function']](node)
c = [] c = []
for child in node.get_children(): for child in node.get_children():
c.append(self.render(child)) c.append(self.render(child))
inv = node.get_invocation()
if inv['function'] in special_cases: if inv['function'] in special_cases:
return special_cases[inv['function']](node, c) return special_cases[inv['function']](node, c)
ret = value=ast.Call(
func=ast.Name(id=str(inv['function']), ctx=ast.Load()),
args=c,
keywords=[],
starargs=None,
kwargs=None
)
return ret return ret
def render(self, tree): def render(self, tree):
t = type(tree) t = type(tree)
handler = self.table[t] handler = self.table[t]
ret = handler(tree) ret = handler(tree)
return ret return ret
@ -97,5 +153,4 @@ def forge_ast(name, forest):
for tree in forest: for tree in forest:
statements.append(conv.render(tree)) statements.append(conv.render(tree))
print [ast.dump(x) for x in statements]
return ast.fix_missing_locations(ast.Module(body=statements)) return ast.fix_missing_locations(ast.Module(body=statements))