Skip to content

Commit

Permalink
Resolver now catches edge case that Becca pointed out to me.
Browse files Browse the repository at this point in the history
  • Loading branch information
quephird committed Mar 17, 2024
1 parent ab2fa9b commit 18b1578
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
4 changes: 2 additions & 2 deletions slox/Interpreter.swift
Expand Up @@ -279,13 +279,13 @@ class Interpreter {
break
} catch JumpType.continue {
if let incrementExpr {
let _ = try evaluate(expr: incrementExpr)
_ = try evaluate(expr: incrementExpr)
}
continue
}

if let incrementExpr {
let _ = try evaluate(expr: incrementExpr)
_ = try evaluate(expr: incrementExpr)
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions slox/Resolver.swift
Expand Up @@ -105,9 +105,12 @@ struct Resolver {
methods: [Statement],
staticMethods: [Statement]) throws -> ResolvedStatement {
let previousClassType = currentClassType
let previousLoopType = currentLoopType
currentClassType = .class
currentLoopType = .none
defer {
currentClassType = previousClassType
currentLoopType = previousLoopType
}

try declareVariable(name: nameToken.lexeme)
Expand Down Expand Up @@ -421,10 +424,13 @@ struct Resolver {
functionType: FunctionType) throws -> ResolvedExpression {
beginScope()
let previousFunctionType = currentFunctionType
let previousLoopType = currentLoopType
currentFunctionType = functionType
currentLoopType = .none
defer {
endScope()
currentFunctionType = previousFunctionType
currentLoopType = previousLoopType
}

for param in params {
Expand Down
33 changes: 33 additions & 0 deletions sloxTests/ResolverTests.swift
Expand Up @@ -465,4 +465,37 @@ final class ResolverTests: XCTestCase {
XCTAssertEqual(actualError as! ResolverError, expectedError)
}
}

func testResolveBreakStatementFunctionInsideWhileLoop() throws {
// while (true) {
// fun foo() {
// break;
// }
// foo();
//}
let statements: [Statement] = [
.while(
.literal(.boolean(true)),
.block([
.function(
Token(type: .identifier, lexeme: "foo", line: 2),
.lambda(
[],
[
.break(Token(type: .break, lexeme: "break", line: 3))
])),
.expression(
.call(
.variable(Token(type: .identifier, lexeme: "foo", line: 5)),
Token(type: .rightParen, lexeme: ")", line: 5),
[]))
]))
]

var resolver = Resolver()
let expectedError = ResolverError.cannotBreakOutsideLoop
XCTAssertThrowsError(try resolver.resolve(statements: statements)) { actualError in
XCTAssertEqual(actualError as! ResolverError, expectedError)
}
}
}

0 comments on commit 18b1578

Please sign in to comment.