2021-05-12 03:58:33 +00:00
|
|
|
local type InputStream = record
|
|
|
|
str: string
|
|
|
|
offset: number
|
|
|
|
refill: function(): string
|
2021-05-13 05:23:42 +00:00
|
|
|
|
|
|
|
new: function(InputStream, function(): string): InputStream
|
|
|
|
|
2021-05-19 06:26:57 +00:00
|
|
|
__setRefill: function(InputStream, function(): string)
|
2021-05-13 05:23:42 +00:00
|
|
|
|
|
|
|
readCurrentCharacter: function(): string
|
|
|
|
advanceOffset: function(): string
|
2021-05-12 03:58:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local istream_mt = {__index = InputStream}
|
|
|
|
|
|
|
|
function InputStream:_manageBuffer()
|
2021-05-20 07:00:48 +00:00
|
|
|
local length = 0
|
|
|
|
if self.str then
|
|
|
|
length = #self.str
|
|
|
|
else
|
|
|
|
length = -1
|
|
|
|
end
|
2021-05-13 05:23:42 +00:00
|
|
|
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
|
2021-05-13 05:23:42 +00:00
|
|
|
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(
|
2021-05-13 05:23:42 +00:00
|
|
|
{
|
|
|
|
string = "",
|
2021-05-19 05:37:47 +00:00
|
|
|
offset = 1,
|
2021-05-13 05:23:42 +00:00
|
|
|
} as InputStream,
|
|
|
|
istream_mt)
|
2021-05-19 06:26:57 +00:00
|
|
|
istream:__setRefill(refill)
|
|
|
|
return istream
|
2021-05-13 05:23:42 +00:00
|
|
|
|
|
|
|
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
|
2021-05-20 07:00:48 +00:00
|
|
|
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
|
2021-05-20 07:00:48 +00:00
|
|
|
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
|
2021-05-19 04:46:50 +00:00
|
|
|
return current_char
|
2021-05-12 03:58:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return InputStream
|
|
|
|
|
|
|
|
|
|
|
|
|