From: Sebastien Bourdeauducq Date: Fri, 28 Jun 2013 17:03:55 +0000 (+0200) Subject: pytholite: use eval instead of literal_eval X-Git-Tag: 24jan2021_ls180~2099^2~546 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b0d467d7443564fb95eca383308e17f93a70f376;p=litex.git pytholite: use eval instead of literal_eval --- diff --git a/migen/pytholite/compiler.py b/migen/pytholite/compiler.py index 708fdacf..767d86a6 100644 --- a/migen/pytholite/compiler.py +++ b/migen/pytholite/compiler.py @@ -9,7 +9,7 @@ from migen.pytholite.reg import * from migen.pytholite.expr import * from migen.pytholite import transel from migen.pytholite.io import gen_io -from migen.pytholite.fsm import * +from migen.pytholite.util import * def _is_name_used(node, name): for n in ast.walk(node): @@ -99,7 +99,7 @@ class _Compiler: if callee == transel.Register: if len(value.args) != 1: raise TypeError("Register() takes exactly 1 argument") - bits_sign = ast.literal_eval(value.args[0]) + bits_sign = eval_ast(value.args[0], self.symdict) if isinstance(node.targets[0], ast.Name): targetname = node.targets[0].id else: @@ -206,18 +206,8 @@ class _Compiler: sa.assemble(states, last_exit_states) def visit_iterator(self, node): - if isinstance(node, ast.List): - return ast.literal_eval(node) - elif isinstance(node, ast.Call) and isinstance(node.func, ast.Name): - funcname = node.func.id - args = map(ast.literal_eval, node.args) - if funcname == "range": - return range(*args) - else: - raise NotImplementedError - else: - raise NotImplementedError - + return eval_ast(node, self.symdict) + def visit_expr_statement(self, sa, node): if isinstance(node.value, ast.Yield): yvalue = node.value.value diff --git a/migen/pytholite/expr.py b/migen/pytholite/expr.py index 17f587f6..186c8854 100644 --- a/migen/pytholite/expr.py +++ b/migen/pytholite/expr.py @@ -4,6 +4,7 @@ from migen.fhdl.structure import * from migen.fhdl.structure import _Slice from migen.pytholite import transel from migen.pytholite.reg import * +from migen.pytholite.util import eval_ast class ExprCompiler: def __init__(self, symdict): @@ -36,9 +37,9 @@ class ExprCompiler: if len(node.args) != 2 and len(node.args) != 3: raise TypeError("bitslice() takes 2 or 3 arguments") val = self.visit_expr(node.args[0]) - low = ast.literal_eval(node.args[1]) + low = eval_ast(node.args[1], self.symdict) if len(node.args) == 3: - up = ast.literal_eval(node.args[2]) + up = eval_ast(node.args[2], self.symdict) else: up = low + 1 return _Slice(val, low, up) @@ -111,4 +112,3 @@ class ExprCompiler: def visit_expr_subscript(self, node): raise NotImplementedError - diff --git a/migen/pytholite/fsm.py b/migen/pytholite/fsm.py deleted file mode 100644 index 4764ff5b..00000000 --- a/migen/pytholite/fsm.py +++ /dev/null @@ -1,25 +0,0 @@ -from migen.genlib.fsm import FSM, NextState - -def id_next_state(l): - return NextState(id(l)) - -# entry state is first state returned -class StateAssembler: - def __init__(self): - self.states = [] - self.exit_states = [] - - def assemble(self, n_states, n_exit_states): - self.states += n_states - for exit_state in self.exit_states: - exit_state.insert(0, id_next_state(n_states[0])) - self.exit_states = n_exit_states - - def ret(self): - return self.states, self.exit_states - -def implement_fsm(states): - fsm = FSM() - for state in states: - fsm.act(id(state), state) - return fsm diff --git a/migen/pytholite/io.py b/migen/pytholite/io.py index 2efdc77f..01f168af 100644 --- a/migen/pytholite/io.py +++ b/migen/pytholite/io.py @@ -6,7 +6,7 @@ from migen.flow.actor import Source, Sink from migen.flow.transactions import * from migen.bus import wishbone from migen.bus.transactions import * -from migen.pytholite.fsm import * +from migen.pytholite.util import * from migen.pytholite.expr import ExprCompiler class _TokenPullExprCompiler(ExprCompiler): @@ -25,15 +25,15 @@ class _TokenPullExprCompiler(ExprCompiler): if not isinstance(node.slice, ast.Index): raise NotImplementedError - field = ast.literal_eval(node.slice.value) + field = eval_ast(node.slice.value, self.symdict) signal = getattr(self.ep.payload, field) return signal def _gen_df_io(compiler, modelname, to_model, from_model): - epname = ast.literal_eval(to_model["endpoint"]) + epname = eval_ast(to_model["endpoint"], compiler.symdict) values = to_model["value"] - idle_wait = ast.literal_eval(to_model["idle_wait"]) + idle_wait = eval_ast(to_model["idle_wait"], compiler.symdict) ep = getattr(compiler.ioo, epname) if idle_wait: state = [compiler.ioo.busy.eq(0)] @@ -62,7 +62,7 @@ def _gen_df_io(compiler, modelname, to_model, from_model): if not isinstance(values, ast.Dict): raise NotImplementedError for akey, value in zip(values.keys, values.values): - key = ast.literal_eval(akey) + key = eval_ast(akey, compiler.symdict) signal = getattr(ep.payload, key) state.append(signal.eq(compiler.ec.visit_expr(value))) state += [ @@ -136,7 +136,7 @@ def _gen_memory_io(compiler, modelname, model, to_model, from_model, port): return [s1, s2], [s2] def _gen_bus_io(compiler, modelname, model, to_model, from_model): - busname = ast.literal_eval(to_model["busname"]) + busname = eval_ast(to_model["busname"], compiler.symdict) if busname is None: buses = compiler.ioo.get_buses() if len(buses) != 1: @@ -183,8 +183,8 @@ def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model): if model == Token: desc = [ "endpoint", - ("value", ast.Name("None", ast.Load())), - ("idle_wait", ast.Name("False", ast.Load())) + ("value", ast.Name("None", ast.Load(), lineno=0, col_offset=0)), + ("idle_wait", ast.Name("False", ast.Load(), lineno=0, col_offset=0)) ] args = _decode_args(desc, to_model, to_model_kw) return _gen_df_io(compiler, modelname, args, from_model) @@ -192,8 +192,8 @@ def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model): desc = [ "address", ("data", ast.Num(0)), - ("sel", ast.Name("None", ast.Load())), - ("busname", ast.Name("None", ast.Load())) + ("sel", ast.Name("None", ast.Load(), lineno=0, col_offset=0)), + ("busname", ast.Name("None", ast.Load(), lineno=0, col_offset=0)) ] args = _decode_args(desc, to_model, to_model_kw) return _gen_bus_io(compiler, modelname, model, args, from_model) diff --git a/migen/pytholite/util.py b/migen/pytholite/util.py new file mode 100644 index 00000000..966e31c6 --- /dev/null +++ b/migen/pytholite/util.py @@ -0,0 +1,33 @@ +import ast + +from migen.genlib.fsm import FSM, NextState + +def id_next_state(l): + return NextState(id(l)) + +# entry state is first state returned +class StateAssembler: + def __init__(self): + self.states = [] + self.exit_states = [] + + def assemble(self, n_states, n_exit_states): + self.states += n_states + for exit_state in self.exit_states: + exit_state.insert(0, id_next_state(n_states[0])) + self.exit_states = n_exit_states + + def ret(self): + return self.states, self.exit_states + +def implement_fsm(states): + fsm = FSM() + for state in states: + fsm.act(id(state), state) + return fsm + +def eval_ast(expr, symdict): + if not isinstance(expr, ast.Expression): + expr = ast.Expression(expr) + code = compile(expr, "", "eval") + return eval(code, symdict)