void generate_precondition_satisfier(ast::tree& ast, ast::node* root, formatter& output) { plnnrc_assert(ast::is_op_or(root)); for (ast::node* child = root->first_child; child != 0; child = child->next_sibling) { plnnrc_assert(ast::is_op_and(child)); generate_conjunctive_clause(ast, child, output); } }
void generate_literal_chain_comparison(ast::tree& ast, ast::node* root, ast::node* atom, formatter& output) { ast::node* arg_0 = atom->first_child; plnnrc_assert(arg_0 && ast::is_term_variable(arg_0)); ast::node* arg_1 = arg_0->next_sibling; plnnrc_assert(arg_1 && ast::is_term_variable(arg_1) && !arg_1->next_sibling); plnnrc_assert(definition(arg_0) && definition(arg_1)); const char* comparison_op = atom->s_expr->token; int var_index_0 = ast::annotation<ast::term_ann>(arg_0)->var_index; int var_index_1 = ast::annotation<ast::term_ann>(arg_1)->var_index; if (ast::is_op_not(root)) { output.writeln("if (!(state._%d %s state._%d))", var_index_0, comparison_op, var_index_1); } else { output.writeln("if (state._%d %s state._%d)", var_index_0, comparison_op, var_index_1); } { scope s(output, root->next_sibling != 0); if (root->next_sibling) { generate_literal_chain(ast, root->next_sibling, output); } else { output.writeln("PLNNR_COROUTINE_YIELD(state);"); } } }
void generate_conjunctive_clause(ast::tree& ast, ast::node* root, formatter& output) { plnnrc_assert(ast::is_op_and(root)); if (root->first_child) { generate_literal_chain(ast, root->first_child, output); } else { // the formula is trivial: (or (and)) output.writeln("PLNNR_COROUTINE_YIELD(state);"); output.newline(); } }
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();"); } }
void generate_worldstate_reflectors(ast::Tree& ast, ast::Node* worldstate, Formatter& output) { ast::Node* worldstate_namespace = worldstate->first_child; plnnrc_assert(worldstate_namespace && ast::is_namespace(worldstate_namespace)); Paste_Fully_Qualified_Namespace paste_world_namespace(worldstate_namespace); output.writeln("template <typename V>"); output.writeln("struct Generated_Type_Reflector<%p::Worldstate, V>", &paste_world_namespace); { Class_Scope s(output); output.writeln("void operator()(const %p::Worldstate& world, V& visitor)", &paste_world_namespace); { Scope s(output, false); for (ast::Node* atom = worldstate_namespace->next_sibling; atom != 0; atom = atom->next_sibling) { if (!ast::is_atom(atom)) { continue; } output.writeln("PLNNR_GENCODE_VISIT_ATOM_LIST(%p, atom_%i, %i_tuple, visitor);", &paste_world_namespace, atom->s_expr->token, atom->s_expr->token); } } } for (ast::Node* atom = worldstate_namespace->next_sibling; atom != 0; atom = atom->next_sibling) { if (!ast::is_atom(atom)) { continue; } generate_atom_reflector(ast, atom, &paste_world_namespace, "atom_name", "tuple", "atom", output); } }
void generate_preconditions(ast::tree& ast, ast::node* domain, formatter& output) { unsigned branch_index = 0; for (ast::node* method = domain->first_child; method != 0; method = method->next_sibling) { if (!ast::is_method(method)) { continue; } for (ast::node* branch = method->first_child->next_sibling; branch != 0; branch = branch->next_sibling) { plnnrc_assert(ast::is_branch(branch)); ast::node* precondition = branch->first_child; generate_precondition_state(ast, precondition, branch_index, output); generate_precondition_next(ast, precondition, branch_index, output); ++branch_index; } } }
virtual void operator()(formatter& output) { output.put_id(function_call->s_expr->token); output.put_char('('); for (ast::node* argument = function_call->first_child; argument != 0; argument = argument->next_sibling) { switch (argument->type) { case ast::node_term_variable: { int var_index = ast::annotation<ast::term_ann>(argument)->var_index; output.put_str(var_prefix); output.put_int(var_index); } break; case ast::node_term_call: { paste_precondition_function_call paste(argument, var_prefix); output.put_str("world."); paste(output); } break; default: // unsupported argument type plnnrc_assert(false); } if (!is_last(argument)) { output.put_str(", "); } } output.put_char(')'); }
void generate_domain_reflectors(ast::Tree& ast, ast::Node* domain, Formatter& output) { ast::Node* domain_namespace = domain->first_child; plnnrc_assert(domain_namespace && ast::is_namespace(domain_namespace)); Paste_Fully_Qualified_Namespace paste_domain_namespace(domain_namespace); for (Id_Table_Values operators = ast.operators.values(); !operators.empty(); operators.pop()) { ast::Node* atom = operators.value()->first_child; if (!atom->first_child) { continue; } generate_atom_reflector(ast, atom, &paste_domain_namespace, "task_name", "args", "task", output); } for (ast::Node* method = domain->first_child; method != 0; method = method->next_sibling) { if (!ast::is_method(method)) { continue; } ast::Node* atom = method->first_child; if (!atom->first_child) { continue; } generate_atom_reflector(ast, atom, &paste_domain_namespace, "task_name", "args", "task", output); } }
void generate_literal_chain(ast::tree& ast, ast::node* root, formatter& output) { plnnrc_assert(ast::is_op_not(root) || ast::is_term_call(root) || is_atom(root) || is_comparison_op(root)); ast::node* atom = root; if (ast::is_op_not(root)) { atom = root->first_child; } if (ast::is_comparison_op(atom)) { generate_literal_chain_comparison(ast, root, atom, output); return; } if (ast::is_term_call(atom)) { generate_literal_chain_call_term(ast, root, atom, output); return; } const char* atom_id = atom->s_expr->token; int atom_index = ast::annotation<ast::atom_ann>(atom)->index; if (ast::is_op_not(root) && all_unbound(atom)) { output.writeln("if (!tuple_list::head<%i_tuple>(world.atoms[atom_%i]))", atom_id, atom_id); { scope s(output); if (root->next_sibling) { generate_literal_chain(ast, root->next_sibling, output); } else { output.writeln("PLNNR_COROUTINE_YIELD(state);"); } } } else if (ast::is_op_not(root) && all_bound(atom)) { output.writeln("for (state.%i_%d = tuple_list::head<%i_tuple>(world.atoms[atom_%i]); state.%i_%d != 0; state.%i_%d = state.%i_%d->next)", atom_id, atom_index, atom_id, atom_id, atom_id, atom_index, atom_id, atom_index, atom_id, atom_index); { scope s(output); int atom_param_index = 0; for (ast::node* term = atom->first_child; term != 0; term = term->next_sibling) { if (ast::is_term_variable(term)) { int var_index = ast::annotation<ast::term_ann>(term)->var_index; output.writeln("if (state.%i_%d->_%d == state._%d)", atom_id, atom_index, atom_param_index, var_index); { scope s(output, !is_last(term)); output.writeln("break;"); } } if (ast::is_term_call(term)) { paste_precondition_function_call paste(term, "state._"); output.writeln("if (state.%i_%d->_%d == world.%p)", atom_id, atom_index, atom_param_index, &paste); { scope s(output, !is_last(term)); output.writeln("break;"); } } ++atom_param_index; } } output.writeln("if (state.%i_%d == 0)", atom_id, atom_index); { scope s(output, is_first(root)); if (root->next_sibling) { generate_literal_chain(ast, root->next_sibling, output); } else { output.writeln("PLNNR_COROUTINE_YIELD(state);"); } } } else { output.writeln("for (state.%i_%d = tuple_list::head<%i_tuple>(world.atoms[atom_%i]); state.%i_%d != 0; state.%i_%d = state.%i_%d->next)", atom_id, atom_index, atom_id, atom_id, atom_id, atom_index, atom_id, atom_index, atom_id, atom_index); { scope s(output, is_first(root)); const char* comparison_op = "!="; if (ast::is_op_not(root)) { comparison_op = "=="; } int atom_param_index = 0; for (ast::node* term = atom->first_child; term != 0; term = term->next_sibling) { if (ast::is_term_variable(term) && definition(term)) { int var_index = ast::annotation<ast::term_ann>(term)->var_index; output.writeln("if (state.%i_%d->_%d %s state._%d)", atom_id, atom_index, atom_param_index, comparison_op, var_index); { scope s(output); output.writeln("continue;"); } } if (ast::is_term_call(term)) { paste_precondition_function_call paste(term, "state._"); output.writeln("if (state.%i_%d->_%d %s world.%p)", atom_id, atom_index, atom_param_index, comparison_op, &paste); { scope s(output); output.writeln("continue;"); } } ++atom_param_index; } atom_param_index = 0; for (ast::node* term = atom->first_child; term != 0; term = term->next_sibling) { if (ast::is_term_variable(term) && !definition(term)) { int var_index = ast::annotation<ast::term_ann>(term)->var_index; output.writeln("state._%d = state.%i_%d->_%d;", var_index, atom_id, atom_index, atom_param_index); output.newline(); } ++atom_param_index; } if (root->next_sibling) { generate_literal_chain(ast, root->next_sibling, output); } else { output.writeln("PLNNR_COROUTINE_YIELD(state);"); } } } }
void generate_task_type_dispatcher(ast::Tree& ast, ast::Node* domain, Formatter& output) { ast::Node* domain_namespace = domain->first_child; plnnrc_assert(domain_namespace && ast::is_namespace(domain_namespace)); Paste_Fully_Qualified_Namespace paste_namespace(domain_namespace); output.writeln("template <typename V>"); output.writeln("struct Task_Type_Dispatcher<%p::Task_Type, V>", &paste_namespace); { Class_Scope s(output); output.writeln("void operator()(const %p::Task_Type& task_type, void* args, V& visitor)", &paste_namespace); { Scope s(output, false); output.writeln("switch (task_type)"); { Scope s(output, false); for (ast::Node* method = domain->first_child; method != 0; method = method->next_sibling) { if (!ast::is_method(method)) { continue; } ast::Node* method_atom = method->first_child; plnnrc_assert(method_atom); output.writeln("case %p::task_%i:", &paste_namespace, method_atom->s_expr->token); { Indented s(output); const char* atom_id = method_atom->s_expr->token; if (method_atom->first_child) { output.writeln("PLNNR_GENCODE_VISIT_TASK_WITH_ARGS(visitor, %p, task_%i, %i_args);", &paste_namespace, atom_id, atom_id); } else { output.writeln("PLNNR_GENCODE_VISIT_TASK_NO_ARGS(visitor, %p, task_%i);", &paste_namespace, atom_id); } output.writeln("break;"); } } for (Id_Table_Values operators = ast.operators.values(); !operators.empty(); operators.pop()) { ast::Node* operatr = operators.value(); ast::Node* operator_atom = operatr->first_child; output.writeln("case %p::task_%i:", &paste_namespace, operator_atom->s_expr->token); { Indented s(output); const char* atom_id = operator_atom->s_expr->token; if (operator_atom->first_child) { output.writeln("PLNNR_GENCODE_VISIT_TASK_WITH_ARGS(visitor, %p, task_%i, %i_args);", &paste_namespace, atom_id, atom_id); } else { output.writeln("PLNNR_GENCODE_VISIT_TASK_NO_ARGS(visitor, %p, task_%i);", &paste_namespace, atom_id); } output.writeln("break;"); } } output.writeln("default:"); { Indented s(output); output.writeln("plnnr_assert(false);"); output.writeln("break;"); } } } } }
void format_error(Error_Ann* annotation, Writer& stream) { Formatter output(stream); output.init(2048); const char* format = error_format_string(annotation->id); output.put_str("error: "); output.put_char('['); output.put_int(annotation->line); output.put_char(':'); output.put_int(annotation->column); output.put_str("] "); while (*format) { if (*format == '$') { move(format); char digit = *format; plnnrc_assert(isdigit(digit)); int slot = digit - '0'; plnnrc_assert(slot < annotation->argument_count); Error_Argument_Type arg_type = annotation->argument_type[slot]; plnnrc_assert(arg_type != error_argument_none); switch (arg_type) { case error_argument_node_token: { sexpr::Node* s_expr = annotation->argument_node[slot]; output.put_str(s_expr->token); } break; case error_argument_node_location: { Location arg = annotation->argument_location[slot]; output.put_char('['); output.put_int(arg.line); output.put_char(':'); output.put_int(arg.column); output.put_char(']'); } break; case error_argument_node_string: { const char* arg = annotation->argument_string[slot]; output.put_str(arg); } break; case error_argument_selection: { move(format); plnnrc_assert(*format == '{'); move(format); int selection = annotation->argument_selection[slot]; for (int i = 0; i < selection; ++i) { skip(format, '|'); move(format); } while (*format != '|' && *format != '}') { plnnrc_assert(format); output.put_char(*format); move(format); } skip(format, '}'); } break; default: break; } } else { output.put_char(*format); } move(format); } output.put_char('\n'); }
void deallocate(void* ptr) { plnnrc_assert(dealloc_f != 0); dealloc_f(ptr); }
void* allocate(size_t size) { plnnrc_assert(alloc_f != 0); return alloc_f(size); }