forked from M-Labs/artiq
compiler: share value_to_ast
This commit is contained in:
parent
5b0fd50dbe
commit
94ff2e2ddc
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue