157 lines
3.5 KiB
TypeScript
157 lines
3.5 KiB
TypeScript
import { expect, test } from 'bun:test';
|
|
import {
|
|
type DenotableFunctionSignature,
|
|
denotableTypesEquivalent,
|
|
matchSignature,
|
|
} from '@/interpreter';
|
|
|
|
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();
|
|
});
|