parent
fa2e096aa0
commit
a816e1c1fa
|
@ -300,6 +300,12 @@ class InvalidArguments(InterpreterException):
|
||||||
class SubdirDoneRequest(BaseException):
|
class SubdirDoneRequest(BaseException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class ContinueRequest(BaseException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class BreakRequest(BaseException):
|
||||||
|
pass
|
||||||
|
|
||||||
class InterpreterObject:
|
class InterpreterObject:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.methods = {}
|
self.methods = {}
|
||||||
|
@ -453,6 +459,10 @@ class InterpreterBase:
|
||||||
return self.evaluate_indexing(cur)
|
return self.evaluate_indexing(cur)
|
||||||
elif isinstance(cur, mparser.TernaryNode):
|
elif isinstance(cur, mparser.TernaryNode):
|
||||||
return self.evaluate_ternary(cur)
|
return self.evaluate_ternary(cur)
|
||||||
|
elif isinstance(cur, mparser.ContinueNode):
|
||||||
|
raise ContinueRequest()
|
||||||
|
elif isinstance(cur, mparser.BreakNode):
|
||||||
|
raise BreakRequest()
|
||||||
elif self.is_elementary_type(cur):
|
elif self.is_elementary_type(cur):
|
||||||
return cur
|
return cur
|
||||||
else:
|
else:
|
||||||
|
@ -641,7 +651,12 @@ The result of this is undefined and will become a hard error in a future Meson r
|
||||||
return items
|
return items
|
||||||
for item in items:
|
for item in items:
|
||||||
self.set_variable(varname, item)
|
self.set_variable(varname, item)
|
||||||
self.evaluate_codeblock(node.block)
|
try:
|
||||||
|
self.evaluate_codeblock(node.block)
|
||||||
|
except ContinueRequest:
|
||||||
|
continue
|
||||||
|
except BreakRequest:
|
||||||
|
break
|
||||||
elif isinstance(items, dict):
|
elif isinstance(items, dict):
|
||||||
if len(node.varnames) != 2:
|
if len(node.varnames) != 2:
|
||||||
raise InvalidArguments('Foreach on dict unpacks key and value')
|
raise InvalidArguments('Foreach on dict unpacks key and value')
|
||||||
|
@ -650,7 +665,12 @@ The result of this is undefined and will become a hard error in a future Meson r
|
||||||
for key, value in items.items():
|
for key, value in items.items():
|
||||||
self.set_variable(node.varnames[0].value, key)
|
self.set_variable(node.varnames[0].value, key)
|
||||||
self.set_variable(node.varnames[1].value, value)
|
self.set_variable(node.varnames[1].value, value)
|
||||||
self.evaluate_codeblock(node.block)
|
try:
|
||||||
|
self.evaluate_codeblock(node.block)
|
||||||
|
except ContinueRequest:
|
||||||
|
continue
|
||||||
|
except BreakRequest:
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
raise InvalidArguments('Items of foreach loop must be an array or a dict')
|
raise InvalidArguments('Items of foreach loop must be an array or a dict')
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,8 @@ class Lexer:
|
||||||
self.code = code
|
self.code = code
|
||||||
self.keywords = {'true', 'false', 'if', 'else', 'elif',
|
self.keywords = {'true', 'false', 'if', 'else', 'elif',
|
||||||
'endif', 'and', 'or', 'not', 'foreach', 'endforeach',
|
'endif', 'and', 'or', 'not', 'foreach', 'endforeach',
|
||||||
'in'}
|
'in', 'continue', 'break'}
|
||||||
self.future_keywords = {'continue', 'break', 'return'}
|
self.future_keywords = {'return'}
|
||||||
self.token_specification = [
|
self.token_specification = [
|
||||||
# Need to be sorted longest to shortest.
|
# Need to be sorted longest to shortest.
|
||||||
('ignore', re.compile(r'[ \t]')),
|
('ignore', re.compile(r'[ \t]')),
|
||||||
|
@ -243,6 +243,12 @@ class StringNode(ElementaryNode):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "String node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
|
return "String node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
|
||||||
|
|
||||||
|
class ContinueNode(ElementaryNode):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class BreakNode(ElementaryNode):
|
||||||
|
pass
|
||||||
|
|
||||||
class ArrayNode:
|
class ArrayNode:
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self.subdir = args.subdir
|
self.subdir = args.subdir
|
||||||
|
@ -759,6 +765,10 @@ class Parser:
|
||||||
block = self.foreachblock()
|
block = self.foreachblock()
|
||||||
self.block_expect('endforeach', block_start)
|
self.block_expect('endforeach', block_start)
|
||||||
return block
|
return block
|
||||||
|
if self.accept('continue'):
|
||||||
|
return ContinueNode(self.current)
|
||||||
|
if self.accept('break'):
|
||||||
|
return BreakNode(self.current)
|
||||||
return self.statement()
|
return self.statement()
|
||||||
|
|
||||||
def codeblock(self):
|
def codeblock(self):
|
||||||
|
|
|
@ -18,3 +18,16 @@ foreach i : tests
|
||||||
# we definitely don't want that.
|
# we definitely don't want that.
|
||||||
tests = ['test4', 'prog4', 'prog4.c']
|
tests = ['test4', 'prog4', 'prog4.c']
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
items = ['a', 'continue', 'b', 'break', 'c']
|
||||||
|
result = []
|
||||||
|
foreach i : items
|
||||||
|
if i == 'continue'
|
||||||
|
continue
|
||||||
|
elif i == 'break'
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
result += i
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
assert(result == ['a', 'b'], 'Continue or break in foreach failed')
|
||||||
|
|
Loading…
Reference in New Issue