-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLabelTable.swift
102 lines (92 loc) · 2.23 KB
/
LabelTable.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
//
// LabelTable.swift
// Hasm
//
// Created by Tiago Lopes on 13/11/24.
//
struct LabelTable {
typealias Label = String
typealias Address = Int
private var addressMap: [Label: Address] = [:]
private var nextAvailableAddress = 16
mutating func associate(symbol: Label, to address: Address) {
guard address >= 0 else {
preconditionFailure("Address can't be negative")
}
addressMap[symbol] = address
}
mutating func associate(variable: Label) {
guard PredefinedVariable(rawValue: variable.lowercased()) == nil else {
return
}
guard address(for: variable) == nil else {
return
}
addressMap[variable] = nextAvailableAddress
nextAvailableAddress += 1
}
func address(for label: Label) -> Address? {
return if let predefinedVar = PredefinedVariable(rawValue: label.lowercased()) {
predefinedVar.address
} else {
addressMap[label]
}
}
}
private extension LabelTable {
enum PredefinedVariable: String {
case sp
case lcl
case arg
case this
case that
case r0
case r1
case r2
case r3
case r4
case r5
case r6
case r7
case r8
case r9
case r10
case r11
case r12
case r13
case r14
case r15
case screen
case kbd
var label: Label {
rawValue.uppercased()
}
var address: Address {
switch self {
case .sp: 0
case .lcl: 1
case .arg: 2
case .this: 3
case .that: 4
case .r0: 0
case .r1: 1
case .r2: 2
case .r3: 3
case .r4: 4
case .r5: 5
case .r6: 6
case .r7: 7
case .r8: 8
case .r9: 9
case .r10: 10
case .r11: 11
case .r12: 12
case .r13: 13
case .r14: 14
case .r15: 15
case .screen: 16384
case .kbd: 24576
}
}
}
}