cps-interpreter/test/signature_match.spec.ts
Elizabeth Hunt 7cc3ef5fa1 builtin_match_signatures (#1)
Co-authored-by: Lizzy Hunt <lizzy.hunt@usu.edu>
Reviewed-on: #1
Co-authored-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Co-committed-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
2024-02-28 14:59:28 -05:00

161 lines
3.6 KiB
TypeScript

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();
});