From f5835d85e2ae098aacb3f585bc63bea5c9e7884f Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 25 Jan 2013 21:59:53 +0200 Subject: [PATCH] Added comparison. --- interpreter.py | 28 ++++++++++++++++++++--- nodes.py | 20 +++++++++++++++-- parser.py | 9 ++++++++ test cases/19 comparison/builder.txt | 33 ++++++++++++++++++++++++++++ test cases/19 comparison/prog.c | 1 + 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 test cases/19 comparison/builder.txt create mode 100644 test cases/19 comparison/prog.c diff --git a/interpreter.py b/interpreter.py index 6b229b885..db570c7e0 100755 --- a/interpreter.py +++ b/interpreter.py @@ -284,6 +284,8 @@ class Interpreter(): if varname in self.variables: return self.variables[varname] raise InvalidCode('Line %d: unknown variable "%s".' % (cur.lineno(), varname)) + elif isinstance(cur, nodes.Comparison): + return self.evaluate_comparison(cur) else: raise InvalidCode("Line %d: Unknown statement." % cur.lineno()) @@ -445,7 +447,7 @@ class Interpreter(): 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() + r = arg.get_value() elif isinstance(arg, nodes.FunctionCall): r = self.function_call(arg) elif isinstance(arg, nodes.MethodCall): @@ -469,15 +471,35 @@ class Interpreter(): def evaluate_if(self, node): result = self.evaluate_statement(node.get_clause()) + cond = None if isinstance(result, nodes.BoolExpression) or \ isinstance(result, nodes.BoolStatement): - if result.get_value(): + cond = result.get_value() + if isinstance(result, bool): + cond = result + + if cond is not None: + if cond: self.evaluate_codeblock(node.get_trueblock()) else: self.evaluate_codeblock(node.get_falseblock()) else: + print(node.get_clause()) + print(result) raise InvalidCode('Line %d: If clause does not evaluate to true or false.' % node.lineno()) - + + def evaluate_comparison(self, node): + v1 = self.evaluate_statement(node.get_first()) + v2 = self.evaluate_statement(node.get_second()) + val1 = v1.get_value() + val2 = v2.get_value() + assert(type(val1) == type(val2)) + if node.get_ctype() == '==': + return val1 == val2 + elif node.get_ctype() == '!=': + return val1 != val2 + else: + raise InvalidCode('You broke me.') if __name__ == '__main__': code = """project('myawesomeproject') message('I can haz text printed out?') diff --git a/nodes.py b/nodes.py index b87022e4c..da2ab6c22 100644 --- a/nodes.py +++ b/nodes.py @@ -83,13 +83,29 @@ class IfStatement(Statement): def get_falseblock(self): return self.falseblock +class Comparison(Statement): + def __init__(self, first, ctype, second, lineno): + Statement.__init__(self, lineno) + self.first = first + self.ctype = ctype + self.second = second + + def get_first(self): + return self.first + + def get_ctype(self): + return self.ctype + + def get_second(self): + return self.second + class StringStatement(Statement): def __init__(self, value, lineno): assert(type(value) == type('')) Statement.__init__(self, lineno) self.value = value - - def get_string(self): + + def get_value(self): return self.value class FunctionCall(Statement): diff --git a/parser.py b/parser.py index 96cf1f741..ad2e87f62 100755 --- a/parser.py +++ b/parser.py @@ -34,6 +34,8 @@ tokens = ['LPAREN', 'ATOM', 'COMMENT', 'ASSIGN', + 'EQUALS', + 'NEQUALS', 'COMMA', 'DOT', 'STRING', @@ -42,6 +44,8 @@ tokens = ['LPAREN', ] + list(reserved.values()) t_ASSIGN = '=' +t_EQUALS = '==' +t_NEQUALS = '\!=' t_LPAREN = '\(' t_RPAREN = '\)' t_LBRACKET = '\[' @@ -115,6 +119,11 @@ def p_statement_assign(t): 'statement : expression ASSIGN statement' t[0] = nodes.Assignment(t[1], t[3], t.lineno(1)) +def p_statement_equals(t): + '''statement : statement EQUALS statement + | statement NEQUALS statement''' + t[0] = nodes.Comparison(t[1], t[2], t[3], t.lineno(1)) + def p_statement_func_call(t): 'statement : expression LPAREN args RPAREN' t[0] = nodes.FunctionCall(t[1], t[3], t.lineno(1)) diff --git a/test cases/19 comparison/builder.txt b/test cases/19 comparison/builder.txt new file mode 100644 index 000000000..4c84fda29 --- /dev/null +++ b/test cases/19 comparison/builder.txt @@ -0,0 +1,33 @@ +project('comparison', 'c') + +var1 = 'foo' +var2 = 'bar' + +if(var1 == var2) + exe1 = executable('broken', 'broken.c') +else + exe1 = executable('prog1', 'prog.c') +endif + +if(var1 == var1) + exe2 = executable('prog2', 'prog.c') +else + exe2 = executable('broken', 'broken.c') +endif + +if(var1 != var2) + exe3 = executable('prog3', 'prog.c') +else + exe3 = executable('broken', 'broken.c') +endif + +if(var1 != var1) + exe4 = executable('broken', 'broken.c') +else + exe4 = executable('prog4', 'prog.c') +endif + +add_test('equalfalse', exe1) +add_test('equaltrue', exe2) +add_test('nequaltrue', exe3) +add_test('nequalfalse', exe4) diff --git a/test cases/19 comparison/prog.c b/test cases/19 comparison/prog.c new file mode 100644 index 000000000..0314ff17b --- /dev/null +++ b/test cases/19 comparison/prog.c @@ -0,0 +1 @@ +int main(int argc, char **argv) { return 0; }