Skip to content

Commit

Permalink
UserDefinedFunction and LoxInstance now get assigned UUIDs upon i…
Browse files Browse the repository at this point in the history
…nstantiation so that hashing `LoxValue` makes more sense.
  • Loading branch information
quephird committed Mar 27, 2024
1 parent a88140c commit ca32ed9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
4 changes: 4 additions & 0 deletions slox/LoxInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Created by Danielle Kefford on 3/4/24.
//

import Foundation

class LoxInstance {
// `klass` is what is used in the interpreter when we need
// to know the class of a particular instance. Every Lox
Expand All @@ -24,12 +26,14 @@ class LoxInstance {
return _klass!
}
var properties: [String: LoxValue] = [:]
var objectId: UUID

/// - Parameter klass: The class this instance belongs to.
/// Use `nil` if this instance *is* a class; the `klass` property
/// will then instantiate a metaclass for it on demand.
required init(klass: LoxClass?) {
self._klass = klass
self.objectId = UUID()
}

func get(propertyName: String) throws -> LoxValue {
Expand Down
24 changes: 10 additions & 14 deletions slox/LoxValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ enum LoxValue: CustomStringConvertible, Equatable, Hashable {
}
}

// NOTA BENE: This equality conformance is only for unit tests
static func == (lhs: LoxValue, rhs: LoxValue) -> Bool {
switch (lhs, rhs) {
case (.string(let lhsString), .string(let rhsString)):
Expand All @@ -132,6 +131,10 @@ enum LoxValue: CustomStringConvertible, Equatable, Hashable {
return lhsBoolean == rhsBoolean
case (.nil, .nil):
return true
case (.userDefinedFunction(let leftFunc), .userDefinedFunction(let rightFunc)):
return leftFunc.objectId == rightFunc.objectId
case (.nativeFunction(let leftFunc), .nativeFunction(let rightFunc)):
return leftFunc == rightFunc
case (.instance(let leftList as LoxList), .instance(let rightList as LoxList)):
return leftList.elements == rightList.elements
default:
Expand All @@ -140,33 +143,26 @@ enum LoxValue: CustomStringConvertible, Equatable, Hashable {
}

// TODO: Check with Becca if this is even remotely sensible
// especially with the function and instance cases, as they
// don't make much sense as candidates for keys
func hash(into hasher: inout Hasher) {
switch self {
case .string(let string):
hasher.combine("string")
hasher.combine(string)
case .double(let double):
hasher.combine("double")
hasher.combine(double)
case .int(let int):
hasher.combine("int")
hasher.combine(int)
case .boolean(let boolean):
hasher.combine("boolean")
hasher.combine(boolean)
case .nil:
hasher.combine("nil")
break
case .userDefinedFunction(let userDefinedFunction):
hasher.combine("userDefinedFunction")
hasher.combine(userDefinedFunction.name)
hasher.combine(userDefinedFunction.params)
hasher.combine(userDefinedFunction.objectId)
case .nativeFunction(let nativeFunction):
hasher.combine("nativeFunction")
hasher.combine(nativeFunction.hashValue)
hasher.combine(nativeFunction)
case .instance(let instance):
hasher.combine("instance")
hasher.combine(instance.klass.name)
hasher.combine(instance.properties)
hasher.combine(instance.objectId)
}
}
}
16 changes: 16 additions & 0 deletions slox/UserDefinedFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Created by Danielle Kefford on 2/29/24.
//

import Foundation

struct UserDefinedFunction: LoxCallable, Equatable {
var name: String
var params: [Token]
Expand All @@ -14,6 +16,20 @@ struct UserDefinedFunction: LoxCallable, Equatable {
var enclosingEnvironment: Environment
var body: [ResolvedStatement]
var isInitializer: Bool
var objectId: UUID

init(name: String,
params: [Token],
enclosingEnvironment: Environment,
body: [ResolvedStatement],
isInitializer: Bool) {
self.name = name
self.params = params
self.enclosingEnvironment = enclosingEnvironment
self.body = body
self.isInitializer = isInitializer
self.objectId = UUID()
}

func call(interpreter: Interpreter, args: [LoxValue]) throws -> LoxValue {
let newEnvironment = Environment(enclosingEnvironment: enclosingEnvironment)
Expand Down

0 comments on commit ca32ed9

Please sign in to comment.