Lightweight Cooperative Multitasking in C

I found this MSDN article quite interesting, it was one of those things that I wanted to try out for myself, just to see what was going on. For some reason, I decided to port the example code shown in the article to C, so here is the result:

// A working C example of the code described in the article here:
// http://msdn.microsoft.com/en-us/magazine/jj553509.aspx

#include <stdio.h>

#define task_begin(name, parameter)      \
                                         \
char name(parameter)                     \
{                                        \
  char yield_ = 0;                       \
  switch (args->task_)                   \
  {                                      \
    case 0:

#define task_end                         \
                                         \
    }                                    \
    args->task_ = 0;                     \
    return 0;                            \
  }

#define task_wait_until(expression)      \
                                         \
  args->task_ = __LINE__; case __LINE__: \
  if (!(expression))                     \
  {                                      \
    return 1;                            \
  }

#define task_return()                    \
                                         \
  args->task_ = 0;                       \
  return 0;

#define task_wait_while(expression)      \
                                         \
  task_wait_until(!(expression))
#define task_wait_for(name, parameter)   \
                                         \
  task_wait_while(name(parameter))

#define task_yield_until(expression)     \
                                         \
  yield_ = 1;                            \
  args->task_ = __LINE__; case __LINE__: \
  if (yield_ || !(expression))           \
  {                                      \
    return 1;                            \
  }
#define task_yield()                     \
                                         \
  task_yield_until(1)

typedef struct input_args
{
  int *target;
  int task_;
} input_args;

typedef struct average_args
{
  int *source;
  int sum;
  int count;
  int average;
  int task_;
} average_args;

task_begin(input, input_args *args)
{
  for (;;)
  {
    printf("number: ");
    if (!scanf_s("%d", args->target))
    {
      task_return();
    }
    task_yield();
  }
}
task_end

task_begin(average, average_args *args)
{
  args->sum = 0;
  args->count = 0;
  args->average = 0;
  for (;;)
  {
    args->sum += *args->source;
    ++args->count;
    args->average = args->sum / args->count;
    task_yield();
  }
}
task_end

int main()
{
  int share = -1;
  average_args aa = { &share };
  input_args ia = { &share };

  while (input(&ia))
  {
    average(&aa);
    printf("sum=%d count=%d average=%d\n", aa.sum, aa.count, aa.average);
  }
  return 0;
}

I hope that I got it right ;-) I didn't spend very much time on it. But I thought that somebody else might find it interesting, or maybe I'd want to come back to it at some point. So I thought that I'd post it... just in case.