Skip to content

Commit

Permalink
Disable function expressions (#96)
Browse files Browse the repository at this point in the history
* Add failing test for disallowed function expression

* Disallow using old-school function definitions and named function declarations as expressions
  • Loading branch information
yyc authored Oct 19, 2018
1 parent cac3928 commit 615fb51
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
4 changes: 4 additions & 0 deletions src/__tests__/__snapshots__/disallowed_syntax.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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"`;
29 changes: 29 additions & 0 deletions src/__tests__/disallowed_syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
3 changes: 0 additions & 3 deletions src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ export const evaluators: { [nodeType: string]: Evaluator<es.Node> } = {
}
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)
},
Expand Down
5 changes: 3 additions & 2 deletions src/syntaxTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const syntaxTypes: { [nodeName: string]: number } = {
BinaryExpression: 1,
LogicalExpression: 1,
ConditionalExpression: 1,
FunctionExpression: 1,
ArrowFunctionExpression: 1,
Identifier: 1,
Literal: 1,
Expand Down Expand Up @@ -45,7 +44,9 @@ const syntaxTypes: { [nodeName: string]: number } = {
CatchClause: Infinity,
DoWhileStatement: Infinity,
ForInStatement: Infinity,
SequenceExpression: Infinity
SequenceExpression: Infinity,
FunctionExpression: Infinity,

}

export default syntaxTypes

0 comments on commit 615fb51

Please sign in to comment.