From eb05f0547f16cca18536e48ae11bf41725aa43a1 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Tue, 15 Sep 2015 03:33:16 +0200 Subject: [PATCH] module name for #39 --- cedast/build/cedast.coedit | 1 + cedast/src/ast.d | 76 +++++++++++++++++++++++++++++++++++++- cedast/src/cedast.d | 11 ++++-- lazproj/cedast_loader.pas | 22 ++++++++--- 4 files changed, 99 insertions(+), 11 deletions(-) diff --git a/cedast/build/cedast.coedit b/cedast/build/cedast.coedit index 73ff8323..5c678244 100644 --- a/cedast/build/cedast.coedit +++ b/cedast/build/cedast.coedit @@ -14,5 +14,6 @@ object CurrentProject: TCENativeProject ConfigurationIndex = 0 LibraryAliases.Strings = ( 'libdparse' + 'iz' ) end diff --git a/cedast/src/ast.d b/cedast/src/ast.d index ca6f6885..b4814feb 100644 --- a/cedast/src/ast.d +++ b/cedast/src/ast.d @@ -1,21 +1,93 @@ module ast; -import std.d.lexer, std.d.parser, common; +import std.d.lexer, std.d.parser, std.d.ast; +import common; +import iz.enumset; + +private +{ + enum AstInfos {moduleName, symbolList, todoList, WarnAndErr} + alias CachedInfos = EnumSet!(AstInfos, Set8); +} + struct Ast { + +private: + + ubyte[] src; + string fname; + LexerConfig config; + StringCache strcache; + Module mod; + CachedInfos cachedInfos; + bool scanned; + string modName; + + final static void parserError(string fname, size_t line, size_t col, string msg, bool isErr) + { + } + + final void resetCachedInfo() + { + cachedInfos = 0; + modName = ""; + } + + final void scan() + { + resetCachedInfo; + scanned = false; + scope(success) scanned = true; + + config = LexerConfig(fname, StringBehavior.source, WhitespaceBehavior.skip); + mod = parseModule(getTokensForParser(src, config, &strcache), fname, null, &parserError); + } + +public: + this(string filename) { mixin(logcall); + + import std.file; + fname = filename; + src = cast(ubyte[]) read(fname, size_t.max); + strcache = StringCache(StringCache.defaultBucketCount); + scan; } this(ubyte[] buffer) { mixin(logcall); + src = buffer.dup; + strcache = StringCache(StringCache.defaultBucketCount); + scan; } - void rescan() + final void rescan() { mixin(logcall); + resetCachedInfo; + } + + final string moduleName() + { + string result; + + if (!scanned) + return result; + if (AstInfos.moduleName in cachedInfos) + return modName; + + cachedInfos += AstInfos.moduleName; + if (mod.moduleDeclaration) + foreach(Token t; mod.moduleDeclaration.moduleName.identifiers) + result ~= t.text ~ "."; + + if (result.length) + modName = result[0 .. $-1]; + return modName; } } diff --git a/cedast/src/cedast.d b/cedast/src/cedast.d index f6ebaafb..8ebba4dc 100644 --- a/cedast/src/cedast.d +++ b/cedast/src/cedast.d @@ -84,10 +84,15 @@ void unleash(AstToken tok) } extern(C) export -char* moduleName(AstToken tok) +immutable(char*) moduleName(AstToken tok) { - char* result = null; - return result; + if (tok < 1 || tok > modules.length) + return null; + Ast* mod = modules[tok - 1]; + if (mod == null) + return null; + import std.string: toStringz; + return toStringz(mod.moduleName); } extern(C) export diff --git a/lazproj/cedast_loader.pas b/lazproj/cedast_loader.pas index 9dc308d0..cab26af7 100644 --- a/lazproj/cedast_loader.pas +++ b/lazproj/cedast_loader.pas @@ -10,6 +10,7 @@ type TScanBuffer = function (buffer: PByte; len: NativeUint): TAstToken; cdecl; TRescan = procedure (tok: TAstToken); cdecl; TUnleash = procedure (tok: TAstToken); cdecl; + TModuleName = function (tok: TAstToken): PChar; cdecl; var dast: TLibHandle; @@ -17,30 +18,39 @@ var scanbuffer: TScanBuffer; rescan: TRescan; unleash: TUnleash; + moduleName: TModuleName; tok: TAstToken; +const + testModule = 'module a.b.c.d.e.f.g.h; import std.stdio;'; + begin - dast := LoadLibrary('cedast.dll'); + dast := LoadLibrary('cedast'); if dast = NilHandle then writeln('dast invalid handle') else begin scanfile := TScanFile(GetProcAddress(dast, 'scanFile')); if scanFile = nil then writeln('invalid scanfile proc ptr') - else tok := scanfile(PChar('blah')); - - scanbuffer := TScanBuffer(GetProcAddress(dast, 'scanBuffer')); - if scanbuffer = nil then writeln('invalid scanBuffer proc ptr') - else scanbuffer(nil, 0); + else tok := scanfile(PChar('exception in call so ticket value is 0')); rescan := TRescan(GetProcAddress(dast, 'rescan')); if rescan = nil then writeln('invalid rescan proc ptr') else rescan(tok); + scanbuffer := TScanBuffer(GetProcAddress(dast, 'scanBuffer')); + if scanbuffer = nil then writeln('invalid scanBuffer proc ptr') + else tok := scanbuffer(@testModule[1], length(testModule)); + + moduleName := TModuleName(GetProcAddress(dast, 'moduleName')); + if moduleName = nil then writeln('invalid moduleName proc ptr') + else if tok <> 0 then writeln(moduleName(tok)); + unleash := TUnleash(GetProcAddress(dast, 'unleash')); if unleash = nil then writeln('invalid unleash proc ptr') else unleash(tok); + end; readln;