<div dir="ltr">I didn't see your announcement, but... AWESOME!!<div><br></div><div>This could be the basis for some really good tutorials on making compiler backends etc...</div><div><br></div><div>We need more little teaser examples like the one you posted in the beginning of this thread.</div><div><br></div><div>PS: I did already check the code out on github because I watch <a href="http://code.dlang.org">code.dlang.org</a> (a lot).</div><div><br></div><div>Thanks!</div><div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 29, 2016 at 12:42 PM, Alexander Breckel via Digitalmars-d <span dir="ltr"><<a href="mailto:digitalmars-d@puremagic.com" target="_blank">digitalmars-d@puremagic.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I just tried to use the DMD frontend as a Dub package in my own project to parse and analyze D files and it ... just worked. The dub.json for dmd is fairly small and doesn't require any changes to the code. This might be common knowledge, but I was completely unprepared for this :)<br>
<br>
Please note: This is "only" the dmd frontend (lexer, parser, semantic passes, CTFE). Code generation will be more complicated.<br>
<br>
The following dub pre-generation hooks were necessary:<br>
<br>
- run src/idgen.d to generate src/id.d<br>
- create verstr.h and SYSCONFDIR.imp<br>
- create and link source/ddmd/ to src/<br>
<br>
The last point makes ddmd modules reside in its correct package. I'm using a symbolic link for this, which is the only reason this approach is currently limited to Linux. In the long run, I think the cleanest way would be to place all ddmd files in src/ddmd/ and just leave mars.d and things like idgen.d in the main src/ directory.<br>
<br>
For demonstration purposes, here is a dub package to play around with:<br>
<a href="http://code.dlang.org/packages/ddmd-experimental" rel="noreferrer" target="_blank">http://code.dlang.org/packages<wbr>/ddmd-experimental</a><br>
<br>
Here is the dub.json that was used:<br>
<a href="https://github.com/aneas/ddmd-experimental/blob/master/dub.json" rel="noreferrer" target="_blank">https://github.com/aneas/ddmd-<wbr>experimental/blob/master/dub.j<wbr>son</a><br>
<br>
And here is an example program using this API, have fun!<br>
(run with $ chmod +x file.d; ./file.d)<br>
---<br>
#!/usr/bin/env dub<br>
/+ dub.sdl:<br>
name "ddmd-example"<br>
dependency "ddmd-experimental" version="~>2.71.2-b2dub"<br>
+/<br>
<br>
import std.path;<br>
import std.stdio;<br>
import std.string;<br>
import ddmd.builtin;<br>
import ddmd.dmodule;<br>
import ddmd.dclass;<br>
import ddmd.dsymbol;<br>
import ddmd.expression;<br>
import ddmd.func;<br>
import ddmd.globals;<br>
import <a href="http://ddmd.id" rel="noreferrer" target="_blank">ddmd.id</a>;<br>
import ddmd.identifier;<br>
import ddmd.mtype;<br>
import ddmd.visitor;<br>
<br>
void main(string[] args) {<br>
        if(args.length != 2) {<br>
                writeln("prints top-level function and class declarations");<br>
                writeln("usage: ", args[0].baseName, " d-filepath");<br>
                return;<br>
        }<br>
<br>
        // Initialization<br>
        global._init();<br>
        global.params.isLinux = true;<br>
        Type._init();<br>
        Id.initialize();<br>
        Module._init();<br>
        Expression._init();<br>
        builtin_init();<br>
<br>
        // Read and parse specified module<br>
        auto id = Identifier.idPool(args[1].base<wbr>Name.stripExtension);<br>
        auto m = new Module(args[1].toStringz, id, false, false);<br>
        m.read(Loc());<br>
        m.parse();<br>
<br>
        // Output<br>
        m.accept(new class Visitor {<br>
                extern(C++):<br>
                alias visit = Visitor.visit;<br>
                override void visit(Module m) {<br>
                        foreach(i; 0 .. m.members.dim)<br>
                                (*m.members)[i].accept(this);<br>
                }<br>
                override void visit(Dsymbol s) {<br>
                }<br>
                override void visit(FuncDeclaration fd) {<br>
                        writeln("function ", fd.ident.toString);<br>
                }<br>
                override void visit(ClassDeclaration cd) {<br>
                        writeln("class ", cd.ident.toString);<br>
                }<br>
        });<br>
}<br>
<br>
</blockquote></div><br></div>