Skip to content

Commit

Permalink
Nested break/continue statement detection fixes (#1545)
Browse files Browse the repository at this point in the history
* Check for break/continue statements in child blocks

* Update tests

---------

Co-authored-by: Richard Dominick <[email protected]>
  • Loading branch information
DiligentPenguinn and RichDom2185 authored Feb 18, 2024
1 parent 9f82165 commit 32b7f64
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 2 deletions.
60 changes: 60 additions & 0 deletions src/cse-machine/__tests__/__snapshots__/cse-machine.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,66 @@ f(5000, 5000);",
}
`;

exports[`breaks, continues are properly detected in child blocks 1: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "let i = 0;
for (i = 1; i < 5; i = i + 1) {
{
const a = i;
if (i === 1) {
continue;
}
}
{
const a = i;
if (i === 2) {
break;
}
}
}
i;",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": 2,
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`breaks, continues are properly detected in child blocks 2: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "let a = 0;
for (let i = 1; i < 5; i = i + 1) {
{
const x = 0;
a = i;
if (i === 1) {
continue;
}
}
{
const x = 0;
a = i;
if (i === 2) {
break;
}
}
}
a;",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": 2,
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`const uses block scoping instead of function scoping: expectResult 1`] = `
Object {
"alertResult": Array [],
Expand Down
52 changes: 52 additions & 0 deletions src/cse-machine/__tests__/cse-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,55 @@ test('Environment reset is inserted when only instructions are in control stack'
optionEC3
).toMatchInlineSnapshot(`undefined`)
})

test('breaks, continues are properly detected in child blocks 1', () => {
return expectResult(
stripIndent`
let i = 0;
for (i = 1; i < 5; i = i + 1) {
{
const a = i;
if (i === 1) {
continue;
}
}
{
const a = i;
if (i === 2) {
break;
}
}
}
i;
`,
optionEC3
).toMatchInlineSnapshot(`2`)
})

test('breaks, continues are properly detected in child blocks 2', () => {
return expectResult(
stripIndent`
let a = 0;
for (let i = 1; i < 5; i = i + 1) {
{
const x = 0;
a = i;
if (i === 1) {
continue;
}
}
{
const x = 0;
a = i;
if (i === 2) {
break;
}
}
}
a;
`,
optionEC3
).toMatchInlineSnapshot(`2`)
})
8 changes: 6 additions & 2 deletions src/cse-machine/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ export const hasBreakStatementIf = (statement: es.IfStatement): boolean => {
}

/**
* Checks whether a block has a `break` statement.
* Checks whether a block OR any of its child blocks has a `break` statement.
* @param body The block to be checked
* @return `true` if there is a `break` statement, else `false`.
*/
Expand All @@ -584,6 +584,8 @@ export const hasBreakStatement = (block: es.BlockStatement): boolean => {
} else if (isIfStatement(statement)) {
// Parser enforces that if/else have braces (block statement)
hasBreak = hasBreak || hasBreakStatementIf(statement as es.IfStatement)
} else if (isBlockStatement(statement)) {
hasBreak = hasBreak || hasBreakStatement(statement as es.BlockStatement)
}
}
return hasBreak
Expand All @@ -604,7 +606,7 @@ export const hasContinueStatementIf = (statement: es.IfStatement): boolean => {
}

/**
* Checks whether a block has a `continue` statement.
* Checks whether a block OR any of its child blocks has a `continue` statement.
* @param body The block to be checked
* @return `true` if there is a `continue` statement, else `false`.
*/
Expand All @@ -616,6 +618,8 @@ export const hasContinueStatement = (block: es.BlockStatement): boolean => {
} else if (isIfStatement(statement)) {
// Parser enforces that if/else have braces (block statement)
hasContinue = hasContinue || hasContinueStatementIf(statement as es.IfStatement)
} else if (isBlockStatement(statement)) {
hasContinue = hasContinue || hasContinueStatement(statement as es.BlockStatement)
}
}
return hasContinue
Expand Down

0 comments on commit 32b7f64

Please sign in to comment.