Skip to content

Commit

Permalink
Universal equality/inequality checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
amyjko committed Oct 28, 2023
1 parent a7c7543 commit 867f7e0
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 249 deletions.
28 changes: 28 additions & 0 deletions src/basis/Basis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ import bootstrapStructure from './StructureBasis';
import { toTokens } from '../parser/toTokens';
import parseType from '../parser/paresType';
import type Locales from '../locale/Locales';
import AnyType from '../nodes/AnyType';
import BooleanType from '../nodes/BooleanType';
import ValueException from '../values/ValueException';
import BoolValue from '../values/BoolValue';

export class Basis {
readonly locales: Locales;
Expand Down Expand Up @@ -177,6 +181,30 @@ export function createBasisFunction(
);
}

export function createEqualsFunction(
locales: Locales,
text: (locale: Locale) => FunctionText<NameAndDoc[]>,
equal: boolean
) {
return createBasisFunction(
locales,
text,
undefined,
[new AnyType()],
BooleanType.make(),
(requestor, evaluation) => {
const left: Value | Evaluation | undefined =
evaluation.getClosure();
const right = evaluation.getInput(0);
if (!(left instanceof Value))
return new ValueException(evaluation.getEvaluator(), requestor);
if (!(right instanceof Value))
return new ValueException(evaluation.getEvaluator(), requestor);
return new BoolValue(requestor, left.isEqualTo(right) === equal);
}
);
}

export function createBasisConversion<ValueType extends Value>(
docs: Docs,
input: Type | string,
Expand Down
21 changes: 11 additions & 10 deletions src/basis/BoolBasis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import BooleanType from '@nodes/BooleanType';
import StructureDefinition from '@nodes/StructureDefinition';
import BoolValue from '@values/BoolValue';
import TextValue from '@values/TextValue';
import { createBasisConversion, createBasisFunction } from './Basis';
import {
createBasisConversion,
createBasisFunction,
createEqualsFunction,
} from './Basis';
import type Value from '@values/Value';
import { getDocLocales } from '@locale/getDocLocales';
import { getNameLocales } from '@locale/getNameLocales';
Expand All @@ -12,7 +16,6 @@ import type Expression from '../nodes/Expression';
import type Locale from '../locale/Locale';
import type { FunctionText, NameAndDoc } from '../locale/Locale';
import type Type from '../nodes/Type';
import AnyType from '../nodes/AnyType';
import type Locales from '../locale/Locales';

export default function bootstrapBool(locales: Locales) {
Expand Down Expand Up @@ -88,17 +91,15 @@ export default function bootstrapBool(locales: Locales) {
return left.not(requestor);
}
),
createBooleanFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Boolean.function.equals,
[new AnyType()],
(requestor, left, right) =>
new BoolValue(requestor, left.isEqualTo(right))
true
),
createBooleanFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Boolean.function.notequal,
[new AnyType()],
(requestor, left, right) =>
new BoolValue(requestor, !left.isEqualTo(right))
false
),
createBasisConversion(
getDocLocales(
Expand Down
2 changes: 2 additions & 0 deletions src/basis/MapBasis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ test.each([
"{'cat':1 'dog':2 'mouse':3}.translate(ƒ(k v) -v)",
'{"cat":-1 "dog":-2 "mouse":-3}',
],
['{1:1 2:2} = ø', '⊥'],
['{1:1 2:2} ≠ ø', '⊤'],
])('Expect %s to be %s map functions', (code, value) => {
expect(evaluateCode(code)?.toString()).toBe(value);
});
45 changes: 9 additions & 36 deletions src/basis/MapBasis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import ListValue from '@values/ListValue';
import TextValue from '@values/TextValue';
import MapValue from '@values/MapValue';
import SetValue from '@values/SetValue';
import { createBasisConversion, createBasisFunction } from './Basis';
import {
createBasisConversion,
createBasisFunction,
createEqualsFunction,
} from './Basis';
import BoolValue from '@values/BoolValue';
import TypeVariables from '@nodes/TypeVariables';
import { getDocLocales } from '@locale/getDocLocales';
Expand All @@ -23,7 +27,6 @@ import NumberValue from '@values/NumberValue';
import TextType from '../nodes/TextType';
import SetType from '../nodes/SetType';
import ListType from '../nodes/ListType';
import AnyType from '../nodes/AnyType';
import type Locales from '../locale/Locales';

export default function bootstrapMap(locales: Locales) {
Expand Down Expand Up @@ -74,45 +77,15 @@ export default function bootstrapMap(locales: Locales) {
);
}
),
createBasisFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Map.function.equals,
undefined,
[new AnyType()],
BooleanType.make(),
(requestor, evaluation) => {
const map = evaluation?.getClosure();
const other = evaluation.getInput(0);
return !(
map instanceof MapValue && other instanceof MapValue
)
? evaluation.getValueOrTypeException(
requestor,
MapType.make(),
other
)
: new BoolValue(requestor, map.isEqualTo(other));
}
true
),
createBasisFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Map.function.notequals,
undefined,
[new AnyType()],
BooleanType.make(),
(requestor, evaluation) => {
const map = evaluation?.getClosure();
const other = evaluation.getInput(0);
return !(
map instanceof MapValue && other instanceof MapValue
)
? evaluation.getValueOrTypeException(
requestor,
MapType.make(),
other
)
: new BoolValue(requestor, !map.isEqualTo(other));
}
false
),
createBasisFunction(
locales,
Expand Down
23 changes: 11 additions & 12 deletions src/basis/NumberBasis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import NumberValue from '@values/NumberValue';
import TextValue from '@values/TextValue';
import TypeException from '@values/TypeException';
import type Value from '@values/Value';
import { createBasisConversion, createBasisFunction } from './Basis';
import {
createBasisConversion,
createBasisFunction,
createEqualsFunction,
} from './Basis';
import InternalExpression from './InternalExpression';
import type Evaluation from '@runtime/Evaluation';
import ListValue from '@values/ListValue';
Expand Down Expand Up @@ -368,21 +372,16 @@ export default function bootstrapNumber(locales: Locales) {
left.isEqualTo(right)
)
),
createBinaryOp(
createEqualsFunction(
locales,
(locale) => locale.basis.Number.function.equal,
NumberType.make((unit) => unit),
BooleanType.make(),
(requestor, left, right) =>
new BoolValue(requestor, left.isEqualTo(right))
true
),
createBinaryOp(
createEqualsFunction(
locales,
(locale) => locale.basis.Number.function.notequal,
NumberType.make((unit) => unit),
BooleanType.make(),
(requestor, left, right) =>
new BoolValue(requestor, !left.isEqualTo(right))
false
),

// Trigonometry
createUnaryOp(
(locale) => locale.basis.Number.function.cos,
Expand Down
2 changes: 2 additions & 0 deletions src/basis/SetBasis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ test.each([
['{1 2 3}.difference({3 4 5})', '{1 2}'],
['{1 2 3}.filter(ƒ(v) v % 2 = 1)', '{1 3}'],
['{1 2 3}.translate(ƒ(v) v + 2)', '{3 4 5}'],
['{1 2 3} = ø', '⊥'],
['{1 2 3} ≠ ø', '⊤'],
])('Expect %s to be %s', (code, value) => {
expect(evaluateCode(code)?.toString()).toBe(value);
});
45 changes: 9 additions & 36 deletions src/basis/SetBasis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import StructureDefinition from '@nodes/StructureDefinition';
import ListValue from '@values/ListValue';
import TextValue from '@values/TextValue';
import SetValue from '@values/SetValue';
import { createBasisConversion, createBasisFunction } from './Basis';
import {
createBasisConversion,
createBasisFunction,
createEqualsFunction,
} from './Basis';
import BoolValue from '@values/BoolValue';
import type Value from '@values/Value';
import type Evaluation from '@runtime/Evaluation';
Expand All @@ -21,7 +25,6 @@ import NumberType from '../nodes/NumberType';
import NumberValue from '@values/NumberValue';
import ListType from '../nodes/ListType';
import TextType from '../nodes/TextType';
import AnyType from '../nodes/AnyType';
import type Locales from '../locale/Locales';

export default function bootstrapSet(locales: Locales) {
Expand Down Expand Up @@ -67,45 +70,15 @@ export default function bootstrapSet(locales: Locales) {
);
}
),
createBasisFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Set.function.equals,
undefined,
[new AnyType()],
BooleanType.make(),
(requestor, evaluation) => {
const set = evaluation?.getClosure();
const other = evaluation.getInput(0);
return !(
set instanceof SetValue && other instanceof SetValue
)
? evaluation.getValueOrTypeException(
requestor,
SetType.make(),
other
)
: new BoolValue(requestor, set.isEqualTo(other));
}
true
),
createBasisFunction(
createEqualsFunction(
locales,
(locale) => locale.basis.Set.function.notequals,
undefined,
[new AnyType()],
BooleanType.make(),
(requestor, evaluation) => {
const set = evaluation?.getClosure();
const other = evaluation.getInput(0);
return !(
set instanceof SetValue && other instanceof SetValue
)
? evaluation.getValueOrTypeException(
requestor,
SetType.make(),
other
)
: new BoolValue(requestor, !set.isEqualTo(other));
}
false
),
createBasisFunction(
locales,
Expand Down
Loading

0 comments on commit 867f7e0

Please sign in to comment.