aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xinterpreter.py8
-rw-r--r--nodes.py12
-rwxr-xr-xparser.py16
-rw-r--r--test cases/18 else/builder.txt11
-rw-r--r--test cases/18 else/prog.c1
5 files changed, 40 insertions, 8 deletions
diff --git a/interpreter.py b/interpreter.py
index f0d2606..497498f 100755
--- a/interpreter.py
+++ b/interpreter.py
@@ -255,6 +255,8 @@ class Interpreter():
self.evaluate_codeblock(self.ast)
def evaluate_codeblock(self, node):
+ if node is None:
+ return
if not isinstance(node, nodes.CodeBlock):
raise InvalidCode('Tried to execute a non-codeblock. Possibly a bug in the parser.')
statements = node.get_statements()
@@ -439,6 +441,8 @@ class Interpreter():
reduced = []
for arg in args.arguments:
if isinstance(arg, nodes.AtomExpression) or isinstance(arg, nodes.AtomStatement):
+ if arg.value not in self.variables:
+ raise InvalidCode('Line %d: variable "%s" is not set' % (arg.lineno(), arg.value))
r = self.variables[arg.value]
elif isinstance(arg, nodes.StringExpression) or isinstance(arg, nodes.StringStatement):
r = arg.get_string()
@@ -468,7 +472,9 @@ class Interpreter():
if isinstance(result, nodes.BoolExpression) or \
isinstance(result, nodes.BoolStatement):
if result.get_value():
- self.evaluate_codeblock(node.get_codeblock())
+ self.evaluate_codeblock(node.get_trueblock())
+ else:
+ self.evaluate_codeblock(node.get_falseblock())
else:
raise InvalidCode('Line %d: If clause does not evaluate to true or false.' % node.lineno())
diff --git a/nodes.py b/nodes.py
index 385e1c9..b87022e 100644
--- a/nodes.py
+++ b/nodes.py
@@ -68,16 +68,20 @@ class BoolStatement(Statement):
return self.value
class IfStatement(Statement):
- def __init__(self, clause, codeblock, lineno):
+ def __init__(self, clause, trueblock, falseblock, lineno):
Statement.__init__(self, lineno)
self.clause = clause
- self.codeblock = codeblock
+ self.trueblock = trueblock
+ self.falseblock = falseblock
def get_clause(self):
return self.clause
- def get_codeblock(self):
- return self.codeblock
+ def get_trueblock(self):
+ return self.trueblock
+
+ def get_falseblock(self):
+ return self.falseblock
class StringStatement(Statement):
def __init__(self, value, lineno):
diff --git a/parser.py b/parser.py
index ac6c8e5..1c00ab8 100755
--- a/parser.py
+++ b/parser.py
@@ -21,7 +21,9 @@ import nodes
reserved = {'true' : 'TRUE',
'false' : 'FALSE',
'if' : 'IF',
- 'endif' : 'ENDIF'}
+ 'endif' : 'ENDIF',
+ 'else' : 'ELSE',
+ }
tokens = ['LPAREN',
'RPAREN',
@@ -122,8 +124,16 @@ def p_statement_method_call(t):
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))
+ 'statement : IF LPAREN statement RPAREN EOL codeblock elseblock ENDIF'
+ t[0] = nodes.IfStatement(t[3], t[6], t[7], t.lineno(1))
+
+def p_empty_else(t):
+ 'elseblock : '
+ return None
+
+def p_else(t):
+ 'elseblock : ELSE EOL codeblock'
+ t[0] = t[3]
def p_statement_expression(t):
'statement : expression'
diff --git a/test cases/18 else/builder.txt b/test cases/18 else/builder.txt
new file mode 100644
index 0000000..f3588d7
--- /dev/null
+++ b/test cases/18 else/builder.txt
@@ -0,0 +1,11 @@
+project('else test', 'c')
+
+var = false
+
+if(var)
+ exe = executable('break', 'break.c')
+else
+ exe = executable('prog', 'prog.c')
+endif
+
+add_test('elsetest', exe)
diff --git a/test cases/18 else/prog.c b/test cases/18 else/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/18 else/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }