diff options
| author | neksard <[email protected]> | 2022-02-10 16:45:33 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:45:33 +0300 |
| commit | 1d9c550e7c38e051d7961f576013a482003a70d9 (patch) | |
| tree | b2cc84ee7850122e7ccf51d0ea21e4fa7e7a5685 /contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp | |
| parent | 8f7cf138264e0caa318144bf8a2c950e0b0a8593 (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp')
| -rw-r--r-- | contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp | 820 |
1 files changed, 410 insertions, 410 deletions
diff --git a/contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp b/contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp index d5bfe31c08c..ab4bb0d8e47 100644 --- a/contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp +++ b/contrib/restricted/boost/libs/locale/src/shared/mo_lambda.cpp @@ -1,411 +1,411 @@ -// -// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -#include "mo_lambda.hpp" -#include <string.h> -#include <stdlib.h> - -namespace boost { -namespace locale { -namespace gnu_gettext { -namespace lambda { - -namespace { // anon - struct identity : public plural { - virtual int operator()(int n) const - { - return n; - }; - virtual identity *clone() const - { - return new identity(); - } - }; - - struct unary : public plural - { - unary(plural_ptr ptr) : - op1(ptr) - { - } - protected: - plural_ptr op1; - }; - - - struct binary : public plural - { - binary(plural_ptr p1,plural_ptr p2) : - op1(p1), - op2(p2) - { - } - protected: - plural_ptr op1,op2; - }; - - struct number : public plural - { - number(int v) : - val(v) - { - } - virtual int operator()(int /*n*/) const - { - return val; - } - virtual number *clone() const - { - return new number(val); - } - - private: - int val; - }; - - #define UNOP(name,oper) \ - struct name: public unary { \ - name(plural_ptr op) : unary(op) \ - { \ - }; \ - virtual int operator()(int n) const \ - { \ - return oper (*op1)(n); \ - } \ - virtual name *clone() const \ - { \ - plural_ptr op1_copy(op1->clone()); \ - return new name(op1_copy); \ - } \ - }; - - #define BINOP(name,oper) \ - struct name : public binary \ - { \ - name(plural_ptr p1,plural_ptr p2) : \ - binary(p1,p2) \ - { \ - } \ - \ - virtual int operator()(int n) const \ - { \ - return (*op1)(n) oper (*op2)(n); \ - } \ - virtual name *clone() const \ - { \ - plural_ptr op1_copy(op1->clone()); \ - plural_ptr op2_copy(op2->clone()); \ - return new name(op1_copy,op2_copy); \ - } \ - }; - - #define BINOPD(name,oper) \ - struct name : public binary { \ - name(plural_ptr p1,plural_ptr p2) : \ - binary(p1,p2) \ - { \ - } \ - virtual int operator()(int n) const \ - { \ - int v1=(*op1)(n); \ - int v2=(*op2)(n); \ - return v2==0 ? 0 : v1 oper v2; \ - } \ - virtual name *clone() const \ - { \ - plural_ptr op1_copy(op1->clone()); \ - plural_ptr op2_copy(op2->clone()); \ - return new name(op1_copy,op2_copy); \ - } \ - }; - - enum { END = 0 , SHL = 256, SHR, GTE,LTE, EQ, NEQ, AND, OR, NUM, VARIABLE }; - - UNOP(l_not,!) - UNOP(minus,-) - UNOP(bin_not,~) - - BINOP(mul,*) - BINOPD(div,/) - BINOPD(mod,%) - static int level10[]={3,'*','/','%'}; - - BINOP(add,+) - BINOP(sub,-) - static int level9[]={2,'+','-'}; - - BINOP(shl,<<) - BINOP(shr,>>) - static int level8[]={2,SHL,SHR}; - - BINOP(gt,>) - BINOP(lt,<) - BINOP(gte,>=) - BINOP(lte,<=) - static int level7[]={4,'<','>',GTE,LTE}; - - BINOP(eq,==) - BINOP(neq,!=) - static int level6[]={2,EQ,NEQ}; - - BINOP(bin_and,&) - static int level5[]={1,'&'}; - - BINOP(bin_xor,^) - static int level4[]={1,'^'}; - - BINOP(bin_or,|) - static int level3[]={1,'|'}; - - BINOP(l_and,&&) - static int level2[]={1,AND}; - - BINOP(l_or,||) - static int level1[]={1,OR}; - - struct conditional : public plural { - conditional(plural_ptr p1,plural_ptr p2,plural_ptr p3) : - op1(p1), - op2(p2), - op3(p3) - { - } +// +// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#include "mo_lambda.hpp" +#include <string.h> +#include <stdlib.h> + +namespace boost { +namespace locale { +namespace gnu_gettext { +namespace lambda { + +namespace { // anon + struct identity : public plural { virtual int operator()(int n) const - { - return (*op1)(n) ? (*op2)(n) : (*op3)(n); - } - virtual conditional *clone() const - { - plural_ptr op1_copy(op1->clone()); - plural_ptr op2_copy(op2->clone()); - plural_ptr op3_copy(op3->clone()); - return new conditional(op1_copy,op2_copy,op3_copy); - } - private: - plural_ptr op1,op2,op3; - }; - - - plural_ptr bin_factory(int value,plural_ptr left,plural_ptr right) - { - - switch(value) { - case '/': return plural_ptr(new div(left,right)); - case '*': return plural_ptr(new mul(left,right)); - case '%': return plural_ptr(new mod(left,right)); - case '+': return plural_ptr(new add(left,right)); - case '-': return plural_ptr(new sub(left,right)); - case SHL: return plural_ptr(new shl(left,right)); - case SHR: return plural_ptr(new shr(left,right)); - case '>': return plural_ptr(new gt(left,right)); - case '<': return plural_ptr(new lt(left,right)); - case GTE: return plural_ptr(new gte(left,right)); - case LTE: return plural_ptr(new lte(left,right)); - case EQ: return plural_ptr(new eq(left,right)); - case NEQ: return plural_ptr(new neq(left,right)); - case '&': return plural_ptr(new bin_and(left,right)); - case '^': return plural_ptr(new bin_xor(left,right)); - case '|': return plural_ptr(new bin_or (left,right)); - case AND: return plural_ptr(new l_and(left,right)); - case OR: return plural_ptr(new l_or(left,right)); - default: - return plural_ptr(); - } - } - - static inline bool is_in(int v,int *p) - { - int len=*p; - p++; - while(len && *p!=v) { p++;len--; } - return len!=0; - } - - - class tokenizer { - public: - tokenizer(char const *s) { text=s; pos=0; step(); }; - int get(int *val=NULL){ - int iv=int_value; - int res=next_tocken; - step(); - if(val && res==NUM){ - *val=iv; - } - return res; - }; - int next(int *val=NULL) { - if(val && next_tocken==NUM) { - *val=int_value; - return NUM; - } - return next_tocken; - } - private: - char const *text; - int pos; - int next_tocken; - int int_value; - bool is_blank(char c) - { - return c==' ' || c=='\r' || c=='\n' || c=='\t'; - } - bool isdigit(char c) - { - return '0'<=c && c<='9'; - } - void step() - { - while(text[pos] && is_blank(text[pos])) pos++; - char const *ptr=text+pos; - char *tmp_ptr; - if(strncmp(ptr,"<<",2)==0) { pos+=2; next_tocken=SHL; } - else if(strncmp(ptr,">>",2)==0) { pos+=2; next_tocken=SHR; } - else if(strncmp(ptr,"&&",2)==0) { pos+=2; next_tocken=AND; } - else if(strncmp(ptr,"||",2)==0) { pos+=2; next_tocken=OR; } - else if(strncmp(ptr,"<=",2)==0) { pos+=2; next_tocken=LTE; } - else if(strncmp(ptr,">=",2)==0) { pos+=2; next_tocken=GTE; } - else if(strncmp(ptr,"==",2)==0) { pos+=2; next_tocken=EQ; } - else if(strncmp(ptr,"!=",2)==0) { pos+=2; next_tocken=NEQ; } - else if(*ptr=='n') { pos++; next_tocken=VARIABLE; } - else if(isdigit(*ptr)) { int_value=strtol(text+pos,&tmp_ptr,0); pos=tmp_ptr-text; next_tocken=NUM; } - else if(*ptr=='\0') { next_tocken=0; } - else { next_tocken=*ptr; pos++; } - } - }; - - - #define BINARY_EXPR(expr,hexpr,list) \ - plural_ptr expr() \ - { \ - plural_ptr op1,op2; \ - if((op1=hexpr()).get()==0) \ - return plural_ptr(); \ - while(is_in(t.next(),list)) { \ - int o=t.get(); \ - if((op2=hexpr()).get()==0) \ - return plural_ptr(); \ - op1=bin_factory(o,op1,op2); \ - } \ - return op1; \ - } - - class parser { - public: - - parser(tokenizer &tin) : t(tin) {}; - - plural_ptr compile() - { - plural_ptr res=cond_expr(); - if(res.get() && t.next()!=END) { - return plural_ptr(); - }; - return res; - } - - private: - - plural_ptr value_expr() - { - plural_ptr op; - if(t.next()=='(') { - t.get(); - if((op=cond_expr()).get()==0) - return plural_ptr(); - if(t.get()!=')') - return plural_ptr(); - return op; - } - else if(t.next()==NUM) { - int value; - t.get(&value); - return plural_ptr(new number(value)); - } - else if(t.next()==VARIABLE) { - t.get(); - return plural_ptr(new identity()); - } - return plural_ptr(); - }; - - plural_ptr un_expr() - { - plural_ptr op1; - static int level_unary[]={3,'-','!','~'}; - if(is_in(t.next(),level_unary)) { - int op=t.get(); - if((op1=un_expr()).get()==0) - return plural_ptr(); - switch(op) { - case '-': - return plural_ptr(new minus(op1)); - case '!': - return plural_ptr(new l_not(op1)); - case '~': - return plural_ptr(new bin_not(op1)); - default: - return plural_ptr(); - } - } - else { - return value_expr(); - } - }; - - BINARY_EXPR(l10,un_expr,level10); - BINARY_EXPR(l9,l10,level9); - BINARY_EXPR(l8,l9,level8); - BINARY_EXPR(l7,l8,level7); - BINARY_EXPR(l6,l7,level6); - BINARY_EXPR(l5,l6,level5); - BINARY_EXPR(l4,l5,level4); - BINARY_EXPR(l3,l4,level3); - BINARY_EXPR(l2,l3,level2); - BINARY_EXPR(l1,l2,level1); - - plural_ptr cond_expr() - { - plural_ptr cond,case1,case2; - if((cond=l1()).get()==0) - return plural_ptr(); - if(t.next()=='?') { - t.get(); - if((case1=cond_expr()).get()==0) - return plural_ptr(); - if(t.get()!=':') - return plural_ptr(); - if((case2=cond_expr()).get()==0) - return plural_ptr(); - } - else { - return cond; - } - return plural_ptr(new conditional(cond,case1,case2)); - } - - tokenizer &t; - - }; - -} // namespace anon - -plural_ptr compile(char const *str) -{ - tokenizer t(str); - parser p(t); - return p.compile(); -} - - -} // lambda -} // gnu_gettext -} // locale -} // boost - -// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 - + { + return n; + }; + virtual identity *clone() const + { + return new identity(); + } + }; + + struct unary : public plural + { + unary(plural_ptr ptr) : + op1(ptr) + { + } + protected: + plural_ptr op1; + }; + + + struct binary : public plural + { + binary(plural_ptr p1,plural_ptr p2) : + op1(p1), + op2(p2) + { + } + protected: + plural_ptr op1,op2; + }; + + struct number : public plural + { + number(int v) : + val(v) + { + } + virtual int operator()(int /*n*/) const + { + return val; + } + virtual number *clone() const + { + return new number(val); + } + + private: + int val; + }; + + #define UNOP(name,oper) \ + struct name: public unary { \ + name(plural_ptr op) : unary(op) \ + { \ + }; \ + virtual int operator()(int n) const \ + { \ + return oper (*op1)(n); \ + } \ + virtual name *clone() const \ + { \ + plural_ptr op1_copy(op1->clone()); \ + return new name(op1_copy); \ + } \ + }; + + #define BINOP(name,oper) \ + struct name : public binary \ + { \ + name(plural_ptr p1,plural_ptr p2) : \ + binary(p1,p2) \ + { \ + } \ + \ + virtual int operator()(int n) const \ + { \ + return (*op1)(n) oper (*op2)(n); \ + } \ + virtual name *clone() const \ + { \ + plural_ptr op1_copy(op1->clone()); \ + plural_ptr op2_copy(op2->clone()); \ + return new name(op1_copy,op2_copy); \ + } \ + }; + + #define BINOPD(name,oper) \ + struct name : public binary { \ + name(plural_ptr p1,plural_ptr p2) : \ + binary(p1,p2) \ + { \ + } \ + virtual int operator()(int n) const \ + { \ + int v1=(*op1)(n); \ + int v2=(*op2)(n); \ + return v2==0 ? 0 : v1 oper v2; \ + } \ + virtual name *clone() const \ + { \ + plural_ptr op1_copy(op1->clone()); \ + plural_ptr op2_copy(op2->clone()); \ + return new name(op1_copy,op2_copy); \ + } \ + }; + + enum { END = 0 , SHL = 256, SHR, GTE,LTE, EQ, NEQ, AND, OR, NUM, VARIABLE }; + + UNOP(l_not,!) + UNOP(minus,-) + UNOP(bin_not,~) + + BINOP(mul,*) + BINOPD(div,/) + BINOPD(mod,%) + static int level10[]={3,'*','/','%'}; + + BINOP(add,+) + BINOP(sub,-) + static int level9[]={2,'+','-'}; + + BINOP(shl,<<) + BINOP(shr,>>) + static int level8[]={2,SHL,SHR}; + + BINOP(gt,>) + BINOP(lt,<) + BINOP(gte,>=) + BINOP(lte,<=) + static int level7[]={4,'<','>',GTE,LTE}; + + BINOP(eq,==) + BINOP(neq,!=) + static int level6[]={2,EQ,NEQ}; + + BINOP(bin_and,&) + static int level5[]={1,'&'}; + + BINOP(bin_xor,^) + static int level4[]={1,'^'}; + + BINOP(bin_or,|) + static int level3[]={1,'|'}; + + BINOP(l_and,&&) + static int level2[]={1,AND}; + + BINOP(l_or,||) + static int level1[]={1,OR}; + + struct conditional : public plural { + conditional(plural_ptr p1,plural_ptr p2,plural_ptr p3) : + op1(p1), + op2(p2), + op3(p3) + { + } + virtual int operator()(int n) const + { + return (*op1)(n) ? (*op2)(n) : (*op3)(n); + } + virtual conditional *clone() const + { + plural_ptr op1_copy(op1->clone()); + plural_ptr op2_copy(op2->clone()); + plural_ptr op3_copy(op3->clone()); + return new conditional(op1_copy,op2_copy,op3_copy); + } + private: + plural_ptr op1,op2,op3; + }; + + + plural_ptr bin_factory(int value,plural_ptr left,plural_ptr right) + { + + switch(value) { + case '/': return plural_ptr(new div(left,right)); + case '*': return plural_ptr(new mul(left,right)); + case '%': return plural_ptr(new mod(left,right)); + case '+': return plural_ptr(new add(left,right)); + case '-': return plural_ptr(new sub(left,right)); + case SHL: return plural_ptr(new shl(left,right)); + case SHR: return plural_ptr(new shr(left,right)); + case '>': return plural_ptr(new gt(left,right)); + case '<': return plural_ptr(new lt(left,right)); + case GTE: return plural_ptr(new gte(left,right)); + case LTE: return plural_ptr(new lte(left,right)); + case EQ: return plural_ptr(new eq(left,right)); + case NEQ: return plural_ptr(new neq(left,right)); + case '&': return plural_ptr(new bin_and(left,right)); + case '^': return plural_ptr(new bin_xor(left,right)); + case '|': return plural_ptr(new bin_or (left,right)); + case AND: return plural_ptr(new l_and(left,right)); + case OR: return plural_ptr(new l_or(left,right)); + default: + return plural_ptr(); + } + } + + static inline bool is_in(int v,int *p) + { + int len=*p; + p++; + while(len && *p!=v) { p++;len--; } + return len!=0; + } + + + class tokenizer { + public: + tokenizer(char const *s) { text=s; pos=0; step(); }; + int get(int *val=NULL){ + int iv=int_value; + int res=next_tocken; + step(); + if(val && res==NUM){ + *val=iv; + } + return res; + }; + int next(int *val=NULL) { + if(val && next_tocken==NUM) { + *val=int_value; + return NUM; + } + return next_tocken; + } + private: + char const *text; + int pos; + int next_tocken; + int int_value; + bool is_blank(char c) + { + return c==' ' || c=='\r' || c=='\n' || c=='\t'; + } + bool isdigit(char c) + { + return '0'<=c && c<='9'; + } + void step() + { + while(text[pos] && is_blank(text[pos])) pos++; + char const *ptr=text+pos; + char *tmp_ptr; + if(strncmp(ptr,"<<",2)==0) { pos+=2; next_tocken=SHL; } + else if(strncmp(ptr,">>",2)==0) { pos+=2; next_tocken=SHR; } + else if(strncmp(ptr,"&&",2)==0) { pos+=2; next_tocken=AND; } + else if(strncmp(ptr,"||",2)==0) { pos+=2; next_tocken=OR; } + else if(strncmp(ptr,"<=",2)==0) { pos+=2; next_tocken=LTE; } + else if(strncmp(ptr,">=",2)==0) { pos+=2; next_tocken=GTE; } + else if(strncmp(ptr,"==",2)==0) { pos+=2; next_tocken=EQ; } + else if(strncmp(ptr,"!=",2)==0) { pos+=2; next_tocken=NEQ; } + else if(*ptr=='n') { pos++; next_tocken=VARIABLE; } + else if(isdigit(*ptr)) { int_value=strtol(text+pos,&tmp_ptr,0); pos=tmp_ptr-text; next_tocken=NUM; } + else if(*ptr=='\0') { next_tocken=0; } + else { next_tocken=*ptr; pos++; } + } + }; + + + #define BINARY_EXPR(expr,hexpr,list) \ + plural_ptr expr() \ + { \ + plural_ptr op1,op2; \ + if((op1=hexpr()).get()==0) \ + return plural_ptr(); \ + while(is_in(t.next(),list)) { \ + int o=t.get(); \ + if((op2=hexpr()).get()==0) \ + return plural_ptr(); \ + op1=bin_factory(o,op1,op2); \ + } \ + return op1; \ + } + + class parser { + public: + + parser(tokenizer &tin) : t(tin) {}; + + plural_ptr compile() + { + plural_ptr res=cond_expr(); + if(res.get() && t.next()!=END) { + return plural_ptr(); + }; + return res; + } + + private: + + plural_ptr value_expr() + { + plural_ptr op; + if(t.next()=='(') { + t.get(); + if((op=cond_expr()).get()==0) + return plural_ptr(); + if(t.get()!=')') + return plural_ptr(); + return op; + } + else if(t.next()==NUM) { + int value; + t.get(&value); + return plural_ptr(new number(value)); + } + else if(t.next()==VARIABLE) { + t.get(); + return plural_ptr(new identity()); + } + return plural_ptr(); + }; + + plural_ptr un_expr() + { + plural_ptr op1; + static int level_unary[]={3,'-','!','~'}; + if(is_in(t.next(),level_unary)) { + int op=t.get(); + if((op1=un_expr()).get()==0) + return plural_ptr(); + switch(op) { + case '-': + return plural_ptr(new minus(op1)); + case '!': + return plural_ptr(new l_not(op1)); + case '~': + return plural_ptr(new bin_not(op1)); + default: + return plural_ptr(); + } + } + else { + return value_expr(); + } + }; + + BINARY_EXPR(l10,un_expr,level10); + BINARY_EXPR(l9,l10,level9); + BINARY_EXPR(l8,l9,level8); + BINARY_EXPR(l7,l8,level7); + BINARY_EXPR(l6,l7,level6); + BINARY_EXPR(l5,l6,level5); + BINARY_EXPR(l4,l5,level4); + BINARY_EXPR(l3,l4,level3); + BINARY_EXPR(l2,l3,level2); + BINARY_EXPR(l1,l2,level1); + + plural_ptr cond_expr() + { + plural_ptr cond,case1,case2; + if((cond=l1()).get()==0) + return plural_ptr(); + if(t.next()=='?') { + t.get(); + if((case1=cond_expr()).get()==0) + return plural_ptr(); + if(t.get()!=':') + return plural_ptr(); + if((case2=cond_expr()).get()==0) + return plural_ptr(); + } + else { + return cond; + } + return plural_ptr(new conditional(cond,case1,case2)); + } + + tokenizer &t; + + }; + +} // namespace anon + +plural_ptr compile(char const *str) +{ + tokenizer t(str); + parser p(t); + return p.compile(); +} + + +} // lambda +} // gnu_gettext +} // locale +} // boost + +// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 + |
