aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xinterpreter.py28
-rw-r--r--nodes.py20
-rwxr-xr-xparser.py9
-rw-r--r--test cases/19 comparison/builder.txt33
-rw-r--r--test cases/19 comparison/prog.c1
5 files changed, 86 insertions, 5 deletions
diff --git a/interpreter.py b/interpreter.py
index 6b229b8..db570c7 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 b87022e..da2ab6c 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 96cf1f7..ad2e87f 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 0000000..4c84fda
--- /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 0000000..0314ff1
--- /dev/null
+++ b/test cases/19 comparison/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }