]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/src/shared/mo_lambda.cpp
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 #include "mo_lambda.hpp"
14 namespace gnu_gettext
{
18 struct identity
: public plural
{
19 virtual int operator()(int n
) const
23 virtual identity
*clone() const
25 return new identity();
29 struct unary
: public plural
31 unary(plural_ptr ptr
) :
40 struct binary
: public plural
42 binary(plural_ptr p1
,plural_ptr p2
) :
51 struct number
: public plural
57 virtual int operator()(int /*n*/) const
61 virtual number
*clone() const
63 return new number(val
);
70 #define UNOP(name,oper) \
71 struct name: public unary { \
72 name(plural_ptr op) : unary(op) \
75 virtual int operator()(int n) const \
77 return oper (*op1)(n); \
79 virtual name *clone() const \
81 plural_ptr op1_copy(op1->clone()); \
82 return new name(op1_copy); \
86 #define BINOP(name,oper) \
87 struct name : public binary \
89 name(plural_ptr p1,plural_ptr p2) : \
94 virtual int operator()(int n) const \
96 return (*op1)(n) oper (*op2)(n); \
98 virtual name *clone() const \
100 plural_ptr op1_copy(op1->clone()); \
101 plural_ptr op2_copy(op2->clone()); \
102 return new name(op1_copy,op2_copy); \
106 #define BINOPD(name,oper) \
107 struct name : public binary { \
108 name(plural_ptr p1,plural_ptr p2) : \
112 virtual int operator()(int n) const \
116 return v2==0 ? 0 : v1 oper v2; \
118 virtual name *clone() const \
120 plural_ptr op1_copy(op1->clone()); \
121 plural_ptr op2_copy(op2->clone()); \
122 return new name(op1_copy,op2_copy); \
126 enum { END
= 0 , SHL
= 256, SHR
, GTE
,LTE
, EQ
, NEQ
, AND
, OR
, NUM
, VARIABLE
};
135 static int level10
[]={3,'*','/','%'};
139 static int level9
[]={2,'+','-'};
143 static int level8
[]={2,SHL
,SHR
};
149 static int level7
[]={4,'<','>',GTE
,LTE
};
153 static int level6
[]={2,EQ
,NEQ
};
156 static int level5
[]={1,'&'};
159 static int level4
[]={1,'^'};
162 static int level3
[]={1,'|'};
165 static int level2
[]={1,AND
};
168 static int level1
[]={1,OR
};
170 struct conditional
: public plural
{
171 conditional(plural_ptr p1
,plural_ptr p2
,plural_ptr p3
) :
177 virtual int operator()(int n
) const
179 return (*op1
)(n
) ? (*op2
)(n
) : (*op3
)(n
);
181 virtual conditional
*clone() const
183 plural_ptr
op1_copy(op1
->clone());
184 plural_ptr
op2_copy(op2
->clone());
185 plural_ptr
op3_copy(op3
->clone());
186 return new conditional(op1_copy
,op2_copy
,op3_copy
);
189 plural_ptr op1
,op2
,op3
;
193 plural_ptr
bin_factory(int value
,plural_ptr left
,plural_ptr right
)
197 case '/': return plural_ptr(new div(left
,right
));
198 case '*': return plural_ptr(new mul(left
,right
));
199 case '%': return plural_ptr(new mod(left
,right
));
200 case '+': return plural_ptr(new add(left
,right
));
201 case '-': return plural_ptr(new sub(left
,right
));
202 case SHL
: return plural_ptr(new shl(left
,right
));
203 case SHR
: return plural_ptr(new shr(left
,right
));
204 case '>': return plural_ptr(new gt(left
,right
));
205 case '<': return plural_ptr(new lt(left
,right
));
206 case GTE
: return plural_ptr(new gte(left
,right
));
207 case LTE
: return plural_ptr(new lte(left
,right
));
208 case EQ
: return plural_ptr(new eq(left
,right
));
209 case NEQ
: return plural_ptr(new neq(left
,right
));
210 case '&': return plural_ptr(new bin_and(left
,right
));
211 case '^': return plural_ptr(new bin_xor(left
,right
));
212 case '|': return plural_ptr(new bin_or (left
,right
));
213 case AND
: return plural_ptr(new l_and(left
,right
));
214 case OR
: return plural_ptr(new l_or(left
,right
));
220 plural_ptr
un_factory(int value
,plural_ptr op
)
223 case '!': return plural_ptr(new l_not(op
));
224 case '~': return plural_ptr(new bin_not(op
));
225 case '-': return plural_ptr(new minus(op
));
231 static inline bool is_in(int v
,int *p
)
235 while(len
&& *p
!=v
) { p
++;len
--; }
242 tokenizer(char const *s
) { text
=s
; pos
=0; step(); };
243 int get(int *val
=NULL
){
252 int next(int *val
=NULL
) {
253 if(val
&& next_tocken
==NUM
) {
264 bool is_blank(char c
)
266 return c
==' ' || c
=='\r' || c
=='\n' || c
=='\t';
270 return '0'<=c
&& c
<='9';
274 while(text
[pos
] && is_blank(text
[pos
])) pos
++;
275 char const *ptr
=text
+pos
;
277 if(strncmp(ptr
,"<<",2)==0) { pos
+=2; next_tocken
=SHL
; }
278 else if(strncmp(ptr
,">>",2)==0) { pos
+=2; next_tocken
=SHR
; }
279 else if(strncmp(ptr
,"&&",2)==0) { pos
+=2; next_tocken
=AND
; }
280 else if(strncmp(ptr
,"||",2)==0) { pos
+=2; next_tocken
=OR
; }
281 else if(strncmp(ptr
,"<=",2)==0) { pos
+=2; next_tocken
=LTE
; }
282 else if(strncmp(ptr
,">=",2)==0) { pos
+=2; next_tocken
=GTE
; }
283 else if(strncmp(ptr
,"==",2)==0) { pos
+=2; next_tocken
=EQ
; }
284 else if(strncmp(ptr
,"!=",2)==0) { pos
+=2; next_tocken
=NEQ
; }
285 else if(*ptr
=='n') { pos
++; next_tocken
=VARIABLE
; }
286 else if(isdigit(*ptr
)) { int_value
=strtol(text
+pos
,&tmp_ptr
,0); pos
=tmp_ptr
-text
; next_tocken
=NUM
; }
287 else if(*ptr
=='\0') { next_tocken
=0; }
288 else { next_tocken
=*ptr
; pos
++; }
293 #define BINARY_EXPR(expr,hexpr,list) \
296 plural_ptr op1,op2; \
297 if((op1=hexpr()).get()==0) \
298 return plural_ptr(); \
299 while(is_in(t.next(),list)) { \
301 if((op2=hexpr()).get()==0) \
302 return plural_ptr(); \
303 op1=bin_factory(o,op1,op2); \
311 parser(tokenizer
&tin
) : t(tin
) {};
315 plural_ptr res
=cond_expr();
316 if(res
.get() && t
.next()!=END
) {
324 plural_ptr
value_expr()
329 if((op
=cond_expr()).get()==0)
335 else if(t
.next()==NUM
) {
338 return plural_ptr(new number(value
));
340 else if(t
.next()==VARIABLE
) {
342 return plural_ptr(new identity());
350 static int level_unary
[]={3,'-','!','~'};
351 if(is_in(t
.next(),level_unary
)) {
353 if((op1
=un_expr()).get()==0)
357 return plural_ptr(new minus(op1
));
359 return plural_ptr(new l_not(op1
));
361 return plural_ptr(new bin_not(op1
));
371 BINARY_EXPR(l10
,un_expr
,level10
);
372 BINARY_EXPR(l9
,l10
,level9
);
373 BINARY_EXPR(l8
,l9
,level8
);
374 BINARY_EXPR(l7
,l8
,level7
);
375 BINARY_EXPR(l6
,l7
,level6
);
376 BINARY_EXPR(l5
,l6
,level5
);
377 BINARY_EXPR(l4
,l5
,level4
);
378 BINARY_EXPR(l3
,l4
,level3
);
379 BINARY_EXPR(l2
,l3
,level2
);
380 BINARY_EXPR(l1
,l2
,level1
);
382 plural_ptr
cond_expr()
384 plural_ptr cond
,case1
,case2
;
385 if((cond
=l1()).get()==0)
389 if((case1
=cond_expr()).get()==0)
393 if((case2
=cond_expr()).get()==0)
399 return plural_ptr(new conditional(cond
,case1
,case2
));
408 plural_ptr
compile(char const *str
)
421 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4