From 0a10a789a588fa5a463b29722a6e472384daad6b Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Thu, 5 Oct 2023 15:34:19 -0700 Subject: [PATCH] Adds support for %% and its derivatives I'm assuming this handles operator overloading automatically. Nothin much else to say, outside that I needed to roll my own operation for this one, since float remainder is kinda hard to find (and I couldn't after cursory reading) --- crates/dreammaker/src/ast.rs | 5 +++++ crates/dreammaker/src/constants.rs | 8 ++++++++ crates/dreammaker/src/lexer.rs | 3 +++ crates/dreammaker/src/parser.rs | 10 ++++++++-- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/dreammaker/src/ast.rs b/crates/dreammaker/src/ast.rs index 49d8086a..3c1cb677 100644 --- a/crates/dreammaker/src/ast.rs +++ b/crates/dreammaker/src/ast.rs @@ -113,6 +113,7 @@ pub enum BinaryOp { Div, Pow, Mod, + FloatMod, Eq, NotEq, Less, @@ -142,6 +143,7 @@ impl fmt::Display for BinaryOp { Div => "/", Pow => "**", Mod => "%", + FloatMod => "%%", Eq => "==", NotEq => "!=", Less => "<", @@ -172,6 +174,7 @@ pub enum AssignOp { MulAssign, DivAssign, ModAssign, + FloatModAssign, AssignInto, BitAndAssign, AndAssign, @@ -192,6 +195,7 @@ impl fmt::Display for AssignOp { MulAssign => "*=", DivAssign => "/=", ModAssign => "%=", + FloatModAssign => "%%=", AssignInto => ":=", BitAndAssign => "&=", AndAssign => "&&=", @@ -233,6 +237,7 @@ augmented! { Mul = MulAssign; Div = DivAssign; Mod = ModAssign; + FloatMod = FloatModAssign; BitAnd = BitAndAssign; BitOr = BitOrAssign; BitXor = BitXorAssign; diff --git a/crates/dreammaker/src/constants.rs b/crates/dreammaker/src/constants.rs index 40adc04d..c75a240c 100644 --- a/crates/dreammaker/src/constants.rs +++ b/crates/dreammaker/src/constants.rs @@ -684,6 +684,14 @@ impl<'a> ConstantFolder<'a> { numeric!(LessEq <=); numeric!(Greater >); numeric!(GreaterEq >=); + match (op, lhs, rhs) { + (BinaryOp::FloatMod, Float(lhs), Float(rhs)) => return Ok(Constant::from(lhs - ((lhs / rhs).floor() * rhs))), + (_, lhs_, rhs_) => { + lhs = lhs_; + rhs = rhs_; + } + } + match (op, lhs, rhs) { (BinaryOp::Pow, Float(lhs), Float(rhs)) => return Ok(Constant::from(lhs.powf(rhs))), (_, lhs_, rhs_) => { diff --git a/crates/dreammaker/src/lexer.rs b/crates/dreammaker/src/lexer.rs index ed4c46d2..68627ce5 100644 --- a/crates/dreammaker/src/lexer.rs +++ b/crates/dreammaker/src/lexer.rs @@ -75,6 +75,8 @@ table! { "##", TokenPaste; "%", Mod; "%=", ModAssign; + "%%", FloatMod; + "%%=", FloatModAssign; "&", BitAnd; "&&", And; "&&=", AndAssign; @@ -278,6 +280,7 @@ impl Token { Eq | NotEq | Mod | + FloatMod | And | BitAndAssign | AndAssign | diff --git a/crates/dreammaker/src/parser.rs b/crates/dreammaker/src/parser.rs index cde62424..08d02db4 100644 --- a/crates/dreammaker/src/parser.rs +++ b/crates/dreammaker/src/parser.rs @@ -150,11 +150,12 @@ oper_table! { BINARY_OPS; Pow { (BinaryOp, Pow), } - // * / % + // * / % %% Mul { (BinaryOp, Mul), // (BinaryOp, Div = Slash), // (BinaryOp, Mod), + (BinaryOp, FloatMod), } // + - Add { @@ -205,7 +206,7 @@ oper_table! { BINARY_OPS; Conditional { (TernaryOp, Conditional = QuestionMark), } - // = += -= -= *= /= %= &= |= ^= <<= >>= + // = += -= -= *= /= %= %%= &= |= ^= <<= >>= Assign { (AssignOp, Assign), (AssignOp, AddAssign), @@ -213,6 +214,7 @@ oper_table! { BINARY_OPS; (AssignOp, MulAssign), (AssignOp, DivAssign), (AssignOp, ModAssign), + (AssignOp, FloatModAssign), (AssignOp, BitAndAssign), (AssignOp, BitOrAssign), (AssignOp, BitXorAssign), @@ -887,6 +889,10 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> { last_part.push('%'); } else if self.exact(Punct(ModAssign))?.is_some() { last_part.push_str("%="); + } else if self.exact(Punct(FloatMod))?.is_some() { + last_part.push_str("%%"); + } else if self.exact(Punct(FloatModAssign))?.is_some() { + last_part.push_str("%%="); } else if self.exact(Punct(BitAnd))?.is_some() { last_part.push('&'); } else if self.exact(Punct(BitAndAssign))?.is_some() {