/
LoxValue.swift
108 lines (102 loc) · 3.21 KB
/
LoxValue.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// LoxValue.swift
// slox
//
// Created by Danielle Kefford on 2/23/24.
//
enum LoxValue: CustomStringConvertible, Equatable {
case string(String)
case double(Double)
case int(Int)
case boolean(Bool)
case `nil`
case userDefinedFunction(UserDefinedFunction)
case nativeFunction(NativeFunction)
case instance(LoxInstance)
var description: String {
switch self {
case .string(let string):
return "\"\(string)\""
case .double(let number):
return "\(number)"
case .int(let number):
return "\(number)"
case .boolean(let boolean):
return "\(boolean)"
case .nil:
return "nil"
case .userDefinedFunction(let function):
return "<function: \(function.name)>"
case .nativeFunction(let function):
return "<function: \(function)>"
case .instance(let klass as LoxClass):
return "<class: \(klass.name)>"
case .instance(let list as LoxList):
var string = "["
for (i, element) in list.elements.enumerated() {
if i > 0 {
string.append(", ")
}
string.append("\(element)")
}
string.append("]")
return string
case .instance(let instance):
return "<instance: \(instance.klass.name)>"
}
}
// These are the rules of equality for Lox
func isEqual(to: Self) -> Bool {
switch (self, to) {
case (.nil, .nil):
return true
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)):
return leftBoolean == rightBoolean
case (.instance(let leftList as LoxList), .instance(let rightList as LoxList)):
return leftList == rightList
default:
return false
}
}
// In Lox, `false` and `nil` are false; everything else is true
var isTruthy: Bool {
switch self {
case .nil:
return false
case .boolean(let boolean):
return boolean
default:
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
}
}
}