forth-stuff/InputStream.tl

88 lines
1.6 KiB
Plaintext
Raw Normal View History

2021-05-12 03:58:33 +00:00
local type InputStream = record
str: string
offset: number
refill: function(): string
new: function(InputStream, function(): string): InputStream
2021-05-19 06:26:57 +00:00
__setRefill: function(InputStream, function(): string)
readCurrentCharacter: function(): string
advanceOffset: function(): string
2021-05-12 03:58:33 +00:00
end
local istream_mt = {__index = InputStream}
function InputStream:_manageBuffer()
local length = 0
if self.str then
length = #self.str
else
length = -1
end
if not self.str then
self.str = self.refill()
self.offset = 1
end
2021-05-19 05:37:47 +00:00
if self.offset > #self.str then
2021-05-12 03:58:33 +00:00
self.str = self.refill()
self.offset = 1
end
end
2021-05-19 05:37:47 +00:00
local function initial_stream(): string
2021-05-20 01:21:17 +00:00
return ""
2021-05-19 05:37:47 +00:00
end
2021-05-12 03:58:33 +00:00
-- constructors
function InputStream:new(refill: function(): string): InputStream
2021-05-19 05:37:47 +00:00
refill = refill or initial_stream
2021-05-19 06:26:57 +00:00
local istream = setmetatable(
{
string = "",
2021-05-19 05:37:47 +00:00
offset = 1,
} as InputStream,
istream_mt)
2021-05-19 06:26:57 +00:00
istream:__setRefill(refill)
return istream
end
2021-05-12 03:58:33 +00:00
-- setters/getters
2021-05-19 06:26:57 +00:00
function InputStream:__setRefill(func: function(): string)
2021-05-12 03:58:33 +00:00
self.refill = func
2021-05-19 05:37:47 +00:00
self:_manageBuffer()
2021-05-12 03:58:33 +00:00
end
--
2021-05-20 01:21:17 +00:00
function InputStream:curr(): string | nil
if self.offset > #self.str then
self:_manageBuffer()
end
if #self.str > 0 and self.offset < #self.str + 1 then
2021-05-20 01:21:17 +00:00
return self.str:sub(self.offset, self.offset)
end
return nil
2021-05-12 03:58:33 +00:00
end
2021-05-20 01:21:17 +00:00
function InputStream:next(): string | nil
if self.offset > #self.str then
self:_manageBuffer()
end
2021-05-20 01:21:17 +00:00
local current_char: string | nil = nil
if #self.str > 0 then
current_char = self.str:sub(self.offset, self.offset)
self.offset = self.offset + 1
end
return current_char
2021-05-12 03:58:33 +00:00
end
return InputStream