|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- diagstacks.lua: the stack, the metastack, and the arrays "nodes" and "arrows".
-- This file:
-- http://angg.twu.net/dednat5/diagstacks.lua.html
-- http://angg.twu.net/dednat5/diagstacks.lua
-- (find-dn5 "diagstacks.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2011apr10
-- License: GPL3
--
-- «.Stack» (to "Stack")
-- «.MetaStack» (to "MetaStack")
-- «.nodes» (to "nodes")
-- «.arrows» (to "arrows")
require "eoo" -- (find-dn5 "eoo.lua")
-- «Stack» (to ".Stack")
push = function (stack, o) table.insert(stack, o) end
pop = function (stack, msg)
assert(#stack > 0, msg or "Empty stack")
return table.remove(stack)
end
popuntil = function (stack, depth) while #stack > depth do pop(stack) end end
pick = function (stack, offset) return stack[#stack - offset] end
pock = function (stack, offset, o) stack[#stack - offset] = o end
Stack = Class {
type = "Stack",
__index = {
push = push,
pop = pop,
popuntil = popuntil,
clear = function (s) s:popuntil(0) end,
pick = pick,
pock = pock,
},
}
-- Current fragilities: pushing a nil is a no-op;
-- and pick and pock do not check depth.
-- Beware: in dednat4 we stored the stack elements in the "wrong"
-- order just to make pick and pock trivial to implement (tos was
-- ds[1] in dednat4)... Now the conventions are:
-- ds:pick(0) returns the tos ("top of stack")
-- ds:pick(1) returns the element below tos
-- ds:pock(0, "a") replaces the tos by "a"
-- ds:pock(1, "b") replaces the element below tos by "b"
ds = Stack {} -- (find-miniforthgempage 3 "DS={ 5 }")
-- «MetaStack» (to ".MetaStack")
-- (find-dn5 "diagforth.lua" "metastack")
MetaStack = ClassOver(Stack) {
type = "MetaStack",
__index = {
ppush = function (ms) push(ms, #(ms.stack)) end,
ppop = function (ms) popuntil(ms.stack, pop(ms, "Empty metastack")) end,
metapick = function (ms, offset) return ms.stack[ms:pick(0) + offset] end,
},
}
depths = MetaStack {stack=ds}
-- «nodes» (to ".nodes")
nodes = {} -- has numeric and string indices
storenode = function (node)
table.insert(nodes, node)
node.noden = #nodes -- nodes[node.noden] == node
if node.tag then -- was: "and not nodes[node.tag]"...
nodes[node.tag] = node -- nodes[node.tag] == node
end
return node
end
-- «arrows» (to ".arrows")
arrows = {} -- has numeric and string indices
storearrow = function (arrow)
table.insert(arrows, arrow)
arrow.arrown = #arrows -- arrows[arrow.arrown] == arrow
if arrow.tag then -- (unused at the moment)
arrows[arrow.tag] = arrow -- arrows[arrow.tag] == arrow
end
return arrow
end
-- dump-to: tests
--[==[
--]==]
-- Local Variables:
-- coding: raw-text-unix
-- ee-anchor-format: "«%s»"
-- End: