diff options
-rwxr-xr-x | interpreter.py | 8 | ||||
-rw-r--r-- | nodes.py | 12 | ||||
-rwxr-xr-x | parser.py | 16 | ||||
-rw-r--r-- | test cases/18 else/builder.txt | 11 | ||||
-rw-r--r-- | test cases/18 else/prog.c | 1 |
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()) @@ -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): @@ -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; } |