mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 02:12:00 +03:00
🧹 Refactor evalBin to improve readability
Extracted percent and quantity arithmetic logic into smaller helper functions (`evalPercentArith` and `evalQuantityArith`) to simplify the main `evalBin` dispatcher. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
parent
f5b1fc038b
commit
68820f7932
2 changed files with 40 additions and 34 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "summarum",
|
"name": "summarum",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "summarum",
|
"name": "summarum",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.18.0",
|
"@codemirror/autocomplete": "^6.18.0",
|
||||||
"@codemirror/commands": "^6.8.0",
|
"@codemirror/commands": "^6.8.0",
|
||||||
|
|
|
||||||
|
|
@ -199,43 +199,37 @@ function numericAdd(a: Quantity, b: Quantity, sign: 1 | -1): Quantity {
|
||||||
return qty(sign === 1 ? a.value.add(b.value) : a.value.sub(b.value), unit);
|
return qty(sign === 1 ? a.value.add(b.value) : a.value.sub(b.value), unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
function evalBin(op: "plus" | "minus" | "mul" | "div" | "mod" | "pow", l: Value, r: Value, ctx: EvalCtx): Value {
|
function evalPercentArith(op: "plus" | "minus" | "mul" | "div" | "mod" | "pow", l: Value, r: Value): Value {
|
||||||
// ---- dates
|
if (l.kind === "percent" && r.kind === "percent") {
|
||||||
if (l.kind === "date" || r.kind === "date") return evalDateArith(op, l, r);
|
|
||||||
|
|
||||||
// ---- percent combinations
|
|
||||||
if (l.kind === "percent" || r.kind === "percent") {
|
|
||||||
if (l.kind === "percent" && r.kind === "percent") {
|
|
||||||
switch (op) {
|
|
||||||
case "plus": return pct(l.value.add(r.value));
|
|
||||||
case "minus": return pct(l.value.sub(r.value));
|
|
||||||
case "mul": return pct(l.value.mul(r.value).div(100));
|
|
||||||
case "div": return qty(l.value.div(r.value));
|
|
||||||
default: throw new EvalError("bad percent op");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const q = (l.kind === "quantity" ? l : r) as Quantity;
|
|
||||||
const p = (l.kind === "percent" ? l : r as { kind: "percent"; value: Decimal }).value;
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case "plus": return qty(q.value.mul(new Decimal(1).add(p.div(100))), q.unit);
|
case "plus": return pct(l.value.add(r.value));
|
||||||
case "minus":
|
case "minus": return pct(l.value.sub(r.value));
|
||||||
if (l.kind === "percent") throw new EvalError("percent minus number");
|
case "mul": return pct(l.value.mul(r.value).div(100));
|
||||||
return qty(q.value.mul(new Decimal(1).sub(p.div(100))), q.unit);
|
case "div": return qty(l.value.div(r.value));
|
||||||
case "mul": return qty(q.value.mul(p).div(100), q.unit);
|
|
||||||
case "div":
|
|
||||||
if (l.kind === "percent") throw new EvalError("percent div number");
|
|
||||||
return qty(q.value.div(p.div(100)), q.unit);
|
|
||||||
case "pow":
|
|
||||||
// which side the percent is on matters: 50% ^ 2 = 0.25, 2 ^ 50% = √2
|
|
||||||
return l.kind === "percent"
|
|
||||||
? qty(p.div(100).pow(q.value))
|
|
||||||
: qty(q.value.pow(p.div(100)), q.unit);
|
|
||||||
default: throw new EvalError("bad percent op");
|
default: throw new EvalError("bad percent op");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const q = (l.kind === "quantity" ? l : r) as Quantity;
|
||||||
|
const p = (l.kind === "percent" ? l : r as { kind: "percent"; value: Decimal }).value;
|
||||||
|
switch (op) {
|
||||||
|
case "plus": return qty(q.value.mul(new Decimal(1).add(p.div(100))), q.unit);
|
||||||
|
case "minus":
|
||||||
|
if (l.kind === "percent") throw new EvalError("percent minus number");
|
||||||
|
return qty(q.value.mul(new Decimal(1).sub(p.div(100))), q.unit);
|
||||||
|
case "mul": return qty(q.value.mul(p).div(100), q.unit);
|
||||||
|
case "div":
|
||||||
|
if (l.kind === "percent") throw new EvalError("percent div number");
|
||||||
|
return qty(q.value.div(p.div(100)), q.unit);
|
||||||
|
case "pow":
|
||||||
|
// which side the percent is on matters: 50% ^ 2 = 0.25, 2 ^ 50% = √2
|
||||||
|
return l.kind === "percent"
|
||||||
|
? qty(p.div(100).pow(q.value))
|
||||||
|
: qty(q.value.pow(p.div(100)), q.unit);
|
||||||
|
default: throw new EvalError("bad percent op");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const a = l as Quantity;
|
function evalQuantityArith(op: "plus" | "minus" | "mul" | "div" | "mod" | "pow", a: Quantity, b: Quantity, ctx: EvalCtx): Value {
|
||||||
const b = r as Quantity;
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case "plus": return numericAdd(a, b, 1);
|
case "plus": return numericAdd(a, b, 1);
|
||||||
case "minus": return numericAdd(a, b, -1);
|
case "minus": return numericAdd(a, b, -1);
|
||||||
|
|
@ -281,6 +275,18 @@ function evalBin(op: "plus" | "minus" | "mul" | "div" | "mod" | "pow", l: Value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function evalBin(op: "plus" | "minus" | "mul" | "div" | "mod" | "pow", l: Value, r: Value, ctx: EvalCtx): Value {
|
||||||
|
if (l.kind === "date" || r.kind === "date") {
|
||||||
|
return evalDateArith(op, l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l.kind === "percent" || r.kind === "percent") {
|
||||||
|
return evalPercentArith(op, l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return evalQuantityArith(op, l as Quantity, r as Quantity, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
function evalBit(op: string, l: Value, r: Value): Value {
|
function evalBit(op: string, l: Value, r: Value): Value {
|
||||||
if (l.kind !== "quantity" || r.kind !== "quantity") throw new EvalError("bitwise needs integers");
|
if (l.kind !== "quantity" || r.kind !== "quantity") throw new EvalError("bitwise needs integers");
|
||||||
if (!l.value.isFinite() || !r.value.isFinite()) throw new EvalError("bitwise needs finite integers");
|
if (!l.value.isFinite() || !r.value.isFinite()) throw new EvalError("bitwise needs finite integers");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue