Merge pull request #605 from mesonbuild/ternary

Added ternary operator support
pull/664/head
Jussi Pakkanen 8 years ago committed by GitHub
commit 657f357fc6
  1. 12
      mesonbuild/interpreter.py
  2. 20
      mesonbuild/mparser.py
  3. 7
      test cases/common/116 ternary/meson.build
  4. 3
      test cases/failing/30 nested ternary/meson.build

@ -1323,6 +1323,8 @@ class Interpreter():
return self.evaluate_plusassign(cur)
elif isinstance(cur, mparser.IndexNode):
return self.evaluate_indexing(cur)
elif isinstance(cur, mparser.TernaryNode):
return self.evaluate_ternary(cur)
elif self.is_elementary_type(cur):
return cur
else:
@ -2402,6 +2404,16 @@ class Interpreter():
if not isinstance(node.elseblock, mparser.EmptyNode):
self.evaluate_codeblock(node.elseblock)
def evaluate_ternary(self, node):
assert(isinstance(node, mparser.TernaryNode))
result = self.evaluate_statement(node.condition)
if not isinstance(result, bool):
raise InterpreterException('Ternary condition is not boolean.')
if result:
return self.evaluate_statement(node.trueblock)
else:
return self.evaluate_statement(node.falseblock)
def evaluate_foreach(self, node):
assert(isinstance(node, mparser.ForeachClauseNode))
varname = node.varname.value

@ -67,6 +67,7 @@ class Lexer:
('lt', re.compile(r'<')),
('ge', re.compile(r'>=')),
('gt', re.compile(r'>')),
('questionmark', re.compile(r'\?')),
]
def lex(self, code):
@ -282,6 +283,14 @@ class IfNode():
self.condition = condition
self.block = block
class TernaryNode():
def __init__(self, lineno, colno, condition, trueblock, falseblock):
self.lineno = lineno
self.colno = colno
self.condition = condition
self.trueblock = trueblock
self.falseblock = falseblock
class ArgumentNode():
def __init__(self, token):
self.lineno = token.lineno
@ -344,6 +353,7 @@ class Parser:
def __init__(self, code):
self.stream = Lexer().lex(code)
self.getsym()
self.in_ternary = False
def getsym(self):
try:
@ -383,6 +393,16 @@ class Parser:
raise ParseException('Assignment target must be an id.',
left.lineno, left.colno)
return AssignmentNode(left.lineno, left.colno, left.value, value)
elif self.accept('questionmark'):
if self.in_ternary:
raise ParseException('Nested ternary operators are not allowed.',
left.lineno, left.colno)
self.in_ternary = True
trueblock = self.e1()
self.expect('colon')
falseblock = self.e1()
self.in_ternary = False
return TernaryNode(left.lineno, left.colno, left, trueblock, falseblock)
return left
def e2(self):

@ -0,0 +1,7 @@
project('ternary operator', 'c')
one = true ? 1 : error('False branch should not be evaluated')
two = false ? error('True branch should not be evaluated.') : 2
assert(one == 1, 'Return value from ternary true is wrong.')
assert(two == 2, 'Return value from ternary false is wrong.')

@ -0,0 +1,3 @@
project('nested ternary', 'c')
x = true ? (false ? 1 : 0) : 2
Loading…
Cancel
Save