diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-02-28 14:59:28 -0500 |
---|---|---|
committer | simponic <elizabeth.hunt@simponic.xyz> | 2024-02-28 14:59:28 -0500 |
commit | 7cc3ef5fa1feec8087618c899441a11052f84c48 (patch) | |
tree | 6d65d585fcf61e9cee7193dfb2af4d719074f732 /test | |
parent | c8336ee48791f00378a35e463e2962f4c856beb2 (diff) | |
download | cps-interpreter-7cc3ef5fa1feec8087618c899441a11052f84c48.tar.gz cps-interpreter-7cc3ef5fa1feec8087618c899441a11052f84c48.zip |
builtin_match_signatures (#1)
Co-authored-by: Lizzy Hunt <lizzy.hunt@usu.edu>
Reviewed-on: https://git.simponic.xyz/simponic/cps-interpreter/pulls/1
Co-authored-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Co-committed-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Diffstat (limited to 'test')
-rw-r--r-- | test/interpreter.spec.ts | 35 | ||||
-rw-r--r-- | test/parser.spec.ts | 42 | ||||
-rw-r--r-- | test/programs/add-1-3.cps | 3 | ||||
-rw-r--r-- | test/programs/index.ts | 9 | ||||
-rw-r--r-- | test/programs/primop-scope.cps | 5 | ||||
-rw-r--r-- | test/programs/string-equal.cps | 1 | ||||
-rw-r--r-- | test/programs/string-unequal.cps | 1 | ||||
-rw-r--r-- | test/signature_match.spec.ts | 160 |
8 files changed, 252 insertions, 4 deletions
diff --git a/test/interpreter.spec.ts b/test/interpreter.spec.ts new file mode 100644 index 0000000..fa74ef0 --- /dev/null +++ b/test/interpreter.spec.ts @@ -0,0 +1,35 @@ +import { expect, test } from 'bun:test'; +import { TestPrograms } from './programs'; +import { peggyParse } from '@/parser'; +import { evaluate } from '@/interpreter'; +import { testingLogger } from './logger'; + +test('Add (1 real) and (3 int) => (4 real)', async () => { + const ast = peggyParse(await TestPrograms.AddOneThree); + + const result = await evaluate(ast, testingLogger); + expect(result).toEqual({ type: 'real', value: 4 }); +}); + +test('Add (1 real) and (3 int) -> result => (real 1 - result) = -3 done with correct lexical scope', async () => { + const ast = peggyParse(await TestPrograms.PrimopScope); + + const result = await evaluate(ast, testingLogger); + expect(result).toEqual({ type: 'real', value: -3 }); +}); + +/* +test('String equality', async () => { + const ast = peggyParse(await TestPrograms.StringEquality); + + const result = await evaluate(ast, testingLogger); + expect(result).toEqual({ type: 'int', value: 1 }); +}); + +test('String inequality', async () => { + const ast = peggyParse(await TestPrograms.StringInEquality); + + const result = await evaluate(ast, testingLogger); + expect(result).toEqual({ type: 'int', value: 0 }); +}); +*/ diff --git a/test/parser.spec.ts b/test/parser.spec.ts index e174383..07353b8 100644 --- a/test/parser.spec.ts +++ b/test/parser.spec.ts @@ -2,6 +2,44 @@ import { expect, test } from 'bun:test'; import { TestPrograms } from './programs'; import { peggyParse } from '@/parser'; -test('Primitive Operations', async () => { - const ast = peggyParse(await TestPrograms.AddOneThree); +test('primitive operation', async () => { + const [operation] = peggyParse(await TestPrograms.AddOneThree); + const { primitiveOperation } = operation; + + expect(primitiveOperation).toEqual({ + opr: '+', + operands: [{ real: 1 }, { int: 3 }], + resultBindings: [{ name: 'result' }], + continuations: [], + }); +}); + +test('primitive operation with continuation', async () => { + const [operation] = peggyParse(await TestPrograms.PrimopScope); + const { primitiveOperation } = operation; + + const continuation = { + primitiveOperation: { + opr: '-', + operands: [{ real: 1 }, { name: 'result' }], + resultBindings: [{ name: 'result' }], + continuations: [ + { + primitiveOperation: { + opr: '+', + operands: [{ name: 'result' }, { real: 0 }], + resultBindings: [], + continuations: [], + }, + }, + ], + }, + }; + + expect(primitiveOperation).toEqual({ + opr: '+', + operands: [{ real: 1 }, { int: 3 }], + resultBindings: [{ name: 'result' }], + continuations: [continuation], + }); }); diff --git a/test/programs/add-1-3.cps b/test/programs/add-1-3.cps index 95b9939..66759f7 100644 --- a/test/programs/add-1-3.cps +++ b/test/programs/add-1-3.cps @@ -1,2 +1 @@ -PRIMOP(+, [INT 1, INT 2], [u], - [APP(LABEL identity, [VAR u])])
\ No newline at end of file +PRIMOP(+, [REAL 1.0, INT 3], [result], [])
\ No newline at end of file diff --git a/test/programs/index.ts b/test/programs/index.ts index e0403fd..c8f3c85 100644 --- a/test/programs/index.ts +++ b/test/programs/index.ts @@ -4,4 +4,13 @@ export namespace TestPrograms { export const AddOneThree = Bun.file( join(import.meta.dir + '/add-1-3.cps'), ).text(); + export const PrimopScope = Bun.file( + join(import.meta.dir + '/primop-scope.cps'), + ).text(); + export const StringEquality = Bun.file( + join(import.meta.dir + '/string-equal.cps'), + ).text(); + export const StringInEquality = Bun.file( + join(import.meta.dir + '/string-unequal.cps'), + ).text(); } diff --git a/test/programs/primop-scope.cps b/test/programs/primop-scope.cps new file mode 100644 index 0000000..eb834fd --- /dev/null +++ b/test/programs/primop-scope.cps @@ -0,0 +1,5 @@ +PRIMOP(+, [REAL 1.0, INT 3], [result], [ + PRIMOP(-, [REAL 1.0, VAR result], [result], [ + PRIMOP(+, [VAR result, REAL 0], [], []) + ]) +])
\ No newline at end of file diff --git a/test/programs/string-equal.cps b/test/programs/string-equal.cps new file mode 100644 index 0000000..ea49b22 --- /dev/null +++ b/test/programs/string-equal.cps @@ -0,0 +1 @@ +PRIMOP(==, ["asdf", "asdf"], [result], [])
\ No newline at end of file diff --git a/test/programs/string-unequal.cps b/test/programs/string-unequal.cps new file mode 100644 index 0000000..ccd278e --- /dev/null +++ b/test/programs/string-unequal.cps @@ -0,0 +1 @@ +PRIMOP(==, ["asdfasdf", "asdf"], [result], []) 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(); +}); |