mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Add frontend module and example
This commit is contained in:
parent
2f0b835f3f
commit
e88073d788
3 changed files with 219 additions and 0 deletions
1
dub.sdl
1
dub.sdl
|
@ -100,6 +100,7 @@ subPackage {
|
|||
"src/dmd/escape.d" \
|
||||
"src/dmd/expression.d" \
|
||||
"src/dmd/expressionsem.d" \
|
||||
"src/dmd/frontend.d" \
|
||||
"src/dmd/func.d" \
|
||||
"src/dmd/gluelayer.d" \
|
||||
"src/dmd/hdrgen.d" \
|
||||
|
|
56
src/dmd/frontend.d
Normal file
56
src/dmd/frontend.d
Normal file
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Compiler implementation of the
|
||||
* $(LINK2 http://www.dlang.org, D programming language).
|
||||
*
|
||||
* This module contains high-level interfaces for interacting
|
||||
with DMD as a library.
|
||||
*
|
||||
* Copyright: Copyright (c) 1999-2017 by The D Language Foundation, All Rights Reserved
|
||||
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
|
||||
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
|
||||
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/id.d, _id.d)
|
||||
*/
|
||||
module dmd.frontend;
|
||||
|
||||
// Online documentation: https://dlang.org/phobos/dmd_frontend.html
|
||||
|
||||
/**
|
||||
Initializes the DMD compiler
|
||||
*/
|
||||
void initDMD()
|
||||
{
|
||||
import dmd.dmodule : Module;
|
||||
import dmd.globals : global;
|
||||
import dmd.id : Id;
|
||||
import dmd.mtype : Type;
|
||||
import dmd.target : Target;
|
||||
import dmd.expression : Expression;
|
||||
import dmd.objc : Objc;
|
||||
import dmd.builtin : builtin_init;
|
||||
|
||||
global._init;
|
||||
|
||||
version(linux)
|
||||
global.params.isLinux = 1;
|
||||
else version(OSX)
|
||||
global.params.isOSX = 1;
|
||||
else version(FreeBSD)
|
||||
global.params.isFreeBSD = 1;
|
||||
else version(Windows)
|
||||
global.params.isWindows = 1;
|
||||
else version(Solaris)
|
||||
global.params.isSolaris = 1;
|
||||
else version(OpenBSD)
|
||||
global.params.isOpenBSD = 1;
|
||||
else
|
||||
static assert(0, "OS not supported yet.");
|
||||
|
||||
Type._init();
|
||||
Id.initialize();
|
||||
Module._init();
|
||||
Target._init();
|
||||
Expression._init();
|
||||
Objc._init();
|
||||
builtin_init();
|
||||
}
|
||||
|
162
test/dub_package/frontend.d
Executable file
162
test/dub_package/frontend.d
Executable file
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env dub
|
||||
/+dub.sdl:
|
||||
dependency "dmd" path="../.."
|
||||
+/
|
||||
import std.stdio;
|
||||
|
||||
// add import paths
|
||||
void addImports(T)(T path)
|
||||
{
|
||||
import dmd.globals : global;
|
||||
import dmd.arraytypes : Strings;
|
||||
|
||||
stderr.writefln("addImport: %s", path);
|
||||
|
||||
Strings* res = new Strings();
|
||||
foreach (p; path)
|
||||
{
|
||||
import std.string : toStringz;
|
||||
Strings* a = new Strings();
|
||||
a.push(p.toStringz);
|
||||
res.append(a);
|
||||
}
|
||||
global.path = res;
|
||||
}
|
||||
|
||||
// finds a dmd.conf and parses it for import paths
|
||||
auto findImportPaths()
|
||||
{
|
||||
import std.file : exists, getcwd;
|
||||
import std.string : fromStringz, toStringz;
|
||||
import std.path : buildPath, buildNormalizedPath, dirName;
|
||||
import std.process : env = environment, execute;
|
||||
import dmd.dinifile : findConfFile;
|
||||
import dmd.errors : fatal;
|
||||
import std.algorithm, std.range, std.regex;
|
||||
|
||||
auto dmdEnv = env.get("DMD", "dmd");
|
||||
auto whichDMD = execute(["which", dmdEnv]);
|
||||
if (whichDMD.status != 0)
|
||||
{
|
||||
stderr.writeln("Can't find DMD.");
|
||||
fatal;
|
||||
}
|
||||
|
||||
immutable dmdFilePath = whichDMD.output;
|
||||
string iniFile;
|
||||
|
||||
if (dmdEnv.canFind("ldmd"))
|
||||
{
|
||||
immutable ldcConfig = "ldc2.conf";
|
||||
immutable binDir = dmdFilePath.dirName;
|
||||
// https://wiki.dlang.org/Using_LDC
|
||||
auto ldcConfigs = [
|
||||
getcwd.buildPath(ldcConfig),
|
||||
binDir.buildPath(ldcConfig),
|
||||
binDir.dirName.buildPath("etc", ldcConfig),
|
||||
"~/.ldc".buildPath(ldcConfig),
|
||||
binDir.buildPath("etc", ldcConfig),
|
||||
binDir.buildPath("etc", "ldc", ldcConfig),
|
||||
"/etc".buildPath(ldcConfig),
|
||||
"/etc/ldc".buildPath(ldcConfig),
|
||||
].filter!exists;
|
||||
assert(!ldcConfigs.empty, "No ldc2.conf found");
|
||||
iniFile = ldcConfigs.front;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto f = findConfFile(dmdFilePath.toStringz, "dmd.conf");
|
||||
iniFile = f.fromStringz.idup;
|
||||
assert(iniFile.exists, "No dmd.conf found.");
|
||||
}
|
||||
|
||||
return File(iniFile, "r")
|
||||
.byLineCopy
|
||||
.map!(l => l.matchAll(`-I[^ "]+`.regex)
|
||||
.joiner
|
||||
.map!(a => a.drop(2)
|
||||
.replace("%@P%", dmdFilePath.dirName)
|
||||
.replace("%%ldcbinarypath%%", dmdFilePath.dirName)))
|
||||
.joiner
|
||||
.array
|
||||
.sort
|
||||
.uniq
|
||||
.map!buildNormalizedPath;
|
||||
}
|
||||
|
||||
// test frontend
|
||||
void main()
|
||||
{
|
||||
import dmd.astcodegen : ASTCodegen;
|
||||
import dmd.dmodule : Module;
|
||||
import dmd.globals : global, Loc;
|
||||
import dmd.frontend : initDMD;
|
||||
import dmd.parse : Parser;
|
||||
import dmd.statement : Identifier;
|
||||
import dmd.tokens : TOKeof;
|
||||
import dmd.id : Id;
|
||||
|
||||
initDMD;
|
||||
findImportPaths.addImports;
|
||||
|
||||
auto parse(Module m, string code)
|
||||
{
|
||||
scope p = new Parser!ASTCodegen(m, code, false);
|
||||
p.nextToken; // skip the initial token
|
||||
auto members = p.parseModule;
|
||||
assert(!p.errors, "Parsing error occurred.");
|
||||
return members;
|
||||
}
|
||||
|
||||
Identifier id = Identifier.idPool("test");
|
||||
auto m = new Module("test.d", id, 0, 0);
|
||||
m.members = parse(m, q{
|
||||
void foo()
|
||||
{
|
||||
foreach (i; 0..10) {}
|
||||
}
|
||||
});
|
||||
|
||||
void semantic()
|
||||
{
|
||||
import dmd.dsymbolsem : dsymbolSemantic;
|
||||
import dmd.semantic : semantic2, semantic3;
|
||||
|
||||
m.importedFrom = m;
|
||||
m.importAll(null);
|
||||
m.dsymbolSemantic(null);
|
||||
m.semantic2(null);
|
||||
m.semantic3(null);
|
||||
}
|
||||
semantic();
|
||||
|
||||
auto prettyPrint()
|
||||
{
|
||||
import dmd.root.outbuffer: OutBuffer;
|
||||
import dmd.hdrgen : HdrGenState, PrettyPrintVisitor;
|
||||
|
||||
OutBuffer buf = { doindent: 1 };
|
||||
HdrGenState hgs = { fullDump: 1 };
|
||||
scope PrettyPrintVisitor ppv = new PrettyPrintVisitor(&buf, &hgs);
|
||||
m.accept(ppv);
|
||||
return buf;
|
||||
}
|
||||
auto buf = prettyPrint();
|
||||
|
||||
auto expected =q{import object;
|
||||
void foo()
|
||||
{
|
||||
{
|
||||
int __key3 = 0;
|
||||
int __limit4 = 10;
|
||||
for (; __key3 < __limit4; __key3 += 1)
|
||||
{
|
||||
int i = __key3;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
import std.string : replace, fromStringz;
|
||||
auto generated = buf.extractData.fromStringz.replace("\t", " ");
|
||||
assert(expected == generated, generated);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue