A (pure) C extension

Posted on March 12, 2014 by phimuemue

Over three years ago, I came across a little problem and was able to write a header file for C++ that allowed the programmer two write things like the following:

10 times {
    do_something_here();
}

This did exactly what you would expect from what it read. Additionally, the implementation had support for an implicitly generated counting variable denoted by a single underscore. The only drawback: It was only for C++.

Now, over three years later, I can claim that I have found a way to implement (at least to some extent) the original thing in pure C.

The header file

The header file itself is not that large at all:

volatile char _A[19] = {0};
#define _Y 10
int _D=0,_O=0,_S=0,_M[_Y],_C[_Y],_L;
#define _ _C[_D]
#define times [_A]=1;_D++;_S=0;for(_S \
              =-1;_A[_S]==0;++_S){ _M \
              [_D]=_S+1;}_A[_S]=0;for \
              (_C[_D]=0;_O=_D,(_L=!!( \
              _C[_O]<_M[_O] )),_C[_O] \
              ==_M[_O]?_D--: 1,_O=_D, \
              _L;_=_C[_O]++)

You can paste this into a header file that can be included in other C source files to support the features described now.

Usage

Let me show some sample code to illustrate what the extension can do:

#include<stdio.h>
#include"extension.h"

int main(int argc, char** argv){
    3 times printf("Hello.\n");
    3 times printf("Score: 0 : %d\n", _);
    2 times {
        printf("Counting: ");
        9 times printf("%d ", _);
        printf("\n");
    }
    5 times {
        printf("Counting up to %d: ", _);
        _ times printf("%d ", _);
        printf("\n");
    }
    return 0;
}

Features

Restrictions

Implementation details

#define MAXSIZE 20
volatile char counterarray[MAXSIZE] = {0};
 
#define MAXDEPTH 10
int depth=0;
int olddepth=0;
int searcher=0;
int searchermax[MAXDEPTH];
int counter[MAXDEPTH];
int lastloop;
#define _ counter[depth]
#define times [counterarray]=1; \
              depth++; \
              searcher = 0;\
              for(searcher=-1; counterarray[searcher]==0; ++searcher){ \
                  searchermax[depth]=searcher+1; \
              } \
              counterarray[searcher] = 0; \
              for(counter[depth]=0; \
                      olddepth=depth, \
                      (lastloop=!!(counter[olddepth]<searchermax[olddepth])), \
                      counter[olddepth]==searchermax[olddepth]?depth--:1, \
                      olddepth = depth, \
                      lastloop; \
                      _=counter[olddepth]++)

The implementation itself basically has to keep track of the following:

It does so by defining a macro times. This macro then takes all actions necessary to support the desired behaviour: