Thread overview
Codebuilder with line info insertion
May 10, 2016
Jesse Phillips
Jul 24, 2016
Jesse Phillips
Jul 24, 2016
Dicebot
Jul 24, 2016
Jesse Phillips
May 10, 2016
One of the things that can be really annoying about using string mixin's, especially when there is a lot of code, is that the compile complains about syntax errors on a line within the mixin that doesn't exist in the code.

While at the D Conference this issue was mention along with the file/line feature of function calls. It got me thinking about a code builder I had been using in ProtocolBuffer[1]. I just checked and found that the use of the #line language feature combined with the file/line feature allowed for providing better information about where a mixin went wrong. So I pulled out the code and packaged it for dub[2].

Documentation is lacking in examples, but is used with ProtocolBuffer[3]. It uses a put/push/pop approach to provide some freedom in organizing the code; but I'll admit doesn't help readability (the call to finalize will pop all code elements push to the stack).

This package doesn't do too much to help with building code, one of the main parts it provides is pretty printing (indenting) which isn't important for a mixin. So please feel free to send of suggestions from experience trying to use it, I won't consider the API stable at this point.

Since ProtocolBuffer support D1 and D2, so does this library.

Instead of -- test.d-mixin-4(4): Error: semicolon expected, not '}'

I get -- test.d(11): Error: semicolon expected, not '}'

---------------------
   import codebuilder.structure;

   void main() {
      mixin(genCode); // Line 4
   }

   auto genCode() {
      auto cb = CodeBuilder(1);

      cb.put("struct m {");
      cb.push("}"); // Line 11
      cb.put("int a"); // Missing semicolon

      return cb.finalize;
   }
---------------------

1. https://github.com/JesseKPhillips/ProtocolBuffer/
2. http://code.dlang.org/packages/codebuilder
3. https://github.com/JesseKPhillips/ProtocolBuffer/blob/master/conversion/dlang.d
July 24, 2016
On Tuesday, 10 May 2016 at 15:42:00 UTC, Jesse Phillips wrote:

> 1. http://code.dlang.org/packages/protocolbuffer
> 2. http://code.dlang.org/packages/codebuilder
> 3. https://github.com/JesseKPhillips/ProtocolBuffer/blob/master/conversion/dlang.d

I wish to announce version 1.0.0 of CodeBuilder. As the code originally came from ProtocolBuffer I've now eat some dog food by utilizing the library within ProtocolBuffer. I've also put in unittests and a readme.

The Dub package provides two configurations, one for mixins and one as a file writer. When using the file writer it is of no interest to modify the line numbers as you'll actually have a D source file to look at.

http://code.dlang.org/packages/codebuilder

Change Highlights

* Reduced complexity. Originally I was trying to store generated code in to many different places, There was the current state, the stack that held items which would later be popped into the current state, a build so code could be structured before putting it on the stack, and the current state could be returned by asking for it's memory. All that goes away and instead another CodeBuilder can be put or pushed into another.

* The string used for indentation can be specified (but is global for all code builders.

* The code string isn't created while putting the string into the builder. Instead it is stored as an operation that is used to generate the string when calling finalize(). This makes indentation consistent when putting one CodeBuilder into another.

I'd also like to note that Google's Protocol Buffer source has a similar need, but I like my API better :)


https://github.com/google/protobuf/blob/master/src/google/protobuf/io/printer.cc

https://github.com/google/protobuf/blob/master/src/google/protobuf/compiler/cpp/cpp_file.cc
July 24, 2016
How much of compile-time overhead does it add compared to naive string concatenation?
July 24, 2016
On Sunday, 24 July 2016 at 19:36:50 UTC, Dicebot wrote:
> How much of compile-time overhead does it add compared to naive string concatenation?

I would expect fairly large, It only increases the amount of memory used and concatenation operations. It stores each requested string into array of structures, that later are used for concatenating together.

I don't have any performance numbers, nor do I have a large amount of code generation to try and tax compile-time work. I ran ProtocolBuffer with -profile and it should the call to finalize(), ~9000 microseconds per call (runtime).

I'd be happy to accept performance improvements (including breaking changes), but if you've already got long compile times due to CTFE I can't recommend using it.