aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-05-28 18:20:10 -0700
committerRose Hogenson <rosehogenson@posteo.net>2024-05-28 18:27:21 -0700
commit52d74efb296cdcdfe8452995dc9d96b34a0e24ac (patch)
treefa08d7eaf090d14e9c360d0bef7fc21496746741 /src
parent2df47cf5e375c73917ebcd6690cd16199d57af83 (diff)
downloadqc-52d74efb296cdcdfe8452995dc9d96b34a0e24ac.tar.zst
Implement modulo.
Diffstat (limited to 'src')
-rw-r--r--src/eval.rs18
-rw-r--r--src/lexer.rs2
-rw-r--r--src/parser.rs4
3 files changed, 22 insertions, 2 deletions
diff --git a/src/eval.rs b/src/eval.rs
index d3b5ddc..e07bec2 100644
--- a/src/eval.rs
+++ b/src/eval.rs
@@ -1,5 +1,6 @@
use num::pow::Pow;
-use num::{BigInt, FromPrimitive, Signed, ToPrimitive};
+use num::{BigInt, FromPrimitive, Integer, Signed, ToPrimitive};
+use std::cmp::Ordering;
use std::fmt::{Display, Formatter};
pub enum Num {
@@ -83,6 +84,21 @@ impl Num {
}
}
+ pub fn modulo(self, other: Num) -> Num {
+ match (self, other) {
+ (Num::Int(i1), Num::Int(i2)) => int(i1.mod_floor(&i2)),
+ (n1, n2) => {
+ let n1 = n1.as_float();
+ let n2 = n2.as_float();
+ let r = n1 % n2;
+ if r < 0. {
+ return float(r + n2);
+ }
+ float(r)
+ }
+ }
+ }
+
pub fn add(self, other: Num) -> Num {
match (self, other) {
(Num::Int(i1), Num::Int(i2)) => int(i1 + i2),
diff --git a/src/lexer.rs b/src/lexer.rs
index 49d2d04..4130760 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -56,7 +56,7 @@ impl<'a> Iterator for Lexer<'a> {
self.buf = &self.buf[1..];
return Some("/");
}
- b'+' | b'-' | b'*' | b'^' | b'(' | b')' => {
+ b'+' | b'-' | b'*' | b'%' | b'^' | b'(' | b')' => {
let t = &self.buf[..1];
self.buf = &self.buf[1..];
return Some(t);
diff --git a/src/parser.rs b/src/parser.rs
index b391202..3728ebf 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -199,6 +199,10 @@ impl<'a> Parser<'a> {
let e2 = seq(self.expt_expr())?;
return self.mul_expr_fold(e1.int_div(e2));
}
+ if self.symbol("%") {
+ let e2 = seq(self.expt_expr())?;
+ return self.mul_expr_fold(e1.modulo(e2));
+ }
// Allow implicit multiplication
if let Some(e2) = or(self.expt_expr_no_num())? {
return self.mul_expr_fold(e1.mul(e2));