forked from M-Labs/artiq
Add support for Break and Continue.
This commit is contained in:
parent
55551714fa
commit
4b4805265d
|
@ -284,9 +284,7 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
|
|
||||||
# stmt
|
# stmt
|
||||||
visit_Assert = visit_unsupported
|
visit_Assert = visit_unsupported
|
||||||
visit_Break = visit_unsupported
|
|
||||||
visit_ClassDef = visit_unsupported
|
visit_ClassDef = visit_unsupported
|
||||||
visit_Continue = visit_unsupported
|
|
||||||
visit_Delete = visit_unsupported
|
visit_Delete = visit_unsupported
|
||||||
visit_Import = visit_unsupported
|
visit_Import = visit_unsupported
|
||||||
visit_ImportFrom = visit_unsupported
|
visit_ImportFrom = visit_unsupported
|
||||||
|
@ -298,8 +296,8 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
class Inferencer(algorithm.Visitor):
|
class Inferencer(algorithm.Visitor):
|
||||||
def __init__(self, engine):
|
def __init__(self, engine):
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
# currently visited function, for Return inference
|
self.function = None # currently visited function, for Return inference
|
||||||
self.function = None
|
self.in_loop = False
|
||||||
|
|
||||||
def _unify(self, typea, typeb, loca, locb, makenotes=None):
|
def _unify(self, typea, typeb, loca, locb, makenotes=None):
|
||||||
try:
|
try:
|
||||||
|
@ -385,11 +383,6 @@ class Inferencer(algorithm.Visitor):
|
||||||
node.operand.loc)
|
node.operand.loc)
|
||||||
self.engine.process(diag)
|
self.engine.process(diag)
|
||||||
|
|
||||||
def visit_FunctionDefT(self, node):
|
|
||||||
old_function, self.function = self.function, node
|
|
||||||
node = self.generic_visit(node)
|
|
||||||
self.function = old_function
|
|
||||||
|
|
||||||
def visit_Assign(self, node):
|
def visit_Assign(self, node):
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
if len(node.targets) > 1:
|
if len(node.targets) > 1:
|
||||||
|
@ -405,12 +398,47 @@ class Inferencer(algorithm.Visitor):
|
||||||
node.target.loc, node.value.loc)
|
node.target.loc, node.value.loc)
|
||||||
|
|
||||||
def visit_For(self, node):
|
def visit_For(self, node):
|
||||||
|
old_in_loop, self.in_loop = self.in_loop, True
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
|
self.in_loop = old_in_loop
|
||||||
# TODO: support more than just lists
|
# TODO: support more than just lists
|
||||||
self._unify(builtins.TList(node.target.type), node.iter.type,
|
self._unify(builtins.TList(node.target.type), node.iter.type,
|
||||||
node.target.loc, node.iter.loc)
|
node.target.loc, node.iter.loc)
|
||||||
|
|
||||||
|
def visit_While(self, node):
|
||||||
|
old_in_loop, self.in_loop = self.in_loop, True
|
||||||
|
self.generic_visit(node)
|
||||||
|
self.in_loop = old_in_loop
|
||||||
|
|
||||||
|
def visit_Break(self, node):
|
||||||
|
if not self.in_loop:
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"break statement outside of a loop", {},
|
||||||
|
node.keyword_loc)
|
||||||
|
self.engine.process(diag)
|
||||||
|
|
||||||
|
def visit_Continue(self, node):
|
||||||
|
if not self.in_loop:
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"continue statement outside of a loop", {},
|
||||||
|
node.keyword_loc)
|
||||||
|
self.engine.process(diag)
|
||||||
|
|
||||||
|
def visit_FunctionDefT(self, node):
|
||||||
|
old_function, self.function = self.function, node
|
||||||
|
old_in_loop, self.in_loop = self.in_loop, False
|
||||||
|
self.generic_visit(node)
|
||||||
|
self.function = old_function
|
||||||
|
self.in_loop = old_in_loop
|
||||||
|
|
||||||
def visit_Return(self, node):
|
def visit_Return(self, node):
|
||||||
|
if not self.function:
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"return statement outside of a function", {},
|
||||||
|
node.keyword_loc)
|
||||||
|
self.engine.process(diag)
|
||||||
|
return
|
||||||
|
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
def makenotes(printer, typea, typeb, loca, locb):
|
def makenotes(printer, typea, typeb, loca, locb):
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# RUN: %python -m artiq.py2llvm.typing +diag %s >%t
|
||||||
|
# RUN: OutputCheck %s --file-to-check=%t
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: return statement outside of a function
|
||||||
|
return
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: break statement outside of a loop
|
||||||
|
break
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: continue statement outside of a loop
|
||||||
|
continue
|
||||||
|
|
||||||
|
while True:
|
||||||
|
def f():
|
||||||
|
# CHECK-L: ${LINE:+1}: error: break statement outside of a loop
|
||||||
|
break
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: continue statement outside of a loop
|
||||||
|
continue
|
Loading…
Reference in New Issue