diff --git a/package.json b/package.json index 09683ee83..9f97227eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-slang", - "version": "0.1.9", + "version": "0.1.10", "description": "Javascript-based interpreter for slang, written in Typescript", "author": { "name": "Source Academy", diff --git a/src/__tests__/__snapshots__/disallowed_syntax.ts.snap b/src/__tests__/__snapshots__/disallowed_syntax.ts.snap index f1d6c96ec..9fedeab82 100644 --- a/src/__tests__/__snapshots__/disallowed_syntax.ts.snap +++ b/src/__tests__/__snapshots__/disallowed_syntax.ts.snap @@ -8,4 +8,8 @@ exports[`Cannot leave blank expressions in for loops 3`] = `"Line 2: For stateme exports[`Cannot leave blank expressions in for loops 4`] = `"Line 2: For statement cannot have empty init,test,update expressions."`; +exports[`Cannot use js function expressions 1`] = `"Line 2: Function expressions are not allowed"`; + exports[`Cannot use update expressions 1`] = `"Line 3: Update expressions are not allowed"`; + +exports[`DEFINITELY CANNOT use named function declarations as expressions 1`] = `"Line 2: Function expressions are not allowed"`; diff --git a/src/__tests__/disallowed_syntax.ts b/src/__tests__/disallowed_syntax.ts index c6260d204..15550c0ee 100644 --- a/src/__tests__/disallowed_syntax.ts +++ b/src/__tests__/disallowed_syntax.ts @@ -57,3 +57,32 @@ test("Cannot use update expressions", () => { }); }); +test("Cannot use js function expressions", () => { + const code = ` + map(function(x) { + return x + 1; + }, list(1)); + `; + const context = mockContext(3); + const promise = runInContext(code, context, { scheduler: "preemptive" }); + return promise.then(obj => { + expect(obj.status).toBe("error"); + const errors = parseError(context.errors); + expect(errors).toMatchSnapshot(); + }); +}); + +test("DEFINITELY CANNOT use named function declarations as expressions", () => { + const code = ` + map(function a(x) { + return x + 1; + }, list(1)); + `; + const context = mockContext(3); + const promise = runInContext(code, context, { scheduler: "preemptive" }); + return promise.then(obj => { + expect(obj.status).toBe("error"); + const errors = parseError(context.errors); + expect(errors).toMatchSnapshot(); + }); +}); diff --git a/src/interpreter.ts b/src/interpreter.ts index 4df480e33..6a76a2a1b 100644 --- a/src/interpreter.ts +++ b/src/interpreter.ts @@ -175,9 +175,6 @@ export const evaluators: { [nodeType: string]: Evaluator } = { } return res }, - FunctionExpression: function*(node: es.FunctionExpression, context: Context) { - return new Closure(node, currentFrame(context), context) - }, ArrowFunctionExpression: function*(node: es.Function, context: Context) { return new ArrowClosure(node, currentFrame(context), context) }, diff --git a/src/syntaxTypes.ts b/src/syntaxTypes.ts index 134f3e40c..357c7861e 100644 --- a/src/syntaxTypes.ts +++ b/src/syntaxTypes.ts @@ -11,7 +11,6 @@ const syntaxTypes: { [nodeName: string]: number } = { BinaryExpression: 1, LogicalExpression: 1, ConditionalExpression: 1, - FunctionExpression: 1, ArrowFunctionExpression: 1, Identifier: 1, Literal: 1, @@ -45,7 +44,9 @@ const syntaxTypes: { [nodeName: string]: number } = { CatchClause: Infinity, DoWhileStatement: Infinity, ForInStatement: Infinity, - SequenceExpression: Infinity + SequenceExpression: Infinity, + FunctionExpression: Infinity, + } export default syntaxTypes