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