| 185 | static Value& parse_const_expr(Type &type); |
| 186 | |
| 187 | static Predicate* parse_predicate(Predicate *last = nullptr, |
| 188 | token last_t = END) { |
| 189 | switch (auto t = *tokenizer) { |
| 190 | case LPAREN: { |
| 191 | auto newpred = parse_predicate(); |
| 192 | tokenizer.ensure(RPAREN); |
| 193 | if (last == nullptr) { |
| 194 | parse_more: |
| 195 | switch (auto t = *tokenizer) { |
| 196 | case BAND: |
| 197 | case BOR: |
| 198 | return parse_predicate(newpred, t); |
| 199 | default: |
| 200 | tokenizer.unget(t); |
| 201 | return newpred; |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | if (last_t == BAND) { |
| 206 | auto p = make_unique<BoolPred>(*last, *newpred, BoolPred::AND); |
| 207 | newpred = p.get(); |
| 208 | fn->addPredicate(std::move(p)); |
| 209 | goto parse_more; |
| 210 | } |
| 211 | |
| 212 | assert(last_t == BOR); |
| 213 | |
| 214 | switch (auto t = *tokenizer) { |
| 215 | case BAND: { |
| 216 | newpred = parse_predicate(newpred, BAND); |
| 217 | auto p = make_unique<BoolPred>(*last, *newpred, BoolPred::OR); |
| 218 | auto ret = p.get(); |
| 219 | fn->addPredicate(std::move(p)); |
| 220 | return ret; |
| 221 | } |
| 222 | |
| 223 | case BOR: { |
| 224 | auto p = make_unique<BoolPred>(*last, *newpred, BoolPred::OR); |
| 225 | auto ret = p.get(); |
| 226 | fn->addPredicate(std::move(p)); |
| 227 | return parse_predicate(ret, BOR); |
| 228 | } |
| 229 | |
| 230 | default: { |
| 231 | tokenizer.unget(t); |
| 232 | auto p = make_unique<BoolPred>(*last, *newpred, |
| 233 | last_t == BAND ? BoolPred::AND : |
| 234 | BoolPred::OR); |
| 235 | auto ret = p.get(); |
| 236 | fn->addPredicate(std::move(p)); |
| 237 | return ret; |
| 238 | } |
| 239 | } |
| 240 | break; |
| 241 | } |
| 242 | case IDENTIFIER: { |
| 243 | // function: identifier '(' arg0, ... argn ')' |
| 244 | vector<Value*> args; |