diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-28 18:20:10 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-28 18:27:21 -0700 |
| commit | 52d74efb296cdcdfe8452995dc9d96b34a0e24ac (patch) | |
| tree | fa08d7eaf090d14e9c360d0bef7fc21496746741 | |
| parent | 2df47cf5e375c73917ebcd6690cd16199d57af83 (diff) | |
| download | qc-52d74efb296cdcdfe8452995dc9d96b34a0e24ac.tar.zst | |
Implement modulo.
| -rw-r--r-- | src/eval.rs | 18 | ||||
| -rw-r--r-- | src/lexer.rs | 2 | ||||
| -rw-r--r-- | src/parser.rs | 4 |
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)); |
