.
This commit is contained in:
@@ -87,6 +87,27 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
|
local stack = VM.new().stack
|
||||||
|
stack:push(10)
|
||||||
|
stack:push(20)
|
||||||
|
stack:push_fp()
|
||||||
|
stack:push(30)
|
||||||
|
stack:push(40)
|
||||||
|
stack:push(50)
|
||||||
|
|
||||||
|
assert_eq(#stack, 3)
|
||||||
|
assert_eq(stack[0], 30)
|
||||||
|
assert_eq(stack[1], 40)
|
||||||
|
assert_eq(stack[-1], 50)
|
||||||
|
assert_eq(stack[-2], 40)
|
||||||
|
|
||||||
|
stack:pop_fp()
|
||||||
|
|
||||||
|
assert_eq(#stack, 2)
|
||||||
|
assert_eq(stack[0], 10)
|
||||||
|
assert_eq(stack[1], 20)
|
||||||
|
assert_eq(stack[-1], 20)
|
||||||
|
assert_eq(stack[-2], 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
print('End.')
|
print('End.')
|
||||||
@@ -10,10 +10,12 @@ local Stack = {}
|
|||||||
Stack.__index = Stack
|
Stack.__index = Stack
|
||||||
|
|
||||||
function Stack.new()
|
function Stack.new()
|
||||||
return setmetatable({
|
local self = setmetatable({
|
||||||
stack = {},
|
stack = {},
|
||||||
fps = { 0 },
|
fps = {},
|
||||||
}, Stack)
|
}, Stack)
|
||||||
|
self:push_fp()
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stack:top_fps()
|
function Stack:top_fps()
|
||||||
@@ -37,14 +39,14 @@ function Stack:peek(value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Stack.__len = function(self)
|
Stack.__len = function(self)
|
||||||
return #self.stack - self:top_fps()
|
return #self.stack - self:top_fps() + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
Stack.__index = function(self, key)
|
Stack.__index = function(self, key)
|
||||||
local idx = tonumber(key)
|
local idx = tonumber(key)
|
||||||
if idx then
|
if idx then
|
||||||
if idx >= 0 then
|
if idx >= 0 then
|
||||||
return self.stack[self:top_fps() + idx + 1]
|
return self.stack[self:top_fps() + idx]
|
||||||
else
|
else
|
||||||
if self:top_fps() + #self.stack + idx < 0 then error("Stack access out of range") end
|
if self:top_fps() + #self.stack + idx < 0 then error("Stack access out of range") end
|
||||||
return self.stack[#self.stack + idx + 1]
|
return self.stack[#self.stack + idx + 1]
|
||||||
@@ -55,18 +57,38 @@ Stack.__index = function(self, key)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Stack.__newindex = function(self, key, value)
|
Stack.__newindex = function(self, key, value)
|
||||||
|
local idx = tonumber(key)
|
||||||
|
if idx then
|
||||||
|
if idx >= 0 then
|
||||||
|
self.stack[self:top_fps() + idx] = value
|
||||||
|
else
|
||||||
|
if self:top_fps() + #self.stack + idx < 0 then error("Stack access out of range") end
|
||||||
|
self.stack[#self.stack + idx + 1] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stack:push_fp()
|
function Stack:push_fp()
|
||||||
|
table.insert(self.fps, #self.stack + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stack:pop_fp()
|
function Stack:pop_fp()
|
||||||
|
if #self.fps == 1 then error("FPS queue underflow") end
|
||||||
|
for i=self:top_fps(),#self.stack,1 do
|
||||||
|
self.stack[i] = nil
|
||||||
|
end
|
||||||
|
table.remove(self.fps)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stack:fp_level()
|
function Stack:fp_level()
|
||||||
|
return #self.fps
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stack:debug()
|
function Stack:debug()
|
||||||
|
if #self.stack == 0 then return "empty" end
|
||||||
|
local ss = {}
|
||||||
|
for _,v in ipairs(self.stack) do table.insert(ss, '[' .. pprint.pformat(v) .. '] ') end
|
||||||
|
return table.concat(ss)
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------
|
----------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user