add DataStructures module

This commit is contained in:
Starfflame 2021-05-12 03:32:25 -05:00
parent 5dc66425f5
commit c20df3883f
5 changed files with 160 additions and 13 deletions

View File

@ -1,17 +1,33 @@
local Dictionary = require("Dictionary") local ds = require("DataStructures")
local Stack = require("Stack") local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State
local WordInfo = require("WordInfo")
local State = require("State")
-- helper functions -- helper functions
function areNumbers(a: any, b: any): boolean function areNumbers(a: any, b: any): boolean
return a is number and b is number return a is number and b is number
end end
function getActiveDataStack(state: State): Stack function getActiveDataStack(state: State): Stack
return state.activeDataStack return state.activeDataStack
end end
function isNumber(token: string): boolean
if tonumber(token) ~= nil then
return true
else
return false
end
end
function isWhitespace(chr: string): boolean
return (chr == " " or
chr == "\t" or
chr == "\r" or
chr == "\n" or
chr == "\v" or
chr == "\f")
end
function popTwoOperands(state: State): any, any function popTwoOperands(state: State): any, any
local stack = getActiveDataStack(state) local stack = getActiveDataStack(state)
local b: any = stack:pop() local b: any = stack:pop()
@ -64,6 +80,24 @@ function dot(state: State)
end end
function skipWhitespace(state: State)
local chr = state.activeInputStream:readCurrentCharacter()
while (isWhitespace(chr)) do
chr = state.activeInputStream:advanceOffset()
end
end
function parseToken(state: State): string
local chr = state.activeInputStream:readCurrentCharacter()
local token = ""
while(not isWhitespace(chr)) do
token = token..chr
chr = state.activeInputStream:advanceOffset()
end
end
local CoreWords = Dictionary:new() local CoreWords = Dictionary:new()
local AddInfo = WordInfo:new(add, false) local AddInfo = WordInfo:new(add, false)
local SubInfo = WordInfo:new(sub, false) local SubInfo = WordInfo:new(sub, false)

93
DataStructures.tl Normal file
View File

@ -0,0 +1,93 @@
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

View File

@ -1,4 +1,3 @@
local State = require("State")
local WordInfo = require("WordInfo") local WordInfo = require("WordInfo")

24
ForthInterpreter.tl Normal file
View File

@ -0,0 +1,24 @@
-- helper functions
function isNumber(token: string): boolean
if tonumber(token) ~= nil then
return true
else
return false
end
end
for line in io.lines() do
local tokens = {}
for token in line:gmatch("%S+") do
table.insert(tokens, token)
end
for idx, val in ipairs(tokens) do
print(idx, val, isNumber(val))
end
end

View File

@ -1,14 +1,14 @@
local Stack = require("Stack") local Stack = require("Stack")
local InputStream = require("InputStream")
local Dictionary = require("Dictionary")
local type State = record local type State = record
dataStacks: {Stack} dataStacks: {Stack}
compilerStack: Stack compilerStack: Stack
activeDataStack: Stack activeDataStack: Stack
interrupts: {function(State)} interrupts: {function(State)}
-- dictionaries: {string:any} activeInputStream: InputStream
dictionaries: {Dictionary}
end end
local state_mt = {__index = State} local state_mt = {__index = State}
@ -34,7 +34,4 @@ function State:changeActiveDataStack(stackIndex: number)
end end
return State return State