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