How sequences are evaluated by the templating engine
In short, the engine will create a coroutine whenever it finds a {{#sequence}} template tag. This coroutine will start, and will execute as usual until it yields.
Yielding false, the engine assumes the iteration ended, and proceeds to find the next matching {{/sequence}} tag to continue from there.
On a true yield, however, the engine will recurse to apply everything is between the iteration tags, repeating the process when the iteration-end tag is found and the coroutine yields true again.
The coroutine is supposed to clean up after itself before returning a false value.
Professor Butts would be proud. Maybe. Source.
A sample generator function is shown below. It iterates over a directory with readdir(), returning 1 on new item availability and 0 when there isn't anything else to do. Notice that initialization, iteration, and cleanup is all contained within a single function.
Also, notice that there's no need to copy any values to and from the structure -- calling coro_yield() will of course maintain the stack alive, so local variables can be used outside this function as long as a reference to them can be obtained.
int dir_list_generator(coro_t *coro)
{
DIR *dir;
struct dirent *ent;
struct file_list *fl = coro_get_data(coro);
dir = opendir(fl->path);
if (!dir)
return 0;
while ((ent = readdir(dir))) {
fl->list.name = ent->d_name;
coro_yield(coro, 1); /* !0 means "iter not done yet" */
}
closedir(dir);
return 0;
}
The details of how the variable descriptors are set up are explained in the commit message that introduced this change. (The commit itself is quite buggy, but whatever I could find has been fixed in HEAD already.)
In an ideal world, one would use something akin to Golang's Channels, but if I were to implement them in lwan it would take perhaps another year. Plus, they wouldn't be as efficient as setting some pointers. But they might be useful in the future, so I'm not completely discarding the idea. Although I've never written a single line of Go code, I'm reading a lot about it recently and it is sort of positively impacting the way I think about programming. But I digress.
Copyright © 2023 L. A. F. Pereira