void generate_precondition_next(ast::tree& ast, ast::node* root, unsigned branch_index, formatter& output) { plnnrc_assert(is_logical_op(root)); output.writeln("bool next(p%d_state& state, worldstate& world)", branch_index); { scope s(output); output.writeln("PLNNR_COROUTINE_BEGIN(state);"); output.newline(); generate_precondition_satisfier(ast, root, output); output.writeln("PLNNR_COROUTINE_END();"); } }
// expression = term { add_op term } | // expression "?" expression ":" expression // expression logical_op expression // variable "=" expression // add_op = "+" | "-" static enum v7_err parse_expression(struct v7 *v7) { #ifdef V7_DEBUG const char *stmt_str = v7->cursor; #endif int op; v7->cur_obj = &v7->scopes[v7->current_scope]; TRY(parse_term(v7)); while (*v7->cursor == '-' || *v7->cursor == '+') { int ch = *v7->cursor; TRY(match(v7, ch)); TRY(parse_term(v7)); TRY(do_arithmetic_op(v7, ch)); } if ((op = is_logical_op(v7->cursor)) > OP_XX) { v7->cursor += op == OP_LT || op == OP_GT ? 1 : 2; skip_whitespaces_and_comments(v7); TRY(parse_expression(v7)); TRY(do_logical_op(v7, op)); } // Parse assignment if (*v7->cursor == '=') { //printf("=> cur_obj: %p\n", cur_obj); TRY(parse_assignment(v7, v7->cur_obj)); } // Parse ternary operator if (*v7->cursor == '?') { int condition_true = v7_is_true(v7_top(v7)[-1]); int old_no_exec = v7->no_exec; TRY(match(v7, '?')); v7->no_exec = old_no_exec || !condition_true; TRY(parse_expression(v7)); TRY(match(v7, ':')); v7->no_exec = old_no_exec || condition_true; TRY(parse_expression(v7)); v7->no_exec = old_no_exec; } return V7_OK; }