Skip to content

Commit 211ec51

Browse files
committed
Add frontend module and example
1 parent aac92fd commit 211ec51

3 files changed

Lines changed: 161 additions & 0 deletions

File tree

dub.sdl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ subPackage {
9999
"src/ddmd/escape.d" \
100100
"src/ddmd/expression.d" \
101101
"src/ddmd/expressionsem.d" \
102+
"src/ddmd/frontend.d" \
102103
"src/ddmd/func.d" \
103104
"src/ddmd/hdrgen.d" \
104105
"src/ddmd/id.d" \

src/ddmd/frontend.d

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Compiler implementation of the
3+
* $(LINK2 http://www.dlang.org, D programming language).
4+
*
5+
* This module contains high-level interfaces for interacting
6+
with DMD as a library.
7+
*
8+
* Copyright: Copyright (c) 1999-2017 by The D Language Foundation, All Rights Reserved
9+
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
10+
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11+
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/ddmd/id.d, _id.d)
12+
*/
13+
module ddmd.frontend;
14+
15+
// Online documentation: https://dlang.org/phobos/ddmd_frontend.html
16+
17+
/**
18+
Initializes the DMD compiler
19+
*/
20+
void initDMD()
21+
{
22+
import ddmd.globals : global;
23+
import ddmd.dmodule : Module;
24+
import ddmd.id : Id;
25+
import ddmd.mtype : Type;
26+
import ddmd.target : Target;
27+
import ddmd.expression : Expression;
28+
import ddmd.objc : Objc;
29+
import ddmd.builtin : builtin_init;
30+
31+
Type._init();
32+
Id.initialize();
33+
Module._init();
34+
Target._init();
35+
Expression._init();
36+
Objc._init();
37+
builtin_init();
38+
}
39+

test/dub_package/frontend.d

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env dub
2+
/+dub.sdl:
3+
dependency "dmd" path="../.."
4+
+/
5+
import std.stdio;
6+
7+
// add import paths
8+
void addImports(T)(T path)
9+
{
10+
import ddmd.globals : global;
11+
import ddmd.arraytypes : Strings;
12+
13+
Strings* res = new Strings();
14+
foreach (p; path)
15+
{
16+
import std.string : toStringz;
17+
Strings* a = new Strings();
18+
a.push(p.toStringz);
19+
res.append(a);
20+
}
21+
global.path = res;
22+
}
23+
24+
// finds a dmd.conf and parses it for import paths
25+
auto findImportPaths()
26+
{
27+
import std.string : fromStringz, toStringz;
28+
import std.path : buildPath, buildNormalizedPath, dirName;
29+
import std.process : env = environment;
30+
import ddmd.dinifile : findConfFile;
31+
32+
auto dmdFilePath = env.get("DMD");
33+
auto iniFile = findConfFile(dmdFilePath.toStringz, "dmd.conf");
34+
35+
import std.algorithm, std.range, std.regex;
36+
return File(iniFile.fromStringz, "r")
37+
.byLineCopy
38+
.dropOne
39+
.front
40+
.matchAll("-I[^ ]+".regex)
41+
.joiner
42+
.map!(a => a.drop(2).replace("%@P%", dmdFilePath.dirName))
43+
.map!buildNormalizedPath;
44+
}
45+
46+
// test frontend
47+
void main()
48+
{
49+
import ddmd.astcodegen : ASTCodegen;
50+
import ddmd.dmodule : Module;
51+
import ddmd.globals : global, Loc;
52+
import ddmd.frontend : initDMD;
53+
import ddmd.parse : Parser;
54+
import ddmd.statement : Identifier;
55+
import ddmd.tokens : TOKeof;
56+
import ddmd.id : Id;
57+
import ddmd.globals : global;
58+
59+
global._init;
60+
global.params.isLinux = 1;
61+
initDMD;
62+
findImportPaths.addImports;
63+
64+
auto parse(Module m, string code) {
65+
scope p = new Parser!ASTCodegen(m, code, false);
66+
p.nextToken; // skip the initial token
67+
auto members = p.parseModule;
68+
assert(!p.errors, "Parsing error occurred.");
69+
return members;
70+
}
71+
72+
Identifier id = Identifier.idPool("test");
73+
auto m = new Module("test.d", id, 0, 0);
74+
m.members = parse(m, q{
75+
void foo() {
76+
foreach (i; 0..10) {
77+
}
78+
}
79+
});
80+
81+
void semantic() {
82+
import ddmd.dsymbolsem : dsymbolSemantic;
83+
import ddmd.semantic : semantic2, semantic3;
84+
85+
m.importedFrom = m;
86+
m.importAll(null);
87+
m.dsymbolSemantic(null);
88+
m.semantic2(null);
89+
m.semantic3(null);
90+
}
91+
semantic();
92+
93+
auto prettyPrint() {
94+
import ddmd.root.outbuffer: OutBuffer;
95+
import ddmd.hdrgen : HdrGenState, PrettyPrintVisitor;
96+
97+
OutBuffer buf = { doindent: 1 };
98+
HdrGenState hgs = { fullDump: 1 };
99+
scope PrettyPrintVisitor ppv = new PrettyPrintVisitor(&buf, &hgs);
100+
m.accept(ppv);
101+
return buf;
102+
}
103+
auto buf = prettyPrint();
104+
105+
auto expected =q{import object;
106+
void foo()
107+
{
108+
{
109+
int __key3 = 0;
110+
int __limit4 = 10;
111+
for (; __key3 < __limit4; __key3 += 1)
112+
{
113+
int i = __key3;
114+
}
115+
}
116+
}
117+
};
118+
import std.string : replace, fromStringz;
119+
auto generated = buf.extractData.fromStringz.replace("\t", " ");
120+
assert(expected == generated, generated);
121+
}

0 commit comments

Comments
 (0)