pytholite: use eval instead of literal_eval
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 28 Jun 2013 17:03:55 +0000 (19:03 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 28 Jun 2013 17:03:55 +0000 (19:03 +0200)
migen/pytholite/compiler.py
migen/pytholite/expr.py
migen/pytholite/fsm.py [deleted file]
migen/pytholite/io.py
migen/pytholite/util.py [new file with mode: 0644]

index 708fdacf8ba60d0c9e4934d01eaa3adb5ad95ccf..767d86a662eaf5338240aadfedd13a993bb81f82 100644 (file)
@@ -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
index 17f587f6dedb88de8d0d8472f11d1bfb16e977dc..186c8854f4f13461a558c42c6e701d0a76c82b7a 100644 (file)
@@ -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 (file)
index 4764ff5..0000000
+++ /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
index 2efdc77f22be9a177dd3b37b6c3355f5e6e46b32..01f168afedf00133638974b379fd780d09edbc6a 100644 (file)
@@ -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 (file)
index 0000000..966e31c
--- /dev/null
@@ -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, "<ast>", "eval")
+       return eval(code, symdict)