diff --git a/src/lib/expr.test.ts b/src/lib/expr.test.ts index e998605..3ed361f 100644 --- a/src/lib/expr.test.ts +++ b/src/lib/expr.test.ts @@ -11,6 +11,11 @@ describe("expr", () => { ["1 * 2", "2"], ["1 / 2", "0.5"], ["1 // 2", "0"], + ["1 % 2", "1"], + ["3 % 2", "1"], + ["-1 % 2", "1"], + // TODO: might change this! negative dividend is weird no matter what, but positive modulo is arguably the better call? + ["1 % -2", "-1"], // TODO: operator precedence // TODO: parentheses ])("%s", (expression, result) => { diff --git a/src/lib/expr.ts b/src/lib/expr.ts index 00dce77..9d6afb2 100644 --- a/src/lib/expr.ts +++ b/src/lib/expr.ts @@ -32,6 +32,7 @@ const MINUS_TOKEN = /\s*(\-)/y; const TIMES_TOKEN = /\s*(\*)/y; const FLOOR_TOKEN = /\s*(\/\/)/y; const DIV_TOKEN = /\s*(\/)/y; +const MOD_TOKEN = /\s*(\%)/y; const NUMBER_TOKEN = /\s*(\d+)/y; @@ -84,6 +85,7 @@ const Operators: TokenHandler[] = [ makeInfixOp(TIMES_TOKEN, 20, 21, (left, right) => ({ value: left * right })), makeInfixOp(FLOOR_TOKEN, 20, 21, (left, right) => ({ value: Math.floor(left / right) })), makeInfixOp(DIV_TOKEN, 20, 21, (left, right) => ({ value: left / right })), + makeInfixOp(MOD_TOKEN, 20, 21, (left, right) => ({ value: ((left % right) + right) % right })), ]; const ZERO = { value: 0 };