Show HN: C programming language extension: Cedro pre-processor

  • >Looking for prior implementations of this idea I’ve found magma (2014), where it is called doto. It is a macro for the cmacro[0] pre-processor

    Hey, that's me! I wrote cmacro. I'm glad someone has built a newer and better alternative (cmacro is a big mess inside and has some significant parser errors :P).

    Related to the backstitch operator, I've wondered about implementing a transform to turn code like:

      type_t value = allocate();
      operate(value);
      operate(value);
      destroy(value);
    
    Into:

      type_t value = allocate();
      type_t tmp1 = operate(value);
      type_t tmp2 = operate(tmp1);
      destroy(tmp2);
    
    To implement something like linear types[1] in C, such that each instance of type_t must be used once and only once. But I imagine this would require too much integration with the type system and code analysis.

    I wish binary inclusion was provided by more languages or build systems. For small files it's a very suitable alternative to the difficulties of packaging resources when distributing an application or library.

    Great project! C is a very useful language and this type of source-to-source compilers are huge force multipliers.

    [0]: https://github.com/eudoxia0/cmacro

    [1]: https://en.wikipedia.org/wiki/Substructural_type_system#Line...

  • This is the first public release, open source under the Apache 2.0 license.

    From the linked document:

    > Cedro is a C language extension that works as a pre-processor with four features:

    > - The backstitch @ operator.

    > - Deferred resource release.

    > - Block macros.

    > - Binary inclusion.

    The source code archive and GitHub link can be found at: https://sentido-labs.com/en/library/

    I have no intention of building this up to a new language: if you can switch to a new compiler, there are better alternatives. This is for cases where all you have is a C99 (or close to it) compiler or you need to produce plain C code for compilation on a different target machine which might only have C89.

  • Thanks for sharing.

    While the original C preprocessor can be a pain (but is still useful to have), additional pre-processors can add language features without abandoning the C standard and one's tool chain. One issue is that other developers need to either learn the dialect accepted by the preprocessor or make sense of its output.

    Here I think some good decisions have been made:

    Pros:

    + safer code

    + shorter/more concise code

    Cons:

    - learning curve of the pre-processor

    Objective C and C++ started out as pre-processors, of course... ;)

  • Impressive approach, you appear to have gone to great lengths to make the Cedro processor be plain C without any dependencies.

    As an extra related work on the deferred resource release: Dlang uses scope guards https://tour.dlang.org/tour/en/gems/scope-guards

  • Nice modest improvements. I could see using this in my previous life as a C programmer of a large project. I am a bit surprised that the defer features uses the 'auto' keyword rather than introducing a new 'defer' keyword. Seems like 'defer' would be clearer.

    But as I type this comment I realize that other syntax parsing tools like IDEs would be happier if the unprocessed code is still valid C.

  • I wonder if this also allows for grouping registers together as a macro, rather than having to allocate an array to track ports and registers like digitalWrite() in arduino.

    e.g. Instead of writing...

    ```

    ANSELBbits.ANSB3 = 0; // RB3 is digital (pinMode)

    TRISBbits.TRISB3 = 0; // RB3 is output (pinMode)

    LATBbits.LATB3 = 1; // RB3 is set to high (digitalWrite)

    ```

    we would be able to write the macro like below, where `ANSEL[RB3] --> ANSELBbits.ANSB3`

    ```

    pinMode(RB3, OUTPUT);

    digitalWrite(RB3, HIGH);

    ```

  • The deferred resource cleanup is really the thing I wish the most was in C. I know that it's relatively un-"C-like", but having to make sure to clean up objects on failure is one of the more annoying things that make my code messy. I like the `defer` paper and proposal linked in this article.

  • Nice project! It makes me think how awesome it would have been if the C programming language had an actual community around it with package repositories and opinions and just actual gradual improvement of everything. Instead of the isolated projects each with their own build systems and styles, and the IRC channels with angry people telling noobs to read K&R.