Skip to content

Commit

Permalink
Merge pull request #28 from quephird/support_adding_two_lists
Browse files Browse the repository at this point in the history
Support adding two lists
  • Loading branch information
quephird committed Mar 23, 2024
2 parents 7c68a60 + 2c69877 commit e97408a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
26 changes: 18 additions & 8 deletions slox/Interpreter.swift
Expand Up @@ -384,13 +384,20 @@ class Interpreter {
return .string(leftString + rightString)
}

if case .instance(let leftList as LoxList) = leftValue,
case .instance(let rightList as LoxList) = rightValue,
case .plus = oper.type {
let newElements = leftList.elements + rightList.elements
return try makeList(elements: newElements)
}

switch oper.type {
case .bangEqual:
return .boolean(!leftValue.isEqual(to: rightValue))
case .equalEqual:
return .boolean(leftValue.isEqual(to: rightValue))
case .plus:
throw RuntimeError.binaryOperandsMustBeNumbersOrStrings
throw RuntimeError.binaryOperandsMustBeNumbersOrStringsOrLists
case .minus, .star, .slash, .greater, .greaterEqual, .less, .lessEqual:
throw RuntimeError.binaryOperandsMustBeNumbers
default:
Expand Down Expand Up @@ -518,13 +525,7 @@ class Interpreter {
return try evaluate(expr: element)
}

guard case .instance(let listClass as LoxClass) = try environment.getValue(name: "List") else {
// TODO: Do we need throw an exception here?
fatalError()
}

let list = LoxList(elements: elementValues, klass: listClass)
return .instance(list)
return try makeList(elements: elementValues)
}

private func handleSubscriptGetExpression(listExpr: ResolvedExpression,
Expand Down Expand Up @@ -556,4 +557,13 @@ class Interpreter {
list[Int(index)] = value
return value
}

private func makeList(elements: [LoxValue]) throws -> LoxValue {
guard case .instance(let listClass as LoxClass) = try environment.getValue(name: "List") else {
fatalError()
}

let list = LoxList(elements: elements, klass: listClass)
return .instance(list)
}
}
6 changes: 3 additions & 3 deletions slox/RuntimeError.swift
Expand Up @@ -11,7 +11,7 @@ enum RuntimeError: CustomStringConvertible, Equatable, LocalizedError {
case unaryOperandMustBeNumber
case unsupportedUnaryOperator
case binaryOperandsMustBeNumbers
case binaryOperandsMustBeNumbersOrStrings
case binaryOperandsMustBeNumbersOrStringsOrLists
case unsupportedBinaryOperator
case undefinedVariable(String)
case notAFunctionDeclaration
Expand All @@ -34,8 +34,8 @@ enum RuntimeError: CustomStringConvertible, Equatable, LocalizedError {
return "Error: unsupported unary operator"
case .binaryOperandsMustBeNumbers:
return "Error: operands must be both numbers"
case .binaryOperandsMustBeNumbersOrStrings:
return "Error: operands must be either both numbers or both strings"
case .binaryOperandsMustBeNumbersOrStringsOrLists:
return "Error: operands must be either both numbers, strings, or lists"
case .unsupportedBinaryOperator:
return "Error: unsupported binary operator"
case .undefinedVariable(let name):
Expand Down
23 changes: 23 additions & 0 deletions sloxTests/InterpreterTests.swift
Expand Up @@ -479,6 +479,29 @@ quux.count
XCTAssertEqual(actual, expected)
}

func testInterpretAddingTwoLists() throws {
let input = """
var xyzzy = [1, 2, 3] + [4, 5, 6];
xyzzy
"""

let interpreter = Interpreter()
guard case .instance(let list as LoxList) = try interpreter.interpretRepl(source: input) else {
XCTFail()
return
}
let actual = list.elements
let expected: [LoxValue] = [
.number(1),
.number(2),
.number(3),
.number(4),
.number(5),
.number(6),
]
XCTAssertEqual(actual, expected)
}

func testInterpretExpressionWithListSubscriptingMethodInvocationAndPropertyGetting() throws {
let input = """
class Foo { }
Expand Down

0 comments on commit e97408a

Please sign in to comment.