aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2013-01-25 21:06:08 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2013-01-25 21:06:08 +0200
commit88bd40ecf3f58414bbc2dd1ea924e90d3885116c (patch)
tree6ebac917be52975399cdce8909de8dc95fa9b42c
parentbd6e542f1c5be82ce24eb9374423747fa7b27a29 (diff)
downloadmeson-88bd40ecf3f58414bbc2dd1ea924e90d3885116c.zip
meson-88bd40ecf3f58414bbc2dd1ea924e90d3885116c.tar.gz
meson-88bd40ecf3f58414bbc2dd1ea924e90d3885116c.tar.bz2
Added if clause.
-rwxr-xr-xinterpreter.py18
-rw-r--r--nodes.py12
-rwxr-xr-xparser.py8
-rw-r--r--test cases/17 if/builder.txt13
-rw-r--r--test cases/17 if/prog.c1
5 files changed, 49 insertions, 3 deletions
diff --git a/interpreter.py b/interpreter.py
index 50c7a40..f0d2606 100755
--- a/interpreter.py
+++ b/interpreter.py
@@ -275,8 +275,15 @@ class Interpreter():
return cur
elif isinstance(cur, nodes.BoolStatement):
return cur
+ elif isinstance(cur, nodes.IfStatement):
+ return self.evaluate_if(cur)
+ elif isinstance(cur, nodes.AtomStatement):
+ varname = cur.get_value()
+ if varname in self.variables:
+ return self.variables[varname]
+ raise InvalidCode('Line %d: unknown variable "%s".' % (cur.lineno(), varname))
else:
- raise InvalidCode("Unknown statement in line %d." % cur.lineno())
+ raise InvalidCode("Line %d: Unknown statement." % cur.lineno())
def validate_arguments(self, args, argcount, arg_types):
if argcount is not None:
@@ -455,6 +462,15 @@ class Interpreter():
if not isinstance(obj, InterpreterObject):
raise InvalidArguments('Line %d: variable "%s" is not callable.' % (node.lineno(), object_name))
return obj.method_call(method_name, self.reduce_arguments(args))
+
+ def evaluate_if(self, node):
+ result = self.evaluate_statement(node.get_clause())
+ if isinstance(result, nodes.BoolExpression) or \
+ isinstance(result, nodes.BoolStatement):
+ if result.get_value():
+ self.evaluate_codeblock(node.get_codeblock())
+ else:
+ raise InvalidCode('Line %d: If clause does not evaluate to true or false.' % node.lineno())
if __name__ == '__main__':
code = """project('myawesomeproject')
diff --git a/nodes.py b/nodes.py
index 4bbaa5d..385e1c9 100644
--- a/nodes.py
+++ b/nodes.py
@@ -66,6 +66,18 @@ class BoolStatement(Statement):
def get_value(self):
return self.value
+
+class IfStatement(Statement):
+ def __init__(self, clause, codeblock, lineno):
+ Statement.__init__(self, lineno)
+ self.clause = clause
+ self.codeblock = codeblock
+
+ def get_clause(self):
+ return self.clause
+
+ def get_codeblock(self):
+ return self.codeblock
class StringStatement(Statement):
def __init__(self, value, lineno):
diff --git a/parser.py b/parser.py
index a6af003..ac6c8e5 100755
--- a/parser.py
+++ b/parser.py
@@ -19,7 +19,9 @@ import ply.yacc as yacc
import nodes
reserved = {'true' : 'TRUE',
- 'false' : 'FALSE'}
+ 'false' : 'FALSE',
+ 'if' : 'IF',
+ 'endif' : 'ENDIF'}
tokens = ['LPAREN',
'RPAREN',
@@ -119,6 +121,10 @@ def p_statement_method_call(t):
'statement : expression DOT expression LPAREN args RPAREN'
t[0] = nodes.MethodCall(t[1], t[3], t[5], t.lineno(1))
+def p_statement_if(t):
+ 'statement : IF LPAREN statement RPAREN EOL codeblock ENDIF'
+ t[0] = nodes.IfStatement(t[3], t[6], t.lineno(1))
+
def p_statement_expression(t):
'statement : expression'
t[0] = nodes.statement_from_expression(t[1])
diff --git a/test cases/17 if/builder.txt b/test cases/17 if/builder.txt
index ca994d0..96615b9 100644
--- a/test cases/17 if/builder.txt
+++ b/test cases/17 if/builder.txt
@@ -1,3 +1,14 @@
project('if test', 'c')
-var = true
+var1 = true
+var2 = false
+
+if(var1)
+ exe = executable('prog', 'prog.c')
+endif
+
+if(var2)
+ exe = executable('breakbreakbreak', 'crashing.c')
+endif
+
+add_test('iftest', exe)
diff --git a/test cases/17 if/prog.c b/test cases/17 if/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/17 if/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }