forth-stuff/DataStructures.tl

116 lines
2.5 KiB
Plaintext

local InputStream = require("InputStream")
local type DataStructures = record
record Stack
contents: {any}
top: number
push: function(Stack, any)
pop: function(Stack)
new: function(Stack): Stack
end
record Dictionary
contents: {string: WordInfo}
define: function(Dictionary, string, WordInfo)
end
record WordInfo
func: function(State, ...: any)
immediate: boolean
new: function(WordInfo, function(State), boolean): WordInfo
end
record State
dataStacks: {Stack}
compilerStack: Stack
activeDataStack: Stack
interrupts: {function(State)}
activeInputStream: InputStream
dictionaries: {Dictionary}
state: boolean
new: function(State): State
addDataStack: function(State, Stack)
changeCompilerStack: function(State, Stack)
changeActiveDataStack: function(State, number)
end
end
local Stack, State, Dictionary, WordInfo = DataStructures.Stack, DataStructures.State, DataStructures.Dictionary, DataStructures.WordInfo
local wordi_mt = {__index = WordInfo}
function WordInfo:new(funct: function(State, ...: any), imm: boolean): WordInfo
return setmetatable({func = funct, immediate = imm} as WordInfo, wordi_mt)
end
local state_mt = {__index = State}
function State:new(): State
return setmetatable(
{
dataStacks = {},
compilerStack = Stack:new(),
dictionaries = {}
} as State,
state_mt)
end
function State:addDataStack(data: Stack)
table.insert(self.dataStacks, data)
end
function State:changeCompilerStack(compilerStack: Stack)
self.compilerStack = compilerStack
end
--function State:changeActiveDataStack(stackIndex: number)
-- assert(stackIndex <= #self.dataStacks and stackIndex > 0)
-- self.activeDataStack = self.dataStacks[stackIndex]
--end
function Stack:push(val: any)
self.top = self.top + 1
table.insert(self.contents,val)
end
function Stack:pop(): any
self.top = self.top -1
if self.top < 0 then
error("Stack underflow")
end
return table.remove(self.contents)
end
local stack_mt = {__index = Stack}
function Stack:new(): Stack
return setmetatable({contents = {}, top = 0} as Stack, stack_mt)
end
-- operations
function Dictionary:lookup(word: string): WordInfo | nil
return self.contents[word]
end
function Dictionary:define(word: string, info: WordInfo)
self.contents[word] = info
end
local dict_mt = {__index = Dictionary}
function Dictionary:new(): Dictionary
return setmetatable({contents = {}} as Dictionary, dict_mt)
end
return DataStructures