-
-
Notifications
You must be signed in to change notification settings - Fork 184
Closed
Labels
Description
Now we have two kinds of iterators - lua-like (functions) and js-like (objects with next method). The idea is to make generated js-like iterators contain data to make lua iteration faster. Additionally, all iterator functions are extracted to helpers to avoid extra allocations.
local ____symbolMetatable = {__tostring = function(self)
if self.description == nil then
return "Symbol()"
else
return "Symbol(" .. tostring(self.description) .. ")"
end
end}
function __TS__Symbol(self, description)
return setmetatable({description = description}, ____symbolMetatable)
end
Symbol = {iterator = __TS__Symbol(_G, "Symbol.iterator")}
-- New helpers:
local __TS__IterableCoroutine = {}
local __TS__IterableArguments = {}
function __TS__IterateStep(self)
local co = self[__TS__IterableCoroutine]
local args = self[__TS__IterableArguments]
local status, value
if args then
status, value = coroutine.resume(co, unpack(args))
self[__TS__IterableArguments] = nil
else
status, value = coroutine.resume(co, self)
end
if coroutine.status(co) == "dead" then
return
end
if not status then
error(value)
end
-- Fix for #600
return true, value
end
function __TS__Iterate(result)
if not result[__TS__IterableCoroutine] then
-- TODO: Fallback for manually constructed iterators
end
return __TS__IterateStep, result
end
function __TS__GeneratorNext(self, ...)
local co = self[__TS__IterableCoroutine]
local args = self[__TS__IterableArguments]
local status, value
if args then
status, value = coroutine.resume(co, unpack(args))
self[__TS__IterableArguments] = nil
else
status, value = coroutine.resume(co, ...)
end
return {
done = coroutine.status(co) == "dead",
value = value,
}
end
function __TS__GeneratorIterator(self)
return self
end
function __TS__Generator(fn)
return function (...)
local args = {...}
return {
[__TS__IterableCoroutine] = coroutine.create(fn),
[__TS__IterableArguments] = args,
next = __TS__GeneratorNext,
[Symbol.iterator] = __TS__GeneratorIterator,
}
end
end
-------------------------------------------------------------------------------
local foo = __TS__Generator(function(self, argument)
local ____ = coroutine.yield(1)
local ____ = coroutine.yield(argument)
return 3
end)
local it = foo(_G, 2)
local x1 = it:next()
print(x1.value, x1.done) -- 1 false
local x2 = it:next()
print(x2.value, x2.done) -- 2 false
local x3 = it:next()
print(x3.value, x3.done) -- 3 true
for ____, value in __TS__Iterate(foo(_G, 2)) do
print(value) -- 1, 2
endReactions are currently unavailable