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