diff --git a/src/main.cpp b/src/main.cpp index 74d631878..13df48038 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -522,8 +522,12 @@ int main(int argc, char** argv) { } else { logV("locale: %s",localeRet); } - if ((localeRet=TA_BINDTEXTDOMAIN("furnace","../po/locale"))==NULL) { - logE("could not bind text domain!"); + if ((localeRet=TA_BINDTEXTDOMAIN("furnace","locale"))==NULL) { + if ((localeRet=TA_BINDTEXTDOMAIN("furnace","../po/locale"))==NULL) { + logE("could not bind text domain!"); + } else { + logV("text domain 1: %s",localeRet); + } } else { logV("text domain 1: %s",localeRet); } diff --git a/src/momo/momo.c b/src/momo/momo.c index d462069d7..44685cef7 100644 --- a/src/momo/momo.c +++ b/src/momo/momo.c @@ -36,6 +36,32 @@ static char curLocale[64]; static char tempPath[4096]; +enum StackInstruction { + MOMO_STACK_EXIT=0, + MOMO_STACK_PUSH, + MOMO_STACK_PUSH_N, + MOMO_STACK_ADD, + MOMO_STACK_SUB, + MOMO_STACK_MUL, + MOMO_STACK_DIV, + MOMO_STACK_MOD, + MOMO_STACK_CMP_EQ, + MOMO_STACK_CMP_NE, + MOMO_STACK_CMP_GT, + MOMO_STACK_CMP_LT, + MOMO_STACK_CMP_GE, + MOMO_STACK_CMP_LE, + MOMO_STACK_CMP_AND, + MOMO_STACK_CMP_OR, + MOMO_STACK_TRUE, + MOMO_STACK_FALSE +}; + +struct StackData { + unsigned char ins; + unsigned char param; +}; + struct LocaleDomain { char path[4096]; char name[64]; @@ -45,6 +71,7 @@ struct LocaleDomain { const char** transPtr; size_t stringCount; size_t firstString[256]; + struct StackData pluralProgram[256]; }; struct MOHeader { @@ -63,6 +90,124 @@ static size_t domainsLen=0; // utility +unsigned int runStackMachine(struct StackData* data, size_t count, unsigned int n) { + size_t pc=0; + unsigned int stack[256]; + unsigned char sp=0xff; + + memset(stack,0,256*sizeof(unsigned int)); + + while (pcop2)?1:0; + break; + case MOMO_STACK_CMP_LT: + op2=stack[sp--]; + op1=stack[sp--]; + stack[++sp]=(op1=op2)?1:0; + break; + case MOMO_STACK_CMP_LE: + op2=stack[sp--]; + op1=stack[sp--]; + stack[++sp]=(op1<=op2)?1:0; + break; + case MOMO_STACK_CMP_AND: + op2=stack[sp--]; + op1=stack[sp--]; + stack[++sp]=(op1 && op2)?1:0; + break; + case MOMO_STACK_CMP_OR: + op2=stack[sp--]; + op1=stack[sp--]; + stack[++sp]=(op1 || op2)?1:0; + break; + case MOMO_STACK_TRUE: + op1=stack[sp--]; + if (op1) return param; + break; + case MOMO_STACK_FALSE: + op1=stack[sp--]; + if (!op1) return param; + break; + default: + return 0; + } + pc++; + } + + return stack[sp]; +} + +unsigned char compileExprSub(const char** ptr, struct StackData* data, size_t* pc, size_t count) { + +} + +unsigned char compileExpr(const char* expr, struct StackData* data, size_t count) { + plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); + + const char* ptr=expr; + size_t pc=0; + + return compileExprSub(&ptr,data,&pc,count); +} + unsigned char domainsInsert(struct LocaleDomain* item) { struct LocaleDomain** newDomains=malloc(sizeof(struct LocaleDomain*)*(domainsLen+1)); if (newDomains==NULL) return 0; @@ -376,7 +521,6 @@ const char* momo_gettext(const char* str) { return str; } if (str==NULL) return NULL; - if ((*str)==0) return str; // TODO: optimize for (size_t i=curDomain->firstString[(unsigned char)(str[0])]; istringCount; i++) { if (strcmp(curDomain->stringPtr[i],str)==0) { diff --git a/src/momo/stack.md b/src/momo/stack.md new file mode 100644 index 000000000..90c4b541c --- /dev/null +++ b/src/momo/stack.md @@ -0,0 +1,26 @@ +the following document describes the stack machine used to get the correct plural form in ngettext. + +# instructions + +``` +op | description +---|-------------------- +00 | exit +01 | push imm +02 | push N +03 | add +04 | sub +05 | mul +06 | div +07 | mod +08 | cmp eq +09 | cmp ne +0a | cmp gt +0b | cmp lt +0c | cmp ge +0d | cmp le +0e | cmp and +0f | cmp or +10 | true imm +11 | false imm +```