Skip to content

Commit

Permalink
pytholite: use eval instead of literal_eval
Browse files Browse the repository at this point in the history
Sebastien Bourdeauducq committed Jun 28, 2013
1 parent ecc4062 commit b0d467d
Showing 4 changed files with 25 additions and 27 deletions.
18 changes: 4 additions & 14 deletions migen/pytholite/compiler.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
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 @@ def visit_assign_special(self, sa, node, statements):
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 @@ def visit_for(self, sa, node):
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
6 changes: 3 additions & 3 deletions migen/pytholite/expr.py
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
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 @@ def visit_expr_call(self, node):
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 @@ def visit_expr_attribute(self, node):

def visit_expr_subscript(self, node):
raise NotImplementedError

20 changes: 10 additions & 10 deletions migen/pytholite/io.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
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 @@ def visit_expr_subscript(self, node):

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,17 +183,17 @@ 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)
elif model == TRead or model == TWrite:
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)
8 changes: 8 additions & 0 deletions migen/pytholite/fsm.py → migen/pytholite/util.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ast

from migen.genlib.fsm import FSM, NextState

def id_next_state(l):
@@ -23,3 +25,9 @@ def implement_fsm(states):
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)

0 comments on commit b0d467d

Please sign in to comment.