Skip to content

Commit 3ca8568

Browse files
when checking for contaminated ident, check recursively.
1 parent 440a897 commit 3ca8568

2 files changed

Lines changed: 30 additions & 5 deletions

File tree

src/services/evaluator/index.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type { Obj } from "@/schemas/objs/union";
1818
import { PolynomialObj } from "@/schemas/objs/unions/polynomials";
1919
import { fnTokenSchema } from "@/schemas/token/function-literal";
2020
import { Effect, Either, Match, Schema } from "effect";
21+
import { left } from "effect/Either";
2122
import type { ParseError } from "effect/ParseResult";
2223
import type { KennethParseError } from "src/errors/kenneth/parse";
2324
import type { DiffExp } from "src/schemas/nodes/exps/diff";
@@ -58,6 +59,29 @@ import {
5859
STRING_OPERATOR_TO_FUNCTION_MAP,
5960
} from "./constants";
6061

62+
const isContaminatedExpression = (
63+
exp: Exp,
64+
contaminatedIdents: readonly IdentExp[],
65+
): boolean =>
66+
Match.value(exp).pipe(
67+
Match.tag("IdentExp", (ident) =>
68+
contaminatedIdents.some((id) => IdentExpEq(id, ident)),
69+
),
70+
Match.tag(
71+
"InfixExp",
72+
({ left, right }) =>
73+
isContaminatedExpression(left, contaminatedIdents) ||
74+
isContaminatedExpression(right, contaminatedIdents),
75+
),
76+
Match.tag("PrefixExp", ({ right }) =>
77+
isContaminatedExpression(right, contaminatedIdents),
78+
),
79+
Match.tag("CallExp", ({ args }) =>
80+
args.some((arg) => isContaminatedExpression(arg, contaminatedIdents)),
81+
),
82+
Match.orElse(() => false),
83+
);
84+
6185
// this error is what we pay for!!!
6286
const nodeEvalMatch = (env: Environment) =>
6387
matchKnode({
@@ -106,10 +130,8 @@ const nodeEvalMatch = (env: Environment) =>
106130
).pipe(
107131
Effect.flatMap((obj) =>
108132
Effect.gen(function* () {
109-
const identoverlap = env.idents.some((ident) =>
110-
args.some(
111-
(arg) => isIdentExp(arg) && ident.value === arg.value,
112-
),
133+
const identoverlap = args.some((arg) =>
134+
isContaminatedExpression(arg, env.idents),
113135
);
114136

115137
const either =
@@ -184,6 +206,7 @@ export const evalDiff = (diffExp: DiffExp) => (env: Environment) =>
184206
yield* Effect.log("diff:");
185207
const diffSoftEval = yield* diffPolynomial(softEval, diffExp.params[0]);
186208

209+
yield* Effect.log("diff-eval", diffSoftEval);
187210
// maybe simplest will be to convert back to exp and Eval.
188211
const convertToExp = (obj: PolynomialObj): Effect.Effect<Exp, ParseError> =>
189212
Match.value(obj).pipe(

src/tests/vitest/eval/eval.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ describe("eval", () => {
295295
["cos(pi() / 2)", Math.cos(Math.PI / 2)],
296296
["tan(0)", Math.tan(0)],
297297
["tan(pi() / 4)", Math.tan(Math.PI / 4)],
298+
["fn (x) { cos(pi() / x) }(2)", Math.cos(Math.PI / 2)],
298299
] as const;
299300

300301
for (const [input, expected] of tests) {
@@ -416,6 +417,7 @@ describe("eval", () => {
416417
describe("trig", () => {
417418
const tests = [
418419
["diff(fn(x) {sin(x)})(0)", Math.cos(0)],
420+
["diff(fn(x) {sin(2)})(0)", 0],
419421
["diff(fn(x) {sin(x)})(pi() / 2)", Math.cos(Math.PI / 2)],
420422
["diff(fn(x) {cos(x)})(0)", -Math.sin(0)],
421423
["diff(fn(x) {cos(x)})(pi() / 2)", -Math.sin(Math.PI / 2)],
@@ -433,7 +435,7 @@ describe("eval", () => {
433435
});
434436
describe("trig chain", () => {
435437
const tests = [
436-
["diff(fn(x) { sin(3x+2) })(0)", 3 * Math.cos(3 * 0 + 2)],
438+
["diff(fn(x) { sin(3 * x + 2) })(0)", 3 * Math.cos(3 * 0 + 2)],
437439
] as const;
438440

439441
for (const [input, expected] of tests) {

0 commit comments

Comments
 (0)