From c9dc50cb972652fa5e1ee0fcb422f3079fecb064 Mon Sep 17 00:00:00 2001 From: Lizzy Hunt Date: Wed, 28 Feb 2024 12:59:01 -0700 Subject: [PATCH] correct scope --- src/interpreter/builtins.ts | 1 - src/interpreter/interpreter.ts | 5 ++++- test/interpreter.spec.ts | 7 +++++++ test/parser.spec.ts | 32 +++++++++++++++++++++++++++++++- test/programs/add-1-3.cps | 2 +- test/programs/index.ts | 3 +++ test/programs/primop-scope.cps | 5 +++++ 7 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 test/programs/primop-scope.cps diff --git a/src/interpreter/builtins.ts b/src/interpreter/builtins.ts index c5769db..200131f 100644 --- a/src/interpreter/builtins.ts +++ b/src/interpreter/builtins.ts @@ -48,7 +48,6 @@ const addBinaryIntegerOperationsTo = (env: Environment) => { { name: '>', fn: (a: number, b: number) => (a > b ? 1 : 0) }, { name: '>=', fn: (a: number, b: number) => (a >= b ? 1 : 0) }, { name: '||', fn: (a: number, b: number) => (a || b ? 1 : 0) }, - { name: '==', fn: (a: number, b: number) => (a == b ? 1 : 0) }, ]) { env.set(name, { type: 'function', diff --git a/src/interpreter/interpreter.ts b/src/interpreter/interpreter.ts index 4a0be05..ebd605c 100644 --- a/src/interpreter/interpreter.ts +++ b/src/interpreter/interpreter.ts @@ -52,6 +52,9 @@ const evaluatePrimitiveOperation = ( const result = env.apply(opr, operandValues); const continuationEnvironment = env.createChild(); + for (const { name } of resultBindings) { + continuationEnvironment.set(name, result); + } // return the result of the last continuation return continuations.reduce((_, continuation, i) => { @@ -107,7 +110,7 @@ export const evaluate = async ( logger: TracingLogger, ): Promise => { const globalEnvironment = putBuiltinsOnEnvironemtn( - new Environment(logger.createChild('Root')), + new Environment(logger.createChild('RootEnv')), ); return ast.reduce((_, continuation, i) => { diff --git a/test/interpreter.spec.ts b/test/interpreter.spec.ts index 0da25c3..fa74ef0 100644 --- a/test/interpreter.spec.ts +++ b/test/interpreter.spec.ts @@ -11,6 +11,13 @@ test('Add (1 real) and (3 int) => (4 real)', async () => { 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); diff --git a/test/parser.spec.ts b/test/parser.spec.ts index 385a4dc..07353b8 100644 --- a/test/parser.spec.ts +++ b/test/parser.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from 'bun:test'; import { TestPrograms } from './programs'; import { peggyParse } from '@/parser'; -test('Primitive Operations', async () => { +test('primitive operation', async () => { const [operation] = peggyParse(await TestPrograms.AddOneThree); const { primitiveOperation } = operation; @@ -13,3 +13,33 @@ test('Primitive Operations', async () => { 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 e890aca..66759f7 100644 --- a/test/programs/add-1-3.cps +++ b/test/programs/add-1-3.cps @@ -1 +1 @@ -PRIMOP(+, [REAL 1, INT 3], [result], []) \ 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 6dcd873..c8f3c85 100644 --- a/test/programs/index.ts +++ b/test/programs/index.ts @@ -4,6 +4,9 @@ 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(); 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