-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.lua
More file actions
162 lines (153 loc) · 5.05 KB
/
types.lua
File metadata and controls
162 lines (153 loc) · 5.05 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
local base = {
type = "base",
__index = function(self, key) error(string.format("%s not implemented for %s", key, self.type)) end
}
function newNumber(n)
return setmetatable({
value = n,
type = "number",
tostring = function(self) return tostring(self.value) end,
tonumber = function(self) return self.value end,
add = function(self, other)
assert(other.type == "number", string.format("Cannot add %s to number", other.type))
return self.value + other.value
end,
sub = function(self, other)
assert(other.type == "number", string.format("Cannot subtract %s from number", other.type))
return self.value - other.value
end,
mul = function(self, other)
assert(other.type == "number", string.format("Cannot multiply number by %s", other.type))
return self.value * other.value
end,
div = function(self, other)
assert(other.type == "number", string.format("Cannot divide number by %s", other.type))
return self.value / other.value
end,
mod = function(self, other)
assert(other.typer == "number", string.format("Cannot modulo number by %s", other.type))
return self.value % other.value
end,
exp = function(self, other)
assert(other.type == "number", string.format("Cannot raise number by %s", other.type))
return self.value ^ other.value
end,
eq = function(self, other)
return other.type == "number" and self.value == other.value
end,
neq = function(self, other)
return self:eq(other) == false
end,
lt = function(self, other)
return other.type == "number" and self.value < other.value
end,
le = function(self, other)
return other.type == "number" and self.value <= other.value
end,
gt = function(self, other)
return other.type == "number" and self.value > other.value
end,
ge = function(self, other)
return other.type == "number" and self.value >= other.value
end,
band = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise and %s and number", other.type))
return bit.band(self.value, other.value)
end,
bor = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise or %s and number", other.type))
return bit.bor(self.value, other.value)
end,
bxor = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise xor %s and number", other.type))
return bit.bxor(self.value, other.value)
end,
bneg = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise negate %s and number", other.type))
return bit.bnot(self.value, other.value)
end,
bshl = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise left shift %s and number", other.type))
return bit.lshift(self.value, other.value)
end,
bshr = function(self, other)
assert(other.type == "number", string.format("Cannot bitwise right shift %s and number", other.type))
return bit.rshift(self.value, other.value)
end
}, base)
end
function newString(str)
return setmetatable({
value = str,
type = "string",
tostring = function(self) return self.value end,
tonumber = function(self) return tostring(self.value) end,
eq = function(self, other)
return other.type == "string" and self.value == other.value
end,
neq = function(self, other)
return self:eq(other) == false
end,
concat = function(self, other)
assert(other.type == "string", string.format("Cannot concatenate string with %s", other.type))
return self.value .. other.value
end,
hash = function(self)
return #self.value
end
}, base)
end
function newFunction(addr, numLocals, parameters, constants, bytecode)
return setmetatable({
type = "function",
addr = addr,
constants = constants,
parameters = parameters,
numLocals = numLocals,
bytecode = bytecode,
eq = function(self, other)
return other.type == "function" and self.addr == other.addr
end,
neq = function(self, other)
return self:eq(other) == false
end,
tostring = function(self)
local paramStr = ""
for i, p in ipairs(self.parameters) do
if (i > 1) then paramStr = paramStr .. ", " end
paramStr = paramStr .. p
end
return string.format("function %#02x(%s)", self.addr, paramStr)
end
}, base)
end
function newBoolean(b)
return setmetatable({
type = "bool",
value = b,
tostring = function(self) return tostring(self.value) end,
eq = function(self, other)
return other.type == "bool" and self.value == other.value
end,
neq = function(self, other)
return self:eq(other) == false
end
}, base)
end
function copyType(t, ...)
if (type(t) == "number") then
return newNumber(t)
elseif (type(t) == "string") then
return newString(t)
elseif (type(t) == "bool") then
return newBool(t)
elseif (t.type == "number") then
return newNumber(...)
elseif (t.type == "string") then
return newString(...)
elseif (t.type == "function") then
return newFunction(...)
elseif (t.type == "bool") then
return newBoolean(...)
end
end