correct scope
This commit is contained in:
parent
68745f5b94
commit
c9dc50cb97
@ -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) },
|
||||||
{ 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, {
|
env.set(name, {
|
||||||
type: 'function',
|
type: 'function',
|
||||||
|
@ -52,6 +52,9 @@ const evaluatePrimitiveOperation = (
|
|||||||
|
|
||||||
const result = env.apply(opr, operandValues);
|
const result = env.apply(opr, operandValues);
|
||||||
const continuationEnvironment = env.createChild();
|
const continuationEnvironment = env.createChild();
|
||||||
|
for (const { name } of resultBindings) {
|
||||||
|
continuationEnvironment.set(name, result);
|
||||||
|
}
|
||||||
|
|
||||||
// return the result of the last continuation
|
// return the result of the last continuation
|
||||||
return continuations.reduce((_, continuation, i) => {
|
return continuations.reduce((_, continuation, i) => {
|
||||||
@ -107,7 +110,7 @@ export const evaluate = async (
|
|||||||
logger: TracingLogger,
|
logger: TracingLogger,
|
||||||
): Promise<Denotable> => {
|
): Promise<Denotable> => {
|
||||||
const globalEnvironment = putBuiltinsOnEnvironemtn(
|
const globalEnvironment = putBuiltinsOnEnvironemtn(
|
||||||
new Environment(logger.createChild('Root')),
|
new Environment(logger.createChild('RootEnv')),
|
||||||
);
|
);
|
||||||
|
|
||||||
return ast.reduce((_, continuation, i) => {
|
return ast.reduce((_, continuation, i) => {
|
||||||
|
@ -11,6 +11,13 @@ test('Add (1 real) and (3 int) => (4 real)', async () => {
|
|||||||
expect(result).toEqual({ type: 'real', value: 4 });
|
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 () => {
|
test('String equality', async () => {
|
||||||
const ast = peggyParse(await TestPrograms.StringEquality);
|
const ast = peggyParse(await TestPrograms.StringEquality);
|
||||||
|
@ -2,7 +2,7 @@ import { expect, test } from 'bun:test';
|
|||||||
import { TestPrograms } from './programs';
|
import { TestPrograms } from './programs';
|
||||||
import { peggyParse } from '@/parser';
|
import { peggyParse } from '@/parser';
|
||||||
|
|
||||||
test('Primitive Operations', async () => {
|
test('primitive operation', async () => {
|
||||||
const [operation] = peggyParse(await TestPrograms.AddOneThree);
|
const [operation] = peggyParse(await TestPrograms.AddOneThree);
|
||||||
const { primitiveOperation } = operation;
|
const { primitiveOperation } = operation;
|
||||||
|
|
||||||
@ -13,3 +13,33 @@ test('Primitive Operations', async () => {
|
|||||||
continuations: [],
|
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],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -1 +1 @@
|
|||||||
PRIMOP(+, [REAL 1, INT 3], [result], [])
|
PRIMOP(+, [REAL 1.0, INT 3], [result], [])
|
@ -4,6 +4,9 @@ export namespace TestPrograms {
|
|||||||
export const AddOneThree = Bun.file(
|
export const AddOneThree = Bun.file(
|
||||||
join(import.meta.dir + '/add-1-3.cps'),
|
join(import.meta.dir + '/add-1-3.cps'),
|
||||||
).text();
|
).text();
|
||||||
|
export const PrimopScope = Bun.file(
|
||||||
|
join(import.meta.dir + '/primop-scope.cps'),
|
||||||
|
).text();
|
||||||
export const StringEquality = Bun.file(
|
export const StringEquality = Bun.file(
|
||||||
join(import.meta.dir + '/string-equal.cps'),
|
join(import.meta.dir + '/string-equal.cps'),
|
||||||
).text();
|
).text();
|
||||||
|
5
test/programs/primop-scope.cps
Normal file
5
test/programs/primop-scope.cps
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
PRIMOP(+, [REAL 1.0, INT 3], [result], [
|
||||||
|
PRIMOP(-, [REAL 1.0, VAR result], [result], [
|
||||||
|
PRIMOP(+, [VAR result, REAL 0], [], [])
|
||||||
|
])
|
||||||
|
])
|
Loading…
Reference in New Issue
Block a user