artiq/artiq/transforms/lower_time.py

65 lines
2.1 KiB
Python
Raw Normal View History

2014-11-22 07:55:39 +08:00
"""
2015-07-02 04:22:53 +08:00
This transform implements time management functions (delay_mu/now_mu/at_mu)
using an accumulator 'now' and simple replacement rules:
2014-09-05 12:03:22 +08:00
2015-07-02 04:22:53 +08:00
delay_mu(t) -> now += t
now_mu() -> now
at_mu(t) -> now = t
2015-07-02 04:22:53 +08:00
The function delay(), that uses seconds, must be lowered to delay_mu() before
invoking this transform.
The accumulator is initialized to an int64 value at the beginning of the
output function.
"""
import ast
2014-07-16 01:22:11 +08:00
class _TimeLowerer(ast.NodeTransformer):
2014-09-05 12:03:22 +08:00
def visit_Call(self, node):
2015-07-02 04:22:53 +08:00
if node.func.id == "now_mu":
2014-09-05 12:03:22 +08:00
return ast.copy_location(ast.Name("now", ast.Load()), node)
else:
self.generic_visit(node)
return node
2014-09-05 12:03:22 +08:00
def visit_Expr(self, node):
r = node
if isinstance(node.value, ast.Call):
2014-09-05 12:03:22 +08:00
funcname = node.value.func.id
2015-07-02 04:22:53 +08:00
if funcname == "delay_mu":
r = ast.copy_location(
2014-09-05 12:03:22 +08:00
ast.AugAssign(target=ast.Name("now", ast.Store()),
op=ast.Add(),
value=node.value.args[0]),
2014-09-05 12:03:22 +08:00
node)
2015-07-02 04:22:53 +08:00
elif funcname == "at_mu":
r = ast.copy_location(
2014-09-05 12:03:22 +08:00
ast.Assign(targets=[ast.Name("now", ast.Store())],
value=node.value.args[0]),
2014-09-05 12:03:22 +08:00
node)
self.generic_visit(r)
return r
2014-09-05 12:03:22 +08:00
2014-07-16 01:22:11 +08:00
def lower_time(func_def):
_TimeLowerer().visit(func_def)
call_init = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("now_init")],
keywords=[], starargs=None, kwargs=None)
stmt_init = ast.Assign(targets=[ast.Name("now", ast.Store())],
value=call_init)
call_save = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("now_save"), ast.Name("now", ast.Load())],
keywords=[], starargs=None, kwargs=None)
stmt_save = ast.Expr(call_save)
func_def.body = [
stmt_init,
ast.Try(body=func_def.body,
handlers=[],
orelse=[],
finalbody=[stmt_save])
]