artiq/examples/transform.py

57 lines
1.5 KiB
Python
Raw Normal View History

2014-05-25 05:06:48 +08:00
import inspect, textwrap, ast
from artiq import units, unparse
_now = "_ARTIQ_now"
class _RequestTransformer(ast.NodeTransformer):
def __init__(self, target_globals):
self.target_globals = target_globals
def visit_FunctionDef(self, node):
self.generic_visit(node)
node.body.insert(0, ast.copy_location(
ast.Assign(targets=[ast.Name(id=_now, ctx=ast.Store())],
value=ast.Num(n=0)), node))
node.body.append(ast.copy_location(
ast.Return(value=ast.Name(id=_now, ctx=ast.Store())),
node))
return node
def visit_Return(self, node):
raise TypeError("Kernels cannot return values")
def visit_Call(self, node):
self.generic_visit(node)
name = node.func.id
if name == "delay":
if len(node.args) != 1:
raise TypeError("delay() takes 1 positional argument but {} were given".format(len(node.args)))
return ast.copy_location(ast.AugAssign(
target=ast.Name(id=_now, ctx=ast.Store()),
op=ast.Add(), value=node.args[0]), node)
return node
def visit_Name(self, node):
if not isinstance(node.ctx, ast.Load):
return node
try:
obj = self.target_globals[node.id]
except KeyError:
return node
if isinstance(obj, units.Quantity):
return ast.Num(obj.amount)
else:
return node
def request_transform(target_ast, target_globals):
transformer = _RequestTransformer(target_globals)
transformer.visit(target_ast)
if __name__ == "__main__":
import threads_test
kernel = threads_test.threads_test
a = ast.parse(textwrap.dedent(inspect.getsource(kernel)))
request_transform(a, kernel.__globals__)
unparse.Unparser(a)