forked from M-Labs/artiq
1
0
Fork 0

compiler: share value_to_ast

This commit is contained in:
Sebastien Bourdeauducq 2014-06-21 00:19:40 +02:00
parent 5b0fd50dbe
commit 94ff2e2ddc
2 changed files with 24 additions and 22 deletions

View File

@ -1,31 +1,15 @@
from collections import namedtuple, defaultdict from collections import namedtuple, defaultdict
import inspect, textwrap, ast import inspect, textwrap, ast
from artiq.compiler.tools import eval_ast from artiq.compiler.tools import eval_ast, value_to_ast
from artiq.language import experiment, units from artiq.language import experiment, units
def _value_to_ast(value):
if isinstance(value, int):
return ast.Num(value)
elif isinstance(value, str):
return ast.Str(value)
else:
for kg in experiment.kernel_globals:
if value is getattr(experiment, kg):
return ast.Name(kg, ast.Load())
if isinstance(value, units.Quantity):
return ast.Call(
func=ast.Name("Quantity", ast.Load()),
args=[ast.Num(value.amount), ast.Name("base_"+value.unit.name+"_unit", ast.Load())],
keywords=[], starargs=None, kwargs=None)
return None
def _replace_global(obj, ref): def _replace_global(obj, ref):
try: try:
value = eval_ast(ref, inspect.getmodule(obj).__dict__) value = eval_ast(ref, inspect.getmodule(obj).__dict__)
except: except:
return None return None
return _value_to_ast(value) return value_to_ast(value)
_UserVariable = namedtuple("_UserVariable", "name") _UserVariable = namedtuple("_UserVariable", "name")
@ -85,7 +69,7 @@ class _ReferenceManager:
if store: if store:
raise NotImplementedError("Cannot turn object into user variable") raise NotImplementedError("Cannot turn object into user variable")
else: else:
a = _value_to_ast(ival) a = value_to_ast(ival)
if a is None: if a is None:
raise NotImplementedError("Cannot represent inlined value") raise NotImplementedError("Cannot represent inlined value")
return a return a
@ -99,7 +83,7 @@ class _ReferenceManager:
if _is_in_attr_list(value, ref.attr, "kernel_attr_ro"): if _is_in_attr_list(value, ref.attr, "kernel_attr_ro"):
if isinstance(ref.ctx, ast.Store): if isinstance(ref.ctx, ast.Store):
raise TypeError("Attempted to assign to read-only kernel attribute") raise TypeError("Attempted to assign to read-only kernel attribute")
a = _value_to_ast(getattr(value, ref.attr)) a = value_to_ast(getattr(value, ref.attr))
if a is None: if a is None:
raise NotImplementedError("Cannot represent read-only kernel attribute") raise NotImplementedError("Cannot represent read-only kernel attribute")
return a return a
@ -113,7 +97,7 @@ class _ReferenceManager:
iname = self.new_name(ref.attr) iname = self.new_name(ref.attr)
ival = _UserVariable(iname) ival = _UserVariable(iname)
self.to_inlined[key] = _UserVariable(iname) self.to_inlined[key] = _UserVariable(iname)
a = _value_to_ast(getattr(value, ref.attr)) a = value_to_ast(getattr(value, ref.attr))
if a is None: if a is None:
raise NotImplementedError("Cannot represent initial value of kernel attribute") raise NotImplementedError("Cannot represent initial value of kernel attribute")
self.kernel_attr_init.append(ast.Assign( self.kernel_attr_init.append(ast.Assign(
@ -226,7 +210,7 @@ def _initialize_function_params(funcdef, k_args, k_kwargs, rm):
rm.set(obj, funcname, arg_name, arg_value) rm.set(obj, funcname, arg_name, arg_value)
else: else:
target = rm.get(obj, funcname, ast.Name(arg_name, ast.Store())) target = rm.get(obj, funcname, ast.Name(arg_name, ast.Store()))
value = _value_to_ast(arg_value) value = value_to_ast(arg_value)
param_init.append(ast.Assign(targets=[target], value=value)) param_init.append(ast.Assign(targets=[target], value=value))
return param_init return param_init

View File

@ -1,7 +1,25 @@
import ast import ast
from artiq.language import experiment, units
def eval_ast(expr, symdict=dict()): def eval_ast(expr, symdict=dict()):
if not isinstance(expr, ast.Expression): if not isinstance(expr, ast.Expression):
expr = ast.Expression(expr) expr = ast.Expression(expr)
code = compile(expr, "<ast>", "eval") code = compile(expr, "<ast>", "eval")
return eval(code, symdict) return eval(code, symdict)
def value_to_ast(value):
if isinstance(value, int):
return ast.Num(value)
elif isinstance(value, str):
return ast.Str(value)
else:
for kg in experiment.kernel_globals:
if value is getattr(experiment, kg):
return ast.Name(kg, ast.Load())
if isinstance(value, units.Quantity):
return ast.Call(
func=ast.Name("Quantity", ast.Load()),
args=[ast.Num(value.amount), ast.Name("base_"+value.unit.name+"_unit", ast.Load())],
keywords=[], starargs=None, kwargs=None)
return None