diff options
Diffstat (limited to 'test/signature_match.spec.ts')
-rw-r--r-- | test/signature_match.spec.ts | 160 |
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(); +}); |