Hello,
The problematic line is at the very bottom.
I only managed to make it run by precedding the .byChar with .text, but that is unwanted because it would convert the whole InputRange.
How can I do this dchar->char conversion on only the required number of chars? (The kwSearch function will pop only a few chars, it doesn't whant a whole RandomAccessRange)
import std;
struct KeywordSearchTree
{
char ch/+root is always 0xff, it is there to hold subNodes.+/;
int code;
KeywordSearchTree[] subNodes;
void addSubNode(string s, int scode)
{
if(s.length==0) return;
auto idx = subNodes.map!"a.ch".countUntil(s[0]);
if(idx<0) { idx = subNodes.length; subNodes ~= KeywordSearchTree(s[0]); }
if(s.length==1) subNodes[idx].code = scode;
else subNodes[idx].addSubNode(s[1..$], scode);
}
static KeywordSearchTree build(string[] keywords)
{
KeywordSearchTree root;
foreach(i, act; keywords)
root.addSubNode(act, (cast(int)(i+1)));
return root;
}
}
int kwSearch(KeywordSearchTree tree, R)(R s)
if(isInputRange!(R, immutable char))
{
//pragma(msg, __FUNCTION__);
if(s.empty) return 0;
switch(s.front)
{
static foreach(sn; tree.subNodes)
{
case sn.ch: {
s.popFront;
if(!s.empty) if(const res = kwSearch!sn(s)) return res;
return sn.code;
}
}
default: return 0;
}
}
int kwSearch(string[] keywords, R)(R s)
if(isInputRange!(R, immutable char))
{
enum tree = KeywordSearchTree.build(keywords);
return kwSearch!tree(s);
}
string[] keywords;
void main()
{
enum ctKeywords = [
"!", //Link: shebang https://dlang.org/spec/lex.html#source_text
"version", "extension", "line", //Link: GLSL directives
"pragma", "warning", "error", "assert", //Link: Opencl directives
"include", "define", "undef", "ifdef", "ifndef", "if", "else", "elif", "endif", //Link: Arduino directives
];
keywords = ctKeywords;
foreach(kw; keywords)
{ (kw.dtext~" garbage"d).byChar.kwSearch!ctKeywords.writeln; }
}