www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [SAoC2022] Replace libdparse with dmd-as-a-library in D-Scanner

reply Lucian Danescu <lucidanescu28 yahoo.com> writes:
Hello everyone!

My project wants to replace the usage of `libdparse` with 
`dmd-as-a-library` in `D-Scanner`, and improvind the dmd 
interface by using it in a real life scenario.

My intention is to attempt and template all the public methods in 
`hdrgen.d`. Since header generation is done right after parsing, 
we don’t need to import files related to semantic analysis, so 
the goal here would be to get rid of all the imports that refer 
files with information relevant for semantics, and at the same 
time it would be useful to be able to use `hdrgen` with any AST 
family, not just with `ASTCodegen`.

These are some of the imports present in `hdrgen.d`:

```
import dmd.declaration;
import dmd.denum;
import dmd.dimport;
import dmd.dmodule; // like this one for example
import dmd.doc;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dtemplate;
import dmd.dversion;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
```

Example of how a templated function would look like:

```
void toCBuffer(const Statement s, OutBuffer* buf, HdrGenState* 
hgs)
{
     scope v = new StatementPrettyPrintVisitor(buf, hgs);
     (cast() s).accept(v);
}
```

to:

```
void toCBuffer(AST = dmd.astcodegen.ASTCodegen)(const 
AST.Statement s, OutBuffer* buf, HdrGenState* hgs)
{
     scope v = new StatementPrettyPrintVisitor(buf, hgs);
     (cast() s).accept(v);
}

```

By templating that method it would bring great benefits to 
ASTBase, because `toCBuffer` is needed in order to print the 
content of an AST node. Example:
ASTCodegen(statement.d)
```
override final const(char)* toChars() const
     {
         HdrGenState hgs;
         OutBuffer buf;
         .toCBuffer(this, &buf, &hgs);
         buf.writeByte(0);
         return buf.extractSlice().ptr;
     }
```
This behavior can’t be implemented also in ASTBase currently, but 
it would be possible if the functions in hdrgen.d were templated.

Now regarding the example for the `toCBuffer` function, this also 
has the following downsides: Taking advantage of the default 
template parameter means that we still have to import ASTCodegen 
(and implicitly all files necessary for semantics), and this 
would also create a circular dependency:

hdrgen.d
```
import dmd.astcodegen
```

astcodegen.d
```
import dmd.hdrgen
```

A solution that avoids these problems would be not to use a 
default value for templated functions, but that implies a lost of 
find and replace work: Example

Statement.d
```
override final const(char)* toChars() const
     {
         HdrGenState hgs;
         OutBuffer buf;

        .toCBuffer!ASTCodegen(this, &buf, &hgs); // instead of old 
toCBuffer(...)
         buf.writeByte(0);
         return buf.extractSlice().ptr;
     }
```

Since this involves a good amount of work I would like to hear 
your thoughts before diving into the implementation.
Sep 24 2022
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 25/09/2022 8:29 AM, Lucian Danescu wrote:
 My intention is to attempt and template all the public methods in 
 `hdrgen.d`. Since header generation is done right after parsing, we 
 don’t need to import files related to semantic analysis, so the goal 
 here would be to get rid of all the imports that refer files with 
 information relevant for semantics, and at the same time it would be 
 useful to be able to use `hdrgen` with any AST family, not just with 
 `ASTCodegen`.
This is outside the scope of your project but: I made a joke poll on BeerConf that we should remove that second AST implementation rather than binary literals. I'm mentioning it here as it is really quite absurd just how much extra complexity this one thing adds.
Sep 24 2022