summaryrefslogtreecommitdiff
path: root/test/signature_match.spec.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test/signature_match.spec.ts')
-rw-r--r--test/signature_match.spec.ts160
1 files changed, 160 insertions, 0 deletions
diff --git a/test/signature_match.spec.ts b/test/signature_match.spec.ts
new file mode 100644
index 0000000..10be880
--- /dev/null
+++ b/test/signature_match.spec.ts
@@ -0,0 +1,160 @@
+import { expect, test } from 'bun:test';
+import { TestPrograms } from './programs';
+import { peggyParse } from '@/parser';
+import {
+ evaluate,
+ type DenotableFunctionSignature,
+ denotableTypesEquivalent,
+ matchSignature,
+} from '@/interpreter';
+import { testingLogger } from './logger';
+
+test('simple denotable types are equivalent', () => {
+ expect(denotableTypesEquivalent('int', 'int')).toBe(true);
+ expect(denotableTypesEquivalent('int', 'real')).toBe(false);
+ expect(denotableTypesEquivalent('int', 'null')).toBe(false);
+ expect(denotableTypesEquivalent('null', 'null')).toBe(true);
+});
+
+test('union data types are equivalent', () => {
+ expect(denotableTypesEquivalent(['int', 'real'], ['int', 'real'])).toBe(true);
+ expect(denotableTypesEquivalent('int', ['int', 'real'])).toBe(false);
+});
+
+test('function data types are equivalent', () => {
+ expect(
+ denotableTypesEquivalent(
+ [
+ {
+ arguments: ['int', 'real'],
+ return: 'int',
+ },
+ ],
+ [
+ {
+ arguments: ['int', 'real'],
+ return: 'int',
+ },
+ ],
+ ),
+ ).toBe(true);
+
+ expect(
+ denotableTypesEquivalent(
+ [
+ {
+ arguments: ['int', 'real'],
+ return: 'real',
+ },
+ ],
+ [
+ {
+ arguments: ['int', 'real'],
+ return: 'int',
+ },
+ ],
+ ),
+ ).toBe(false);
+});
+
+test('matches simple signatures', async () => {
+ const simpleSignature: DenotableFunctionSignature[] = [
+ {
+ arguments: ['int'],
+ return: 'int',
+ },
+ ];
+
+ expect(matchSignature(['int'], simpleSignature)).toEqual(simpleSignature[0]);
+});
+
+test('finds first match', async () => {
+ const simpleSignature: DenotableFunctionSignature[] = [
+ {
+ arguments: ['int', 'int'],
+ return: 'int',
+ },
+ {
+ arguments: [['int', 'real'], 'int'],
+ return: 'real',
+ },
+ ];
+
+ expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
+ simpleSignature[0],
+ );
+
+ expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
+ simpleSignature[1],
+ );
+});
+
+test('finds first match with a function signature', async () => {
+ const testSignature: DenotableFunctionSignature = {
+ arguments: ['int', 'real'],
+ return: 'int',
+ };
+
+ const simpleSignature: DenotableFunctionSignature[] = [
+ {
+ arguments: ['int', 'int'],
+ return: 'int',
+ },
+ {
+ arguments: [[testSignature, 'real'], 'int'],
+ return: 'function',
+ },
+ ];
+
+ expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
+ simpleSignature[0],
+ );
+
+ expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
+ simpleSignature[1],
+ );
+
+ expect(matchSignature([testSignature, 'int'], simpleSignature)).toEqual(
+ simpleSignature[1],
+ );
+});
+
+test('finds first match with a function with many signatures', async () => {
+ const testSignature: DenotableFunctionSignature[] = [
+ {
+ arguments: ['int', 'real'],
+ return: 'int',
+ },
+ {
+ arguments: ['int', 'int'],
+ return: 'int',
+ },
+ ];
+
+ const simpleSignature: DenotableFunctionSignature[] = [
+ {
+ arguments: ['int', 'int'],
+ return: 'int',
+ },
+ {
+ arguments: [[testSignature, 'real'], 'int'],
+ return: 'function',
+ },
+ ];
+
+ expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
+ simpleSignature[0],
+ );
+
+ expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
+ simpleSignature[1],
+ );
+
+ expect(matchSignature([testSignature, 'int'], simpleSignature)).toEqual(
+ simpleSignature[1],
+ );
+
+ expect(
+ matchSignature([[testSignature[0]], 'int'], simpleSignature),
+ ).toBeUndefined();
+});