aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2016-09-02 23:13:46 +0300
committerGitHub <noreply@github.com>2016-09-02 23:13:45 +0300
commit84995b2993a875496827b28293f228902038dcd7 (patch)
tree1e080ee33ab96334dd5d4f9c2453c72fbe822334
parent0e796641559f0fd6ac75a190157c8940cb7bc5a8 (diff)
parent5fec1620d2528d79862ad28f2f31e12af8fd22c1 (diff)
downloadmeson-84995b2993a875496827b28293f228902038dcd7.zip
meson-84995b2993a875496827b28293f228902038dcd7.tar.gz
meson-84995b2993a875496827b28293f228902038dcd7.tar.bz2
Merge pull request #750 from ebassi/integer-modulo
Add support to integer modulo operator
-rw-r--r--mesonbuild/interpreter.py22
-rw-r--r--mesonbuild/mparser.py9
-rw-r--r--test cases/common/68 number arithmetic/meson.build21
3 files changed, 51 insertions, 1 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index ac95e15..abbeaf7 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2293,6 +2293,22 @@ class Interpreter():
else:
raise InterpreterException('Unknown method "%s" for a boolean.' % method_name)
+ def int_method_call(self, obj, method_name, args):
+ obj = self.to_native(obj)
+ (posargs, _) = self.reduce_arguments(args)
+ if method_name == 'is_even':
+ if len(posargs) == 0:
+ return obj % 2 == 0
+ else:
+ raise InterpreterException('int.is_even() must have no arguments.')
+ elif method_name == 'is_odd':
+ if len(posargs) == 0:
+ return obj % 2 != 0
+ else:
+ raise InterpreterException('int.is_odd() must have no arguments.')
+ else:
+ raise InterpreterException('Unknown method "%s" for an integer.' % method_name)
+
def string_method_call(self, obj, method_name, args):
obj = self.to_native(obj)
(posargs, _) = self.reduce_arguments(args)
@@ -2379,6 +2395,8 @@ class Interpreter():
return self.string_method_call(obj, method_name, args)
if isinstance(obj, bool):
return self.bool_method_call(obj, method_name, args)
+ if isinstance(obj, int):
+ return self.int_method_call(obj, method_name, args)
if isinstance(obj, list):
return self.array_method_call(obj, method_name, self.reduce_arguments(args)[0])
if not isinstance(obj, InterpreterObject):
@@ -2595,6 +2613,10 @@ class Interpreter():
if not isinstance(l, int) or not isinstance(r, int):
raise InvalidCode('Division works only with integers.')
return l // r
+ elif cur.operation == 'mod':
+ if not isinstance(l, int) or not isinstance(r, int):
+ raise InvalidCode('Modulo works only with integers.')
+ return l % r
else:
raise InvalidCode('You broke me.')
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index 2f0eb2d..f593c8e 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -58,6 +58,7 @@ class Lexer:
('plus', re.compile(r'\+')),
('dash', re.compile(r'-')),
('star', re.compile(r'\*')),
+ ('percent', re.compile(r'\%')),
('fslash', re.compile(r'/')),
('colon', re.compile(r':')),
('equal', re.compile(r'==')),
@@ -434,11 +435,17 @@ class Parser:
return left
def e5sub(self):
- left = self.e5mul()
+ left = self.e5mod()
if self.accept('dash'):
return ArithmeticNode(left.lineno, left.colno, 'sub', left, self.e5sub())
return left
+ def e5mod(self):
+ left = self.e5mul()
+ if self.accept('percent'):
+ return ArithmeticNode(left.lineno, left.colno, 'mod', left, self.e5mod())
+ return left
+
def e5mul(self):
left = self.e5div()
if self.accept('star'):
diff --git a/test cases/common/68 number arithmetic/meson.build b/test cases/common/68 number arithmetic/meson.build
index 4b98d73..02c7878 100644
--- a/test cases/common/68 number arithmetic/meson.build
+++ b/test cases/common/68 number arithmetic/meson.build
@@ -21,6 +21,27 @@ if (5 / 3) * 3 != 3
error('Integer division is broken')
endif
+assert((5 % 2) == 1, 'Integer modulo (odd) is broken')
+assert((4 % 2) == 0, 'Integer modulo (even) is broken')
+
+if 2 * 1 % 2 != 0
+ error('Modulo precendence with multiplication is broken')
+endif
+if 2 + 1 % 2 != 3
+ error('Modulo precendence with addition is broken')
+endif
+if 9 / 9 % 2 != 1
+ error('Modulo precendence with division is broken')
+endif
+if 9 - 9 % 2 != 8
+ error('Modulo precendence with subtraction is broken')
+endif
+
+assert(2.is_even(), 'int is_even() broken for even value')
+assert(not(2.is_odd()), 'int is_odd() broken for even value')
+assert(not(3.is_even()), 'int is_even() broken for odd value')
+assert(3.is_odd(), 'int is_odd() broken for odd value')
+
assert(3 < 4, 'Lt broken')
assert(not(4 < 3), 'Lt broken')
assert(3 <= 4, 'Lte broken')