Skip to content

Commit

Permalink
Merge pull request #104 from Kacarott/v1.1
Browse files Browse the repository at this point in the history
Fix compiler bug
  • Loading branch information
Kacarott authored Feb 1, 2024
2 parents 0c44a2a + d8546b0 commit 9bc1db1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/lambda-calculus.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,16 @@ export function compile(code) {
function evalLC(term) {

// builds function to return to user ( representing an abstraction awaiting input )
function awaitArg(term, stack, env) {
function awaitArg(term, env) {
// callback function which will evaluate term.body in an env with the input
function result(arg) {
let argEnv;
if ( arg?.term && arg?.env ) ({ term: arg, env: argEnv } = arg); // if callback is passed another callback, or a term
const termVal = new Tuple( typeof arg === 'number' ? fromInt(arg) : arg , new Env(argEnv) );
if ( term.name==="_" )
return runEval( new Tuple(term.body, new Env(env)), stack );
return runEval( new Tuple(term.body, new Env(env)) );
else
return runEval( new Tuple(term.body, new Env(env).setThunk(term.name, termVal)), stack );
return runEval( new Tuple(term.body, new Env(env).setThunk(term.name, termVal)) );
}
return Object.assign( result, {term,env} );
}
Expand All @@ -363,8 +363,8 @@ function evalLC(term) {
// isRight :: bool (indicating whether the term is left or right side of an Application)
// isEvaluated :: bool (indicating whether the current term should be stored in the Env)
// callstack :: [String] (History of var lookups, for better error messages)
function runEval({term,env},stack) { // stack: [[term, isRight, isEvaluated]], term: LC term, env = Env { name => term }
const callstack = []; // Does not persist between requests for arguments
function runEval({term,env}) { // stack: [[term, isRight, isEvaluated]], term: LC term, env = Env { name => term }
const callstack = [], stack = []; // Does not persist between requests for arguments
while ( ! ( term instanceof L ) || stack.length > 0 ) {
if ( term instanceof V )
if ( term.name==="()" )
Expand All @@ -377,7 +377,7 @@ function evalLC(term) {
else {
if (res.term instanceof V || res.term instanceof A)
// Push a frame to the stack to indicate when the value should be stored back
stack.push( [new Tuple( term, env ), false, true ] );
stack.push( [new Tuple( term, env ), true, true ] );
({term, env} = res);
}
}
Expand All @@ -395,7 +395,7 @@ function evalLC(term) {
env = new Env(env).setThunk(term.name, new Tuple(lastTerm, lastEnv));
term = term.body;
} else { // Pass the function some other function.
term = lastTerm(awaitArg(term, [], env));
term = lastTerm(awaitArg(term, env));
}
} else if ( term instanceof Tuple ) {
// for primitives
Expand All @@ -421,9 +421,9 @@ function evalLC(term) {
}
}
// We need input
return awaitArg(term, stack, env);
return awaitArg(term, env);
}
return runEval(term, []);
return runEval(term);
}

// Print an error, with stack trace according to verbosity level
Expand Down
1 change: 1 addition & 0 deletions tests/known-bugs/solution.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo = \ x j c . x c ()
18 changes: 18 additions & 0 deletions tests/known-bugs/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {readFileSync} from "fs";
import {assert, config as chaiConfig} from "chai";
chaiConfig.truncateThreshold = 0;

import * as LC from "../../src/lambda-calculus.js";
LC.configure({ purity: "Let", numEncoding: "None" });

const solutionText = readFileSync(new URL("./solution.txt", import.meta.url), {encoding: "utf8"});
const { foo } = LC.compile(solutionText);

describe("No side effects", () => {
it("The initial failed call used to cause the second call to behave weirdly", () => {
try {
foo("hi")("there")("world")
} catch {}
assert.strictEqual( foo(null).term.toString(), "\\ j c . x c ()" );
});
});

0 comments on commit 9bc1db1

Please sign in to comment.