01 CTask *trie_task=Fs;
02 class CTrie {
03   U8 *str;
04   U8 *front_declension;//Optionalaly used 
05   U8 *back_declension;//Optionalaly used 
06   U8 *translation;
07   I64 flags;
08   CTrie *branches[26];
09   CTrie *next;
10 };
11 CTrie root;
12 MemSet(&root,0,sizeof(CTrie));
13 CTrie *TrieGet(U8 *name,CTrie *of=&root) {
14 ent:
15   if(!of) return NULL;
16   if(!*name) {
17     while(!of->str) {
18       of=of->next;
19       if(!of) return NULL;
20     }
21     return of;
22   }
23   if('A'<=ToUpper(*name)<='Z') {
24     of=of->branches[ToUpper(*name)-'A'];
25     name++;
26     goto ent;
27   }
28   return NULL;
29 }
30 CTrie *TrieExists(U8 *name,I64 flags) {
31   CTrie *t=TrieGet(name),*ret=t;
32   while(t) {
33     if(t->flags==flags)
34       return t;
35     t=t->next;
36   }
37   return NULL;
38 }
39 CTrie *TrieAdd(U8 *name,I64 flags=0,U8 *translation=NULL) {
40   I64 idx;
41   CTrie *new=CAlloc(sizeof(CTrie),trie_task),*to=&root,**ins_at=&to->next,*new2;
42   if(translation) new->translation=StrNew(translation,trie_task);
43   new->str=StrNew(name,trie_task);
44   new->flags=flags;
45   while(*name) {
46     if('A'<=(idx=ToUpper(*name))<='Z') {
47       idx-='A';
48       if(to->branches[idx]) {
49         to=to->branches[idx];
50       } else {
51         new2=CAlloc(sizeof(CTrie),trie_task);
52         to->branches[idx]=new2;
53         to=new2;
54       }
55       ins_at=&to->next;
56       name++;
57     } else if(*name)
58       throw('InvChr');
59   }
60   while(ins_at[0])
61     ins_at=&ins_at[0]->next;
62   *ins_at=new;
63   return new;
64 };