Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 6 commits
  • 1 file changed
  • 0 commit comments
  • 1 contributor
Showing with 47 additions and 6 deletions.
  1. +47 −6 migen/pytholite/compiler.py
View
53 migen/pytholite/compiler.py
@@ -111,10 +111,51 @@ def visit_statement(self, statement):
states.append(test_state)
states += states_t + states_f
exit_states += exit_states_t + exit_states_f
+ elif isinstance(statement, ast.While):
+ test = self.visit_expr(statement.test)
+ states_b, exit_states_b = self.visit_block(statement.body)
+
+ test_state = [If(test, _AbstractNextState(states_b[0]))]
+ for exit_state in exit_states_b:
+ exit_state.insert(0, _AbstractNextState(test_state))
+
+ exit_states.append(test_state)
+ states += states_b
+ states.append(test_state)
+ elif isinstance(statement, ast.For):
+ if not isinstance(statement.target, ast.Name):
+ raise NotImplementedError
+ target = statement.target.id
+ if target in self.symdict:
+ raise NotImplementedError("For loop target must use an available name")
+ it = self.visit_iterator(statement.iter)
+ last_exit_states = []
+ for iteration in it:
+ self.symdict[target] = iteration
+ states_b, exit_states_b = self.visit_block(statement.body)
+ for exit_state in last_exit_states:
+ exit_state.insert(0, _AbstractNextState(states_b[0]))
+ last_exit_states = exit_states_b
+ states += states_b
+ exit_states += last_exit_states
+ del self.symdict[target]
else:
raise NotImplementedError
return states, 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
+
def visit_assign(self, node):
if isinstance(node.targets[0], ast.Name):
self.targetname = node.targets[0].id
@@ -224,9 +265,15 @@ def visit_expr_compare(self, node):
return r
def visit_expr_name(self, node):
+ if node.id == "True":
+ return Constant(1)
+ if node.id == "False":
+ return Constant(0)
r = self.symdict[node.id]
if isinstance(r, _Register):
r = r.storage
+ if isinstance(r, int):
+ r = Constant(r)
return r
def visit_expr_num(self, node):
@@ -266,14 +313,8 @@ def make_pytholite(func):
symdict = func.__globals__.copy()
registers = []
- print("ast:")
- print(ast.dump(tree))
-
states = _Compiler(symdict, registers).visit_top(tree)
- print("compilation result:")
- print(states)
-
regf = Fragment()
for register in registers:
register.finalize()

No commit comments for this range

Something went wrong with that request. Please try again.