Earlier quoted context omitted.
Back in the day, we had multiple windows on the screen at one time, so this wasn't a problem. I think it was Windows which defaulted to full-screen, and led to the plague of sites assuming that the browser would be full-width on a landscape screen, but I could be wrong. Although I love using a tiling window manager now, I kinda miss my old System 8 Macintosh setup, with Netscape open in one window & Think C (or was i…
On a Mac, Spectacle gets you pretty much there. I haven't found something similar for Windows, but I'm sure there is one.
Coroutines in C (2000)
41–50 of 61 posts
Re: Coroutines in C (2000)
#42I guess one of the applications of Coroutines could be WebAssembly. When you run WebAssembly on a website which needs 100% of the CPU for more than a few ms, you have to use the "setTimeout(fn, 0)" trick to prevent the "this website stopped responding" message. That means you have to store the current state at some point and continue in the function fn (after waiting 0 ms). Languages which support coroutines out of t…
Aren't Web Workers (which can run WASM) supposed to fill that role?
Re: Coroutines in C (2000)
#43I really like that trick. It's very powerful. But I wonder what the difference is between this and protothreads?
Re: Coroutines in C (2000)
#44Earlier quoted context omitted.
The only issue of these websites is the width: using the full width of the screen is just too much for reading. If you add {max-width: 60em; margin: auto;} to the body tag it looks much better.
Not too wide for my browser windows, which are a bit under 50% of screen width.
Re: Coroutines in C (2000)
#45Earlier quoted context omitted.
Not too wide for my browser windows, which are a bit under 50% of screen width.
Likewise I would say not enough people put their monitors in portrait. It's amazing for coding.
And it also works when I want to play games, or watch anything recorded in landscape, which is most media.
Re: Coroutines in C (2000)
#46Nevertheless, even in C, I'd find it conceptually simpler to understand if the functions were written as pure functions, returning a tuple with (c, state) and passing the state back into the caller. Using non-idiomatic tricks and macros in this way is harder to read and understand.
Re: Coroutines in C (2000)
#47There are implementations that use the GCC goto and label pointer, which then avoid the need for a switch statement.
Re: Coroutines in C (2000)
#48As an OOP dev this kind of horrifies me, even though it works okay (though it's surely not thread-safe?) Nevertheless, even in C, I'd find it conceptually simpler to understand if the functions were written as pure functions, returning a tuple with (c, state) and passing the state back into the caller. Using non-idiomatic tricks and macros in this way is harder to read and understand.
static int
u_getopt_r(int argc, char *const argv[], const char *shortopts, struct u_getopt_r *K)
{
K->optarg = NULL;
K->optopt = 0;
GETOPT_ENTER;
while (K->optind cp = argv[K->optind];
if (!K->cp || *(K->cp) != '-' || !strcmp(K->cp, "-")) {
break;
} else if (!strcmp(K->cp, "--")) {
K->optind++;
break;
}
for (;;) {
char *shortopt;
if (!(K->optopt = *++K->cp)) {
K->optind++;
break;
} else if (!(shortopt = strchr(shortopts, K->optopt))) {
getopt_err(argc, argv, shortopts, K, "illegal option -- %c\n", K->optopt);
GETOPT_YIELD('?');
} else if (shortopt[1] != ':') {
GETOPT_YIELD(K->optopt);
} else if (K->cp[1]) {
K->optarg = &K->cp[1];
K->optind++;
GETOPT_YIELD(K->optopt);
break;
} else if (K->optind + 1 optarg = argv[K->optind + 1];
K->optind += 2;
GETOPT_YIELD(K->optopt);
break;
} else {
getopt_err(argc, argv, shortopts, K, "option requires an argument -- %c\n", K->optopt);
K->optind++;
GETOPT_YIELD((*shortopts == ':')? ':' : '?');
break;
}
}
}
GETOPT_LEAVE;
return -1;
}
Here's macro magic, the complexity of which is more than made up for by the readability of the core code: #define GETOPT_ENTER \
do { \
static const int pc0 = __LINE__; \
switch (pc0 + K->pc) { \
case __LINE__: (void)0
#define GETOPT_SAVE_AND_DO(do_statement) \
do { \
K->pc = __LINE__ - pc0; \
do_statement; \
case __LINE__: (void)0; \
} while (0)
#define GETOPT_YIELD(rv) \
GETOPT_SAVE_AND_DO(return (rv))
#define GETOPT_LEAVE \
GETOPT_SAVE_AND_DO(break); \
} \
} while (0)Re: Coroutines in C (2000)
#49Earlier quoted context omitted.
For those wondering how it works, libdill keeps track of context between function calls and does some clever stack modification in assembly.
I wonder if it would work from Rust. I was looking at something minimal like this.
Re: Coroutines in C (2000)
#50Has anyone used these to write interrupt service routines? Seems like there's an opportunity here. You can take your existing synchronous code and not have to rewrite it into something like continuation-passing style. This is a source of a lot of bugs.
I have, it's not pretty either: https://github.com/nraynaud/webgcode/blob/gh-pages/interpola...