// Hyperbolic Rogue language file generator // Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details #include #include #include #include #include #include #define GEN_M 0 #define GEN_F 1 #define GEN_N 2 #define GEN_O 3 #if MAC #define IF_MAC(y,z) y #else #define IF_MAC(y,z) z #endif template int isize(const T& x) { return x.size(); } #define NUMLAN 7 // language generator const char *escape(std::string s, const std::string& dft); template struct dictionary { std::map m; void add(const std::string& s, T val) { if(m.count(s)) add(s + " [repeat]", std::move(val)); else m[s] = std::move(val); } T& operator [] (const std::string& s) { return m[s]; } int count(const std::string& s) const { return m.count(s); } }; dictionary d[NUMLAN]; struct noun2 { int genus; const char *nom; const char *nomp; const char *acc; const char *abl; }; struct noun { int genus; std::string nom, nomp, acc, abl; noun() = default; noun(const noun2& n) : genus(n.genus), nom(n.nom), nomp(n.nomp), acc(n.acc), abl(n.abl) {} }; dictionary nouns[NUMLAN]; int utfsize(char c) { unsigned char cu = c; if(cu < 128) return 1; if(cu < 224) return 2; if(cu < 0xE0) return 3; return 4; } void addutftoset(std::set& s, std::string& w) { size_t i = 0; while(i < w.size()) { int siz = utfsize(w[i]); s.insert(w.substr(i, siz)); i += siz; } } void addutftoset(std::set& s, noun& w) { addutftoset(s, w.nom); addutftoset(s, w.nomp); addutftoset(s, w.acc); addutftoset(s, w.abl); } template void addutftoset(std::set& s, dictionary& w) { for(auto&& elt : w.m) addutftoset(s, elt.second); } std::set allchars; typedef unsigned hashcode; hashcode hashval; bool isrepeat(const std::string& s) { return s.find(" [repeat]") != std::string::npos; } hashcode langhash(const std::string& s) { if(isrepeat(s)) { return langhash(s.substr(0, s.size() - 9)) + 1; } hashcode r = 0; for(int i=0; i buildHashTable(std::set& s) { std::map res; for(auto&& elt : s) res[langhash(elt)] = elt; return res; } const char *escape(std::string s, const std::string& dft) { if(s == "") { printf("/*MISSING*/ "); s = dft; } static std::string t; t = "\""; for(int i=0; i nothe; std::set plural; void langPL() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e,f) #include "language-pl.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e,f) { a, noun2{ b, c, d, e, f } }, #include "language-pl.cpp" #undef N #undef S }; for(auto&& elt : ds) d[1].add(elt.first, elt.second); for(auto&& elt : ns) nouns[1].add(elt.first, elt.second); } void langTR() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e,f) #include "language-tr.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e,f) { a, noun2{ b, c, d, e, f } }, #include "language-tr.cpp" #undef N #undef S }; for(auto&& elt : ds) d[2].add(elt.first, elt.second); for(auto&& elt : ns) nouns[2].add(elt.first, elt.second); } void langCZ() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e,f) #include "language-cz.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e,f) { a, noun2{ b, c, d, e, f } }, #include "language-cz.cpp" #undef N #undef S }; for(auto&& elt : ds) d[3].add(elt.first, elt.second); for(auto&& elt : ns) nouns[3].add(elt.first, elt.second); } void langRU() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e,f) #include "language-ru.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e,f) { a, noun2{ b, c, d, e, f } }, #include "language-ru.cpp" #undef N #undef S }; for(auto&& elt : ds) d[4].add(elt.first, elt.second); for(auto&& elt : ns) nouns[4].add(elt.first, elt.second); } void langDE() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e) #include "language-de.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e) { a, noun2{ b, c, d, e, e } }, #include "language-de.cpp" #undef N #undef S }; for(auto&& elt : ds) d[5].add(elt.first, elt.second); for(auto&& elt : ns) nouns[5].add(elt.first, elt.second); } void langPT() { static std::pair ds[] = { #define S(a,b) { a, b }, #define N(a,b,c,d,e) #include "language-ptbr.cpp" #undef N #undef S }; static std::pair ns[] = { #define S(a,b) #define N(a,b,c,d,e) { a, noun2{ b, c, d, "", e } }, #include "language-ptbr.cpp" #undef N #undef S }; for(auto&& elt : ds) d[6].add(elt.first, elt.second); for(auto&& elt : ns) nouns[6].add(elt.first, elt.second); } int completeness[NUMLAN]; template void compute_completeness(const T& dict) { std::set s; for(int i=1; i vchars; for(auto&& elt : allchars) { if(isize(elt) >= 2) { javastring += elt; vchars.push_back(elt); } } printf("\n"); printf("#if HDR\n"); printf("#define NUMEXTRA %d\n", isize(vchars)); printf("#define NATCHARS {"); for(auto&& elt : vchars) printf("\"%s\",", elt.c_str()); printf("};\n"); printf("extern char* natchars[NUMEXTRA];\n"); printf("#endif\n"); printf("char* natchars[NUMEXTRA] = NATCHARS;\n"); printf("//javastring = \"%s\";\n", javastring.c_str()); printf("\nEX int transcompleteness[NUMLAN] = {"); for(int i=0; i allsent; for(auto&& elt : d[1].m) allsent.insert(elt.first); std::set allnouns; for(auto&& elt : nouns[1].m) allnouns.insert(elt.first); std::map ms, mn; do { hashval = rand(); printf("// check hash: %x\n", hashval); ms = buildHashTable(allsent); mn = buildHashTable(allnouns); } while(ms.size() != allsent.size() || mn.size() != allnouns.size()); printf("hashcode hashval = 0x%x;\n\n", hashval); printf("sentence all_sentences[] = {\n"); for(auto&& elt : ms) { const std::string& s = elt.second; if(isrepeat(s)) printf("#if REPEATED\n"); printf(" {0x%x, { // %s\n", elt.first, escape(s, s)); for(int i=1; i