1 Stack = Stack or {}
2
3 function Stack.new()
4 local inst = {}
5 inst._cname = "lang.Stack"
6
7 local arr = {}
8 local len = 0
9
10 function inst:push(v)
11 len = len + 1
12 arr[len] = v
13 end
14
15 function inst:pop()
16 assert(len >= 1, "Stack: pop: out of range")
17 local v = arr[len]
18 arr[len] = nil
19 len = len - 1
20 return v
21 end
22
23 function inst:peek()
24 if len >= 1 then
25 return arr[len]
26 end
27 return nil
28 end
29
30 function inst:count()
31 return len
32 end
33
34 function inst:contains(v)
35 for i=1,len do
36 if arr[i] == v then
37 return true
38 end
39 end
40 return false
41 end
42
43 function inst:clear()
44 for i=1,len do
45 arr[i] = nil
46 end
47 len = 0
48 end
49
50 function inst:copyTo(dst)
51 assert("table" == type(dst), "copyTo: dst not table or Stack")
52 if "lang.Stack" == dst._cname then
53 for i=1,len do
54 dst:push(arr[i])
55 end
56 else
57 for i=1,len do
58 table.insert(dst, arr[i])
59 end
60 end
61 end
62
63 function inst:__tostring()
64 if len <= 0 then return "" end
65 local strTb = {}
66 for i=1,len do
67 local item = arr[i]
68 table.insert(strTb, (nil == item) and "nil" or tostring(item))
69 end
70 return table.concat(strTb, ",")
71 end
72
73 function inst:__len()
74 return len
75 end
76
77 function inst:__index(k)
78 error("Stack: invalid member: " .. k)
79 end
80
81 function inst:__newindex(k, v)
82 error("Stack: add member error: " .. k)
83 end
84
85 function inst:__pairs()
86 local iterator = function(src, index)
87 if nil == index then
88 index = len
89 else
90 index = index - 1
91 end
92 if index >= 1 then
93 return index, arr[index]
94 end
95 return nil, nil
96 end
97 return iterator
98 end
99
100 setmetatable(inst, inst)
101 return inst
102 end
103
104 Stack.__call = function()
105 return Stack.new()
106 end
107
108 setmetatable(Stack, Stack)
測試代碼:
1 function Test1()
2 local stack = Stack()
3 stack:push("one")
4 assert(1 == stack:count(), "push error")
5 assert("one" == stack:peek(), "peek error")
6 assert("one" == stack:pop(), "pop error")
7 assert(0 == stack:count(), "pop error")
8
9 assert(nil == stack:peek(), "peek error")
10
11 for i=1,100 do
12 stack:push(i)
13 end
14 assert(100 == stack:count(), "push error")
15 stack:clear()
16 assert(0 == stack:count(), "push error")
17
18 stack:push("a")
19 stack:push("b")
20
21 local s2 = Stack()
22 stack:copyTo(s2)
23 assert(2 == s2:count(), "copyTo error")
24
25 for k,v in s2:__pairs() do
26 print("k: " .. k .. ": " .. v)
27 end
28
29 assert("b" == s2:peek(), "peek error")
30 assert("b" == s2:pop(), "pop error")
31
32 assert("a" == s2:peek(), "peek error")
33 assert("a" == s2:pop(), "pop error")
34
35 assert(0 == s2:count(), "copyTo error")
36 end
37
38
39 Test1()