1 module dpp.translation.tokens; 2 3 4 import dpp.from; 5 6 7 string translateTokens(in from!"clang".Token[] tokens) @safe pure { 8 import dpp.translation.type: translateString; 9 import clang: Token; 10 import std.algorithm: map, filter, canFind, endsWith; 11 import std.array: array, join, replace; 12 13 const translatedPropertyTokens = tokens 14 .translateProperty("sizeof") 15 .translateProperty("alignof") 16 ; 17 18 // we can't rely on `translateString` for angle brackets here since it 19 // checks if there are matching pairs in the string to translate. 20 // Since we have an array of tokens, the matching pair might be in a different position 21 22 const canFindOpeningAngle = translatedPropertyTokens 23 .canFind!(t => t.kind == Token.Kind.Punctuation && t.spelling == "<"); 24 const canFindClosingAngle = translatedPropertyTokens 25 .canFind!(t => t.kind == Token.Kind.Punctuation && (t.spelling == ">" || t.spelling == ">>")); 26 27 const translatedAngleBracketTokens = canFindOpeningAngle && canFindClosingAngle 28 ? translatedPropertyTokens 29 .map!(t => Token(t.kind, t.spelling.replace("<", "!(").replace(">>", "))").replace(">", ")"))) 30 .array 31 : translatedPropertyTokens; 32 33 auto ret = translatedAngleBracketTokens 34 .filter!(t => t.kind != Token.Kind.Keyword || t.spelling != "typename") 35 .map!(t => t.spelling.translateString) 36 .join; 37 38 // this can happen because of ending with ">>" 39 if(ret.endsWith("))")) ret = ret[0 .. $-1]; 40 41 return ret; 42 } 43 44 45 // sizeof(foo) -> foo.sizeof, alignof(foo) -> foo.alignof 46 private auto translateProperty(const(from!"clang".Token)[] tokens, in string property) @safe pure { 47 import dpp.translation.type: translateString; 48 import clang: Token; 49 import std.algorithm: countUntil, map; 50 import std.array: join, replace; 51 52 for(;;) { 53 const indexProperty = tokens.countUntil!(a => a.kind == Token.Kind.Keyword && a.spelling == property); 54 if(indexProperty == -1) return tokens; 55 const indexCloseParen = indexProperty + tokens[indexProperty..$].countUntil!(a => a.kind == Token.Kind.Punctuation && a.spelling == ")"); 56 const newTokenSpelling = 57 "(" ~ tokens[indexProperty + 2 .. indexCloseParen] 58 .map!(a => a.spelling) 59 .join(" ") 60 ~ ")." ~ property 61 ; 62 63 tokens = 64 tokens[0 .. indexProperty] ~ 65 Token(Token.Kind.Literal, newTokenSpelling.translateString) ~ 66 tokens[indexCloseParen + 1 .. $]; 67 } 68 }