diff options
-rw-r--r-- | interpreter.py | 19 | ||||
-rw-r--r-- | mparser.py | 21 | ||||
-rw-r--r-- | nodes.py | 12 | ||||
-rw-r--r-- | test cases/common/40 logic ops/meson.build | 46 |
4 files changed, 97 insertions, 1 deletions
diff --git a/interpreter.py b/interpreter.py index ebd29e5..eb04fbb 100644 --- a/interpreter.py +++ b/interpreter.py @@ -841,6 +841,8 @@ class Interpreter(): return self.evaluate_arraystatement(cur) elif isinstance(cur, nodes.IntStatement): return cur + elif isinstance(cur, nodes.AndStatement): + return self.evaluate_andstatement(cur) else: raise InvalidCode("Unknown statement.") @@ -1229,7 +1231,22 @@ class Interpreter(): return val1 != val2 else: raise InvalidCode('You broke me.') - + + def evaluate_andstatement(self, cur): + l = self.evaluate_statement(cur.left) + if isinstance(l, nodes.BoolStatement): + l = l.get_value() + if not isinstance(l, bool): + raise InterpreterException('First argument to "and" is not a boolean.') + if not l: + return False + r = self.evaluate_statement(cur.right) + if isinstance(r, nodes.BoolStatement): + r = r.get_value() + if not isinstance(r, bool): + raise InterpreterException('Second argument to "and" is not a boolean.') + return r + def evaluate_arraystatement(self, cur): (arguments, kwargs) = self.reduce_arguments(cur.get_args()) if len(kwargs) > 0: @@ -27,6 +27,9 @@ reserved = {'true' : 'TRUE', 'if' : 'IF', 'endif' : 'ENDIF', 'else' : 'ELSE', + 'and' : 'AND', + 'or' : 'OR', + 'not' : 'NOT', } tokens = ['LPAREN', @@ -62,6 +65,16 @@ t_COLON = ':' t_ignore = ' \t' +precedence = ( +('left', 'COMMA'), +('left', 'ASSIGN'), +('nonassoc', 'EQUALS', 'NEQUALS'), +('left', 'OR'), +('left', 'AND'), +('nonassoc', 'COLON') +('left', 'DOT'), +) + def t_ATOM(t): '[a-zA-Z][_0-9a-zA-Z]*' t.type = reserved.get(t.value, 'ATOM') @@ -175,6 +188,14 @@ def p_statement_if(t): 'statement : IF statement EOL codeblock elseblock ENDIF' t[0] = nodes.IfStatement(t[2], t[4], t[5], t.lineno(1)) +def p_statement_parentheses(t): + 'statement : LPAREN statement RPAREN' + t[0] = t[2] + +def p_statement_and(t): + 'statement : statement AND statement' + t[0] = nodes.AndStatement(t[1], t[3]) + def p_empty_else(t): 'elseblock : ' return None @@ -82,6 +82,18 @@ class IntStatement(Statement): def get_value(self): return self.value +class AndStatement(Statement): + def __init__(self, left, right): + Statement.__init__(self, left.lineno) + self.left = left + self.right = right + +class OrStatement(Statement): + def __init__(self, left, right): + Statement.__init__(self, left.lineno) + self.left = left + self.right = right + class IfStatement(Statement): def __init__(self, clause, trueblock, falseblock, lineno): Statement.__init__(self, lineno) diff --git a/test cases/common/40 logic ops/meson.build b/test cases/common/40 logic ops/meson.build new file mode 100644 index 0000000..a4466f4 --- /dev/null +++ b/test cases/common/40 logic ops/meson.build @@ -0,0 +1,46 @@ +project('logicopts', 'c') + +t = true +f = false + +if (true) + message('Ok.') +else + error('Not ok.') +endif + +if (false) + error('Not ok.') +else + message('Ok.') +endif + +if (f) + error('Not ok.') +else + message('Ok.') +endif + +if (t) + message('Ok.') +else + error('Not ok.') +endif + +if t and t + message('Ok.') +else + error('Not ok.') +endif + +if t and f + error('Not ok.') +else + message('Ok.') +endif + +if f and t + error('Not ok.') +else + message('Ok.') +endif |