Repository: source-academy/js-slang (ts)

Issue:
Repeated parameters: forbidden in strict-mode-JS, allowed in Source?
The current playground allows

```
function f(x, x) { 
    1;
}
```

I think this should be forbidden, as in strict-mode-JS.

Pull request description:
Change acorn sourceType from 'script' to 'module'
Resolves #146.

Patch:
diff --git a/package.json b/package.json
index d306cae6..6d188163 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "js-slang",
-  "version": "0.1.19",
+  "version": "0.2.0-alpha",
   "description": "Javascript-based interpreter for slang, written in Typescript",
   "author": {
     "name": "Source Academy",
diff --git a/src/parser.ts b/src/parser.ts
index f69a67cf..c654bca7 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -123,7 +123,7 @@ export function parse(source: string, context: Context) {
 }
 
 const createAcornParserOptions = (context: Context): AcornOptions => ({
-  sourceType: 'script',
+  sourceType: 'module',
   ecmaVersion: 6,
   locations: true,
   // tslint:disable-next-line:no-any


Test patch:
diff --git a/src/__tests__/__snapshots__/disallowed_syntax.ts.snap b/src/__tests__/__snapshots__/disallowed_syntax.ts.snap
index 5a715efc..079758d3 100644
--- a/src/__tests__/__snapshots__/disallowed_syntax.ts.snap
+++ b/src/__tests__/__snapshots__/disallowed_syntax.ts.snap
@@ -73,11 +73,11 @@ Line 2: Class declarations are not allowed"
 
 exports[`no debugger statement 1`] = `"Line 2: Debugger statements are not allowed"`;
 
-exports[`no export constant 1`] = `"Line 2: SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (2:4)"`;
+exports[`no export constant 1`] = `"Line 2: Export named declarations are not allowed"`;
 
-exports[`no export default 1`] = `"Line 3: SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (3:4)"`;
+exports[`no export default 1`] = `"Line 3: Export default declarations are not allowed"`;
 
-exports[`no export function 1`] = `"Line 2: SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (2:4)"`;
+exports[`no export function 1`] = `"Line 2: Export named declarations are not allowed"`;
 
 exports[`no for in loops 1`] = `
 "Line 2: Missing value in variable declaration
@@ -91,15 +91,20 @@ Line 2: For of statements are not allowed"
 
 exports[`no generator functions 1`] = `"Line 3: Yield expressions are not allowed"`;
 
-exports[`no import 1`] = `"Line 2: SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (2:4)"`;
+exports[`no import 1`] = `
+"Line 2: Import specifiers are not allowed
+Line 2: Import declarations are not allowed"
+`;
 
-exports[`no interface 1`] = `"Line 2: SyntaxError: Unexpected token (2:14)"`;
+exports[`no interface 1`] = `"Line 2: SyntaxError: The keyword 'interface' is reserved (2:4)"`;
 
 exports[`no regexp 1`] = `
 "Line 1: Missing semicolon at the end of statement
 Line 1: 'RegExp' literals are not allowed"
 `;
 
+exports[`no repeated params 1`] = `"Line 2: SyntaxError: Argument name clash (2:18)"`;
+
 exports[`no sequence expression 1`] = `"Line 2: Sequence expressions are not allowed"`;
 
 exports[`no super 1`] = `
diff --git a/src/__tests__/disallowed_syntax.ts b/src/__tests__/disallowed_syntax.ts
index e3640241..3f9064cc 100644
--- a/src/__tests__/disallowed_syntax.ts
+++ b/src/__tests__/disallowed_syntax.ts
@@ -503,7 +503,7 @@ test('no export default', () => {
 
 test('no import', () => {
   const code = `
-    import { stripIndent } from 'common-tags'
+    import { stripIndent } from 'common-tags';
   `
   const context = mockContext(100)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
@@ -605,3 +605,18 @@ test('no unspecified unary operators', () => {
     expect(errors).toMatchSnapshot()
   })
 })
+
+test('no repeated params', () => {
+  const code = `
+    function f(x, x) {
+      return x;
+    }
+  `
+  const context = mockContext(100)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('error')
+    const errors = parseError(context.errors)
+    expect(errors).toMatchSnapshot()
+  })
+})