diff --git a/slox/Interpreter.swift b/slox/Interpreter.swift index 24910b7..4bc102a 100644 --- a/slox/Interpreter.swift +++ b/slox/Interpreter.swift @@ -336,11 +336,14 @@ class Interpreter { switch oper.type { case .minus: - guard case .number(let number) = value else { + switch value { + case .double(let number): + return .double(-number) + case .int(let number): + return .int(-number) + default: throw RuntimeError.unaryOperandMustBeNumber } - - return .number(-number) case .bang: return .boolean(!value.isTruthy) default: @@ -354,17 +357,17 @@ class Interpreter { let leftValue = try evaluate(expr: leftExpr) let rightValue = try evaluate(expr: rightExpr) - if case .number(let leftNumber) = leftValue, - case .number(let rightNumber) = rightValue { + switch (leftValue, rightValue) { + case (.int(let leftNumber), .int(let rightNumber)): switch oper.type { case .plus: - return .number(leftNumber + rightNumber) + return .int(leftNumber + rightNumber) case .minus: - return .number(leftNumber - rightNumber) + return .int(leftNumber - rightNumber) case .star: - return .number(leftNumber * rightNumber) + return .int(leftNumber * rightNumber) case .slash: - return .number(leftNumber / rightNumber) + return .int(leftNumber / rightNumber) case .greater: return .boolean(leftNumber > rightNumber) case .greaterEqual: @@ -376,19 +379,47 @@ class Interpreter { default: break } - } - - if case .string(let leftString) = leftValue, - case .string(let rightString) = rightValue, - case .plus = oper.type { - return .string(leftString + rightString) - } + case (.int, .double), (.double, .int), (.double, .double): + let leftNumber = try leftValue.convertToRawDouble() + let rightNumber = try rightValue.convertToRawDouble() - 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 .plus: + return .double(leftNumber + rightNumber) + case .minus: + return .double(leftNumber - rightNumber) + case .star: + return .double(leftNumber * rightNumber) + case .slash: + return .double(leftNumber / rightNumber) + case .greater: + return .boolean(leftNumber > rightNumber) + case .greaterEqual: + return .boolean(leftNumber >= rightNumber) + case .less: + return .boolean(leftNumber < rightNumber) + case .lessEqual: + return .boolean(leftNumber <= rightNumber) + default: + break + } + case (.string(let leftString), .string(let rightString)): + switch oper.type { + case .plus: + return .string(leftString + rightString) + default: + break + } + case (.instance(let leftList as LoxList), .instance(let rightList as LoxList)): + switch oper.type { + case .plus: + let newElements = leftList.elements + rightList.elements + return try makeList(elements: newElements) + default: + break + } + default: + break } switch oper.type { @@ -534,8 +565,8 @@ class Interpreter { throw RuntimeError.notAList } - guard case .number(let index) = try evaluate(expr: indexExpr) else { - throw RuntimeError.indexMustBeANumber + guard case .int(let index) = try evaluate(expr: indexExpr) else { + throw RuntimeError.indexMustBeAnInteger } return list[Int(index)] @@ -548,8 +579,8 @@ class Interpreter { throw RuntimeError.notAList } - guard case .number(let index) = try evaluate(expr: indexExpr) else { - throw RuntimeError.indexMustBeANumber + guard case .int(let index) = try evaluate(expr: indexExpr) else { + throw RuntimeError.indexMustBeAnInteger } let value = try evaluate(expr: valueExpr) diff --git a/slox/LoxList.swift b/slox/LoxList.swift index d315847..732e15b 100644 --- a/slox/LoxList.swift +++ b/slox/LoxList.swift @@ -19,7 +19,7 @@ class LoxList: LoxInstance { override func get(propertyName: String) throws -> LoxValue { switch propertyName { case "count": - return .number(Double(elements.count)) + return .int(elements.count) default: return try super.get(propertyName: propertyName) } diff --git a/slox/LoxValue.swift b/slox/LoxValue.swift index 318435a..dcc5ec4 100644 --- a/slox/LoxValue.swift +++ b/slox/LoxValue.swift @@ -7,7 +7,8 @@ enum LoxValue: CustomStringConvertible, Equatable { case string(String) - case number(Double) + case double(Double) + case int(Int) case boolean(Bool) case `nil` case userDefinedFunction(UserDefinedFunction) @@ -18,7 +19,9 @@ enum LoxValue: CustomStringConvertible, Equatable { switch self { case .string(let string): return "\"\(string)\"" - case .number(let number): + case .double(let number): + return "\(number)" + case .int(let number): return "\(number)" case .boolean(let boolean): return "\(boolean)" @@ -50,8 +53,14 @@ enum LoxValue: CustomStringConvertible, Equatable { switch (self, to) { case (.nil, .nil): return true - case (.number(let leftNumber), .number(let rightNumber)): + case (.int(let leftNumber), .int(let rightNumber)): + return leftNumber == rightNumber + case (.double(let leftNumber), .double(let rightNumber)): return leftNumber == rightNumber + case (.int(let leftNumber), .double(let rightNumber)): + return Double(leftNumber) == rightNumber + case (.double(let leftNumber), .int(let rightNumber)): + return leftNumber == Double(rightNumber) case (.string(let leftString), .string(let rightString)): return leftString == rightString case (.boolean(let leftBoolean), .boolean(let rightBoolean)): @@ -74,4 +83,26 @@ enum LoxValue: CustomStringConvertible, Equatable { return true } } + + func convertToRawInt() throws -> Int { + switch self { + case .int(let number): + return number + case .double(let number): + return Int(number) + default: + throw RuntimeError.notANumber + } + } + + func convertToRawDouble() throws -> Double { + switch self { + case .int(let number): + return Double(number) + case .double(let number): + return number + default: + throw RuntimeError.notANumber + } + } } diff --git a/slox/NativeFunction.swift b/slox/NativeFunction.swift index b8f89be..542bd4a 100644 --- a/slox/NativeFunction.swift +++ b/slox/NativeFunction.swift @@ -26,7 +26,7 @@ enum NativeFunction: LoxCallable, Equatable, CaseIterable { func call(interpreter: Interpreter, args: [LoxValue]) throws -> LoxValue { switch self { case .clock: - return .number(Date().timeIntervalSince1970) + return .double(Date().timeIntervalSince1970) case .appendNative: guard case .instance(let loxList as LoxList) = args[0] else { throw RuntimeError.notAList @@ -41,8 +41,8 @@ enum NativeFunction: LoxCallable, Equatable, CaseIterable { throw RuntimeError.notAList } - guard case .number(let index) = args[1] else { - throw RuntimeError.indexMustBeANumber + guard case .int(let index) = args[1] else { + throw RuntimeError.indexMustBeAnInteger } return loxList.elements.remove(at: Int(index)) diff --git a/slox/Parser.swift b/slox/Parser.swift index b68f2bb..f962233 100644 --- a/slox/Parser.swift +++ b/slox/Parser.swift @@ -609,9 +609,13 @@ struct Parser { return .literal(.nil) } - if currentTokenMatchesAny(types: [.number]) { + if currentTokenMatchesAny(types: [.double]) { let number = Double(previousToken.lexeme)! - return .literal(.number(number)) + return .literal(.double(number)) + } + if currentTokenMatchesAny(types: [.int]) { + let number = Int(previousToken.lexeme)! + return .literal(.int(number)) } if currentTokenMatchesAny(types: [.string]) { diff --git a/slox/RuntimeError.swift b/slox/RuntimeError.swift index 2cf3a2e..19c4fa2 100644 --- a/slox/RuntimeError.swift +++ b/slox/RuntimeError.swift @@ -18,13 +18,14 @@ enum RuntimeError: CustomStringConvertible, Equatable, LocalizedError { case notACallableObject case notAnInstance case notAList + case notANumber case onlyInstancesHaveProperties case undefinedProperty(String) case wrongArity(Int, Int) case notALambda case couldNotFindAncestorEnvironmentAtDepth(Int) case superclassMustBeAClass - case indexMustBeANumber + case indexMustBeAnInteger var description: String { switch self { @@ -48,6 +49,8 @@ enum RuntimeError: CustomStringConvertible, Equatable, LocalizedError { return "Error: expected an instance" case .notAList: return "Error: expected a list" + case .notANumber: + return "Error: expected a number" case .onlyInstancesHaveProperties: return "Error: can only get/set properties of instances" case .undefinedProperty(let name): @@ -60,7 +63,7 @@ enum RuntimeError: CustomStringConvertible, Equatable, LocalizedError { return "Error: could not find ancestor environment at depth \(depth)." case .superclassMustBeAClass: return "Error: superclass must be a class" - case .indexMustBeANumber: + case .indexMustBeAnInteger: return "Error: index must be a number" } } diff --git a/slox/Scanner.swift b/slox/Scanner.swift index 70edc94..628955f 100644 --- a/slox/Scanner.swift +++ b/slox/Scanner.swift @@ -162,8 +162,10 @@ struct Scanner { advanceCursor() } + var tokenType: TokenType = .int if nextIndex < source.endIndex, source[nextIndex] == "." { + tokenType = .double advanceCursor() while nextIndex < source.endIndex, @@ -172,7 +174,7 @@ struct Scanner { } } - addToken(type: .number) + addToken(type: tokenType) } mutating private func handleIdentifier() { diff --git a/slox/TokenType.swift b/slox/TokenType.swift index b23140e..5c76515 100644 --- a/slox/TokenType.swift +++ b/slox/TokenType.swift @@ -34,7 +34,8 @@ enum TokenType: Equatable { // Literals case identifier case string - case number + case double + case int // Keywords case and diff --git a/sloxTests/InterpreterTests.swift b/sloxTests/InterpreterTests.swift index e36fb4c..ef702f5 100644 --- a/sloxTests/InterpreterTests.swift +++ b/sloxTests/InterpreterTests.swift @@ -20,7 +20,7 @@ final class InterpreterTests: XCTestCase { let input = "42" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input)! - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -28,7 +28,7 @@ final class InterpreterTests: XCTestCase { let input = "(42)" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input)! - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -50,11 +50,27 @@ final class InterpreterTests: XCTestCase { } } - func testInterpretNumericBinaryExpression() throws { + func testInterpretBinaryExpressionInvolvingIntegers() throws { let input = "21 * 2" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input)! - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) + XCTAssertEqual(actual, expected) + } + + func testInterpretBinaryExpressionInvolvingDoubles() throws { + let input = "21.0 * 2.0" + let interpreter = Interpreter() + let actual = try interpreter.interpretRepl(source: input)! + let expected: LoxValue = .double(42.0) + XCTAssertEqual(actual, expected) + } + + func testInterpretBinaryExpressionInvolvingAnIntAndADouble() throws { + let input = "21.0 * 2" + let interpreter = Interpreter() + let actual = try interpreter.interpretRepl(source: input)! + let expected: LoxValue = .double(42.0) XCTAssertEqual(actual, expected) } @@ -88,7 +104,7 @@ final class InterpreterTests: XCTestCase { let input = "(-2) * (3 + 4)" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(-14) + let expected: LoxValue = .int(-14) XCTAssertEqual(actual, expected) } @@ -112,7 +128,7 @@ final class InterpreterTests: XCTestCase { let input = "var theAnswer = 42; theAnswer" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -120,7 +136,7 @@ final class InterpreterTests: XCTestCase { let input = "var theAnswer; theAnswer = 42; theAnswer" let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -134,7 +150,7 @@ i """ let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(3) + let expected: LoxValue = .int(3) XCTAssertEqual(actual, expected) } @@ -149,7 +165,7 @@ theAnswer """ let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -163,7 +179,7 @@ theAnswer """ let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -177,7 +193,7 @@ theAnswer """ let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -191,7 +207,7 @@ add(1, 2) let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(3) + let expected: LoxValue = .int(3) XCTAssertEqual(actual, expected) } @@ -207,7 +223,7 @@ fact(5) let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(120) + let expected: LoxValue = .int(120) XCTAssertEqual(actual, expected) } @@ -216,7 +232,7 @@ fact(5) let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(5) + let expected: LoxValue = .int(5) XCTAssertEqual(actual, expected) } @@ -231,7 +247,7 @@ addTwo(5) let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(7) + let expected: LoxValue = .int(7) XCTAssertEqual(actual, expected) } @@ -326,7 +342,7 @@ me.age let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(55) + let expected: LoxValue = .int(55) XCTAssertEqual(actual, expected) } @@ -360,7 +376,7 @@ Math.add(2, 3) let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(5) + let expected: LoxValue = .int(5) XCTAssertEqual(actual, expected) } @@ -378,7 +394,7 @@ b.getTheAnswer() let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -400,7 +416,7 @@ b.method() let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(42) + let expected: LoxValue = .int(42) XCTAssertEqual(actual, expected) } @@ -412,10 +428,23 @@ foo[2] let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(3) + let expected: LoxValue = .int(3) XCTAssertEqual(actual, expected) } + func testInterpretAccessingElementOfListWithDouble() throws { + let input = """ +var foo = [1, 2, 3, 4, 5]; +foo[2.0] +""" + + let interpreter = Interpreter() + let expectedError = RuntimeError.indexMustBeAnInteger + XCTAssertThrowsError(try interpreter.interpretRepl(source: input)!) { actualError in + XCTAssertEqual(actualError as! RuntimeError, expectedError) + } + } + func testInterpretMutationOfList() throws { let input = """ var foo = [1, 2, 3, 4, 5]; @@ -425,7 +454,7 @@ foo[2] let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(6) + let expected: LoxValue = .int(6) XCTAssertEqual(actual, expected) } @@ -439,7 +468,7 @@ foo()[1] let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(2) + let expected: LoxValue = .int(2) XCTAssertEqual(actual, expected) } @@ -463,7 +492,7 @@ baz[1][1] let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(4) + let expected: LoxValue = .int(4) XCTAssertEqual(actual, expected) } @@ -475,7 +504,7 @@ quux.count let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(0) + let expected: LoxValue = .int(0) XCTAssertEqual(actual, expected) } @@ -492,12 +521,12 @@ xyzzy } let actual = list.elements let expected: [LoxValue] = [ - .number(1), - .number(2), - .number(3), - .number(4), - .number(5), - .number(6), + .int(1), + .int(2), + .int(3), + .int(4), + .int(5), + .int(6), ] XCTAssertEqual(actual, expected) } @@ -512,7 +541,7 @@ foo.bar()[1] let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(2) + let expected: LoxValue = .int(2) XCTAssertEqual(actual, expected) } @@ -525,7 +554,7 @@ foo.count let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(4) + let expected: LoxValue = .int(4) XCTAssertEqual(actual, expected) } @@ -538,7 +567,7 @@ foo.count let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(2) + let expected: LoxValue = .int(2) XCTAssertEqual(actual, expected) } @@ -556,7 +585,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(6) + let expected: LoxValue = .int(6) XCTAssertEqual(actual, expected) } @@ -576,7 +605,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(6) + let expected: LoxValue = .int(6) XCTAssertEqual(actual, expected) } @@ -596,7 +625,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(45) + let expected: LoxValue = .int(45) XCTAssertEqual(actual, expected) } @@ -617,7 +646,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(12) + let expected: LoxValue = .int(12) XCTAssertEqual(actual, expected) } @@ -635,7 +664,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(12) + let expected: LoxValue = .int(12) XCTAssertEqual(actual, expected) } @@ -660,7 +689,7 @@ sum let interpreter = Interpreter() let actual = try interpreter.interpretRepl(source: input) - let expected: LoxValue = .number(4) + let expected: LoxValue = .int(4) XCTAssertEqual(actual, expected) } } diff --git a/sloxTests/ParserTests.swift b/sloxTests/ParserTests.swift index 5212107..72bd599 100644 --- a/sloxTests/ParserTests.swift +++ b/sloxTests/ParserTests.swift @@ -25,7 +25,7 @@ final class ParserTests: XCTestCase { func testParseNumericLiteralExpression() throws { let tokens: [Token] = [ - Token(type: .number, lexeme: "123.456", line: 1), + Token(type: .double, lexeme: "123.456", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -33,7 +33,7 @@ final class ParserTests: XCTestCase { let actual = try parser.parse() let expected: [Statement] = [ - .expression(.literal(.number(123.456))) + .expression(.literal(.double(123.456))) ] XCTAssertEqual(actual, expected) } @@ -71,7 +71,7 @@ final class ParserTests: XCTestCase { func testParseGroupingExpression() throws { let tokens: [Token] = [ Token(type: .leftParen, lexeme: "(", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), @@ -80,7 +80,7 @@ final class ParserTests: XCTestCase { let actual = try parser.parse() let expected: [Statement] = [ - .expression(.grouping(.literal(.number(42)))) + .expression(.grouping(.literal(.int(42)))) ] XCTAssertEqual(actual, expected) } @@ -88,7 +88,7 @@ final class ParserTests: XCTestCase { func testParseInvalidGroupingExpression() throws { let tokens: [Token] = [ Token(type: .leftParen, lexeme: "(", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -104,7 +104,7 @@ final class ParserTests: XCTestCase { func testParseInvalidExpression() throws { let tokens: [Token] = [ Token(type: .rightParen, lexeme: ")", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .leftParen, lexeme: "(", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), @@ -139,9 +139,9 @@ final class ParserTests: XCTestCase { func testParseFactorExpression() throws { let tokens: [Token] = [ - Token(type: .number, lexeme: "21", line: 1), + Token(type: .int, lexeme: "21", line: 1), Token(type: .star, lexeme: "*", line: 1), - Token(type: .number, lexeme: "2", line: 1), + Token(type: .int, lexeme: "2", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -151,9 +151,9 @@ final class ParserTests: XCTestCase { let expected: [Statement] = [ .expression( .binary( - .literal(.number(21)), + .literal(.int(21)), Token(type: .star, lexeme: "*", line: 1), - .literal(.number(2)))) + .literal(.int(2)))) ] XCTAssertEqual(actual, expected) } @@ -181,9 +181,9 @@ final class ParserTests: XCTestCase { func testParseComparisonExpression() throws { let tokens: [Token] = [ - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .lessEqual, lexeme: "<=", line: 1), - Token(type: .number, lexeme: "2", line: 1), + Token(type: .int, lexeme: "2", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -193,9 +193,9 @@ final class ParserTests: XCTestCase { let expected: [Statement] = [ .expression( .binary( - .literal(.number(1)), + .literal(.int(1)), Token(type: .lessEqual, lexeme: "<=", line: 1), - .literal(.number(2)))) + .literal(.int(2)))) ] XCTAssertEqual(actual, expected) } @@ -286,7 +286,7 @@ final class ParserTests: XCTestCase { let tokens: [Token] = [ Token(type: .identifier, lexeme: "theAnswer", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -297,7 +297,7 @@ final class ParserTests: XCTestCase { .expression( .assignment( Token(type: .identifier, lexeme: "theAnswer", line: 1), - .literal(.number(42)))) + .literal(.int(42)))) ] XCTAssertEqual(actual, expected) } @@ -308,13 +308,13 @@ final class ParserTests: XCTestCase { let tokens: [Token] = [ Token(type: .leftParen, lexeme: "(", line: 1), Token(type: .minus, lexeme: "-", line: 1), - Token(type: .number, lexeme: "2", line: 1), + Token(type: .int, lexeme: "2", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .star, lexeme: "*", line: 1), Token(type: .leftParen, lexeme: "(", line: 1), - Token(type: .number, lexeme: "3", line: 1), + Token(type: .int, lexeme: "3", line: 1), Token(type: .plus, lexeme: "+", line: 1), - Token(type: .number, lexeme: "4", line: 1), + Token(type: .int, lexeme: "4", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), @@ -327,12 +327,12 @@ final class ParserTests: XCTestCase { .binary( .grouping(.unary( Token(type: .minus, lexeme: "-", line: 1), - .literal(.number(2)))), + .literal(.int(2)))), Token(type: .star, lexeme: "*", line: 1), .grouping(.binary( - .literal(.number(3)), + .literal(.int(3)), Token(type: .plus, lexeme: "+", line: 1), - .literal(.number(4)))))) + .literal(.int(4)))))) ] XCTAssertEqual(actual, expected) } @@ -348,19 +348,19 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "0", line: 1), + Token(type: .int, lexeme: "0", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .less, lexeme: "<", line: 1), - Token(type: .number, lexeme: "5", line: 1), + Token(type: .int, lexeme: "5", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .equal, lexeme: "=", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .plus, lexeme: "+", line: 1), - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .print, lexeme: "print", line: 2), @@ -376,17 +376,17 @@ final class ParserTests: XCTestCase { .for( .variableDeclaration( Token(type: .identifier, lexeme: "i", line: 1), - .literal(.number(0))), + .literal(.int(0))), .binary( .variable(Token(type: .identifier, lexeme: "i", line: 1)), Token(type: .less, lexeme: "<", line: 1), - .literal(.number(5))), + .literal(.int(5))), .assignment( Token(type: .identifier, lexeme: "i", line: 1), .binary( .variable(Token(type: .identifier, lexeme: "i", line: 1)), Token(type: .plus, lexeme: "+", line: 1), - .literal(.number(1)))), + .literal(.int(1)))), .print( .variable(Token(type: .identifier, lexeme: "i", line: 2)))), ] @@ -430,19 +430,19 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "0", line: 1), + Token(type: .int, lexeme: "0", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .less, lexeme: "<", line: 1), - Token(type: .number, lexeme: "5", line: 1), + Token(type: .int, lexeme: "5", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .equal, lexeme: "=", line: 1), Token(type: .identifier, lexeme: "i", line: 1), Token(type: .plus, lexeme: "+", line: 1), - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .print, lexeme: "print", line: 2), Token(type: .identifier, lexeme: "i", line: 2), @@ -586,7 +586,7 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 1), Token(type: .identifier, lexeme: "theAnswer", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -596,7 +596,7 @@ final class ParserTests: XCTestCase { let expected: [Statement] = [ .variableDeclaration( Token(type: .identifier, lexeme: "theAnswer", line: 1), - .literal(.number(42))) + .literal(.int(42))) ] XCTAssertEqual(actual, expected) } @@ -605,7 +605,7 @@ final class ParserTests: XCTestCase { let tokens: [Token] = [ Token(type: .var, lexeme: "var", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "42", line: 1), + Token(type: .int, lexeme: "42", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -627,13 +627,13 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 1), Token(type: .identifier, lexeme: "the", line: 1), Token(type: .equal, lexeme: "=", line: 1), - Token(type: .number, lexeme: "2", line: 1), + Token(type: .int, lexeme: "2", line: 1), Token(type: .semicolon, lexeme: ";", line: 1), Token(type: .var, lexeme: "var", line: 2), Token(type: .identifier, lexeme: "answer", line: 2), Token(type: .equal, lexeme: "=", line: 2), - Token(type: .number, lexeme: "21", line: 2), + Token(type: .int, lexeme: "21", line: 2), Token(type: .semicolon, lexeme: ";", line: 2), Token(type: .print, lexeme: "print", line: 3), @@ -650,10 +650,10 @@ final class ParserTests: XCTestCase { let expected: [Statement] = [ .variableDeclaration( Token(type: .identifier, lexeme: "the", line: 1), - .literal(.number(2))), + .literal(.int(2))), .variableDeclaration( Token(type: .identifier, lexeme: "answer", line: 2), - .literal(.number(21))), + .literal(.int(21))), .print( .binary( .variable(Token(type: .identifier, lexeme: "the", line: 3)), @@ -675,7 +675,7 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 2), Token(type: .identifier, lexeme: "theAnswer", line: 2), Token(type: .equal, lexeme: "=", line: 2), - Token(type: .number, lexeme: "42", line: 2), + Token(type: .int, lexeme: "42", line: 2), Token(type: .semicolon, lexeme: ";", line: 2), Token(type: .print, lexeme: "print", line: 3), @@ -693,7 +693,7 @@ final class ParserTests: XCTestCase { .block([ .variableDeclaration( Token(type: .identifier, lexeme: "theAnswer", line: 2), - .literal(.number(42))), + .literal(.int(42))), .print( .variable(Token(type: .identifier, lexeme: "theAnswer", line: 3))), ]), @@ -708,7 +708,7 @@ final class ParserTests: XCTestCase { Token(type: .var, lexeme: "var", line: 2), Token(type: .identifier, lexeme: "theAnswer", line: 2), Token(type: .equal, lexeme: "=", line: 2), - Token(type: .number, lexeme: "42", line: 2), + Token(type: .int, lexeme: "42", line: 2), Token(type: .semicolon, lexeme: ";", line: 2), Token(type: .print, lexeme: "print", line: 3), @@ -737,7 +737,7 @@ final class ParserTests: XCTestCase { Token(type: .leftParen, lexeme: "(", line: 1), Token(type: .identifier, lexeme: "x", line: 1), Token(type: .lessEqual, lexeme: "<=", line: 1), - Token(type: .number, lexeme: "5", line: 1), + Token(type: .int, lexeme: "5", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .leftBrace, lexeme: "{", line: 1), @@ -749,7 +749,7 @@ final class ParserTests: XCTestCase { Token(type: .equal, lexeme: "=", line: 3), Token(type: .identifier, lexeme: "x", line: 3), Token(type: .plus, lexeme: "+", line: 3), - Token(type: .number, lexeme: "1", line: 3), + Token(type: .int, lexeme: "1", line: 3), Token(type: .semicolon, lexeme: ";", line: 3), Token(type: .rightBrace, lexeme: "}", line: 4), @@ -763,7 +763,7 @@ final class ParserTests: XCTestCase { .binary( .variable(Token(type: .identifier, lexeme: "x", line: 1)), Token(type: .lessEqual, lexeme: "<=", line: 1), - .literal(.number(5))), + .literal(.int(5))), .block([ .print(.variable(Token(type: .identifier, lexeme: "x", line: 2))), .expression( @@ -772,7 +772,7 @@ final class ParserTests: XCTestCase { .binary( .variable(Token(type: .identifier, lexeme: "x", line: 3)), Token(type: .plus, lexeme: "+", line: 3), - .literal(.number(1))))), + .literal(.int(1))))), ])) ] XCTAssertEqual(actual, expected) @@ -813,7 +813,7 @@ final class ParserTests: XCTestCase { Token(type: .leftBrace, lexeme: "{", line: 1), Token(type: .print, lexeme: "print", line: 2), - Token(type: .number, lexeme: "42", line: 2), + Token(type: .int, lexeme: "42", line: 2), Token(type: .semicolon, lexeme: ";", line: 2), Token(type: .rightBrace, lexeme: "}", line: 3), @@ -828,7 +828,7 @@ final class ParserTests: XCTestCase { .lambda( [], [ - .print(.literal(.number(42))) + .print(.literal(.int(42))) ])), ] XCTAssertEqual(actual, expected) @@ -886,9 +886,9 @@ final class ParserTests: XCTestCase { let tokens: [Token] = [ Token(type: .identifier, lexeme: "add", line: 1), Token(type: .leftParen, lexeme: "(", line: 1), - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .comma, lexeme: ",", line: 1), - Token(type: .number, lexeme: "2", line: 1), + Token(type: .int, lexeme: "2", line: 1), Token(type: .rightParen, lexeme: ")", line: 1), Token(type: .eof, lexeme: "", line: 1), ] @@ -901,8 +901,8 @@ final class ParserTests: XCTestCase { .variable(Token(type: .identifier, lexeme: "add", line: 1)), Token(type: .rightParen, lexeme: ")", line: 1), [ - .literal(.number(1)), - .literal(.number(2)), + .literal(.int(1)), + .literal(.int(2)), ])) ] XCTAssertEqual(actual, expected) @@ -1174,7 +1174,7 @@ final class ParserTests: XCTestCase { // [1, "one", true] let tokens: [Token] = [ Token(type: .leftBracket, lexeme: "[", line: 1), - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .comma, lexeme: ",", line: 1), Token(type: .string, lexeme: "\"one\"", line: 1), Token(type: .comma, lexeme: ",", line: 1), @@ -1188,7 +1188,7 @@ final class ParserTests: XCTestCase { let expected: [Statement] = [ .expression( .list([ - .literal(.number(1)), + .literal(.int(1)), .literal(.string("one")), .literal(.boolean(true)) ])) @@ -1200,7 +1200,7 @@ final class ParserTests: XCTestCase { // [1, "one", true let tokens: [Token] = [ Token(type: .leftBracket, lexeme: "[", line: 1), - Token(type: .number, lexeme: "1", line: 1), + Token(type: .int, lexeme: "1", line: 1), Token(type: .comma, lexeme: ",", line: 1), Token(type: .string, lexeme: "\"one\"", line: 1), Token(type: .comma, lexeme: ",", line: 1), diff --git a/sloxTests/ResolverTests.swift b/sloxTests/ResolverTests.swift index 196157a..51df28d 100644 --- a/sloxTests/ResolverTests.swift +++ b/sloxTests/ResolverTests.swift @@ -31,7 +31,7 @@ final class ResolverTests: XCTestCase { let statements: [Statement] = [ .variableDeclaration( Token(type: .identifier, lexeme: "answer", line: 1), - .literal(.number(42))), + .literal(.int(42))), ] var resolver = Resolver() @@ -39,7 +39,7 @@ final class ResolverTests: XCTestCase { let expected: [ResolvedStatement] = [ .variableDeclaration( Token(type: .identifier, lexeme: "answer", line: 1), - .literal(.number(42))), + .literal(.int(42))), ] XCTAssertEqual(actual, expected) } @@ -139,7 +139,7 @@ final class ResolverTests: XCTestCase { .block([ .return( Token(type: .return, lexeme: "return", line: 1), - .literal(.number(42))), + .literal(.int(42))), ]) ] @@ -288,7 +288,7 @@ final class ResolverTests: XCTestCase { [ .return( Token(type: .return, lexeme: "return", line: 3), - .literal(.number(42))) + .literal(.int(42))) ])) ], []) diff --git a/sloxTests/ScannerTests.swift b/sloxTests/ScannerTests.swift index 183776c..2ca6650 100644 --- a/sloxTests/ScannerTests.swift +++ b/sloxTests/ScannerTests.swift @@ -89,8 +89,8 @@ final class ScannerTests: XCTestCase { var scanner = Scanner(source: source) let actual = try! scanner.scanTokens() let expected: [Token] = [ - Token(type: .number, lexeme: "123", line: 1), - Token(type: .number, lexeme: "456.789", line: 1), + Token(type: .int, lexeme: "123", line: 1), + Token(type: .double, lexeme: "456.789", line: 1), Token(type: .eof, lexeme: "", line: 1), ]