static void groups(FIELD *start,int group) { FIELD *walk; TAG *scan; for (walk = start; walk; walk = walk->next) { if (walk->structure) { groups(walk->my_block,group); continue; } if (walk->value) switch (walk->value->type) { case vt_id: break; case vt_case: case vt_multi: for (scan = walk->value->tags; scan; scan = scan->next) { int start_field,length,offset; if (scan->block && scan->block->structure && scan->block->structure->instances < 0) { start_field = scan->block->structure->first_field; length = scan->block->structure->fields; offset = scan->block->my_block->field- scan->block->structure->first_field; } else { start_field = -1; length = offset = 0; } if (scan->id) to_test(" \"%s\",\n",scan->id); if (scan->block && scan->block->has_required) if (scan->block->id) to_c(" { %d, required_%d, %d, %d, %d }, " "/* %s */\n",group,scan->group,start_field, length,offset,scan->block->id); else to_c(" { %d, required_%d, %d, %d, %d },\n", group,scan->group,start_field,length,offset); else to_c(" { %d, NULL, %d, %d, %d },\n",group, start_field,length,offset); groups(scan->block,scan->group); } break; case vt_length: groups(walk->value->block,group); break; default: abort(); } } }
static void fields(FIELD *start,int group) { FIELD *walk; TAG *scan; VALUE_LIST *tag; for (walk = start; walk; walk = walk->next) { if (walk->structure) { fields(walk->my_block,group); continue; } if (*walk->id != '_') { if (walk->value && walk->value->type == vt_case) to_c(" { %d, %d, %d, values_%d, %d }, /* %s */\n",group, walk->pos,walk->size,walk->field,walk->var_len,walk->id); else to_c(" { %d, %d, %d, NULL, %d }, /* %s */\n",group, walk->pos,walk->size,walk->var_len,walk->id); } if (walk->value) switch (walk->value->type) { case vt_id: break; case vt_case: case vt_multi: for (scan = walk->value->tags; scan; scan = scan->next) fields(scan->block,scan->group); to_test("static int unique_%d[] = { /* %s */\n",unique++, walk->id); for (scan = walk->value->tags; scan; scan = scan->next) { to_test(" %s,\n",scan->value); for (tag = scan->more; tag; tag = tag->next) to_test(" %s,\n",tag->value); } to_test(" -1\n};\n\n"); break; case vt_length: fields(walk->value->block,group); break; default: abort(); } } }
static void values(FIELD *start) { FIELD *walk; TAG *scan; VALUE_LIST *tag; for (walk = start; walk; walk = walk->next) { if (walk->structure) { values(walk->my_block); } if (walk->value) switch (walk->value->type) { case vt_id: break; case vt_case: if (*walk->id != '_') { to_c("static int values_%d[] = { /* %s */\n", walk->field,walk->id); for (scan = walk->value->tags; scan; scan = scan->next) { to_c(" %s, %d,\n",scan->value,scan->group); for (tag = scan->more; tag; tag = tag->next) to_c(" %s, %d,\n",tag->value,scan->group); if (scan->deflt) to_c(" -2, %d,\n",scan->group); /* could also skip while entry, but maybe we'll want to use the tags later */ } to_c(" -1, -1\n};\n\n"); } /* fall through */ case vt_multi: for (scan = walk->value->tags; scan; scan = scan->next) values(scan->block); break; case vt_length: values(walk->value->block); break; default: abort(); } } }
static void dump_required(FIELD *start,FIELD *leader,int group) { FIELD *walk; for (walk = start; walk; walk = walk->next) { if (walk->structure) { dump_required(walk->my_block,leader,group); continue; } if (walk->brk) break; if (!walk->value) { if (!leader->has_required) { to_c("static int required_%d[] = {\n",group); leader->has_required = 1; } to_c(" %d, /* %s */\n",walk->field,walk->id); } else if (walk->value->type == vt_length) dump_required(walk->value->block,leader,group); } if (leader == start && leader && leader->has_required) to_c(" -1\n};\n\n"); }
void third(FIELD *def) { if (dump) constr_size = 0; else { to_c("\n/*\n"); to_c(" * \"Microcode\" used to construct messages. It copies all\n"); to_c(" * fields from the construction area to the resulting message."); to_c("\n */\n\n"); to_c("static int construct[] = {\n"); begin_code(); construct(def); constr_size = end_code()+1; to_c(" OP_END\n};\n\n"); } to_c("\n/*\n * \"Microcode\" used to parse messages. It detects the\n"); to_c(" * presence of fields and copies them from the message to the\n"); to_c(" * construction area.\n */\n\n"); to_c("static int parse[] = {\n"); if (dump) { to_dump("typedef struct {\n int level;\n const SYM_NAME *sym;\n"); to_dump(" const char *name;\n"); to_dump("} DUMP_FIELD;\n\n"); to_dump("static DUMP_FIELD dump_fields[] = {\n"); } begin_code(); parser(def,0,0); parser_size = end_code()+1; to_c(" OP_END\n};\n\n"); if (dump) to_dump("};\n\n"); }
int main(int argc,char **argv) { const char *prefix; if (argc == 2 && !strcmp(argv[1],"-d")) debug = 1; if (argc == 2 && !strcmp(argv[1],"-D")) dump = 1; prefix = getenv("PREFIX"); if (!prefix) prefix = dump ? "qd" : "q"; open_files(prefix); to_h("/* THIS IS A MACHINE-GENERATED FILE. DO NOT EDIT ! */\n\n"); to_c("/* THIS IS A MACHINE-GENERATED FILE. DO NOT EDIT ! */\n\n"); to_c("#if HAVE_CONFIG_H\n"); to_c("#include <config.h>\n"); to_c("#endif\n\n"); to_test("/* THIS IS A MACHINE-GENERATED FILE. DO NOT EDIT ! */\n\n"); to_test("#if HAVE_CONFIG_H\n"); to_test("#include <config.h>\n"); to_test("#endif\n\n"); if (dump) { to_dump("/* THIS IS A MACHINE-GENERATED FILE. DO NOT EDIT ! */\n\n"); to_dump("#if HAVE_CONFIG_H\n"); to_dump("#include <config.h>\n"); to_dump("#endif\n\n"); } to_c("/* (optional) user includes go here */\n\n"); to_test("/* (optional) user includes go here */\n\n"); if (dump) to_dump("/* (optional) user includes go here */\n\n"); if (yyparse()) return 1; to_test("\n#ifndef NULL\n#define NULL ((void *) 0)\n#endif\n\n"); if (dump) to_dump("\n#ifndef NULL\n#define NULL ((void *) 0)\n#endif\n\n"); to_h("#ifndef Q_OUT_H\n#define Q_OUT_H\n\n"); to_c("\n#include <stdlib.h>\n#include <stdio.h>\n"); to_c("#include <string.h>\n#include <sys/types.h>\n\n"); to_c("#include \"common.h\"\n#include \"op.h\"\n"); to_c("#include \"%s.out.h\"\n",prefix); to_c("#include \"qlib.h\"\n\n"); to_c("\n\nstatic void q_put(unsigned char *table,int pos,int size," "unsigned long value);\n\n"); first(def); second(def); third(def); to_h("#endif\n"); to_c("\n/*\n * Sorry, this is necessary ...\n */\n\n"); to_c("#include \"qlib.c\"\n"); to_test("\n/*\n * Sorry, this is necessary ...\n */\n\n"); to_test("#include \"qtest.c\"\n"); if (dump) { to_dump("\n/*\n * Sorry, this is necessary ...\n */\n\n"); to_dump("#define DUMP_MODE\n\n"); to_dump("#include \"%s.out.c\"\n",prefix); } close_files(); fprintf(stderr," %d groups, %d fields (%d var-len), construction area is " "%d bytes,\n",group,field,varlen_fields,(offset+7)/8); fprintf(stderr," %d words in constructor, %d words in parser", constr_size,parser_size); if (!dump) fprintf(stderr,".\n"); else fprintf(stderr,",\n %d symbolic names in %d tables.\n",symbols, sym_tables); return 0; }
void export_line(enum token_line t) { int count; char buf[MAXLINEBUF]; char buf1[MAXLINEBUF]; char cache[MAXLINEBUF]; int len; switch (t) { case SECTION_HEADER: output("struct sect%s {\n", to_c(section, buf1, 0)); break; case SECTION_NAME: output("\t%s\tname[%d];\n", to_c(type, buf1, 0), bytes); break; case SECTION_NUMBER: count = bytes / sizeof_type(type); if (count == 1) { output("\t%s\tnumber;\n", to_c(type, buf1, 0)); } else { output("\t%s\tnumber[%d];\n", to_c(type, buf1, 0), count); } break; case ITEM_HEADER: output("\tstruct st%s *%s;\n", to_c(g_buf, buf, 1), to_c(g_buf, buf1, 0)); rewind_cache(CACHE1); field1 = 0; len = sprintf(cache, "\tstruct st%s {\n", to_c(g_buf, buf, 1)); output_cache(CACHE1, cache, len); break; case ITEM_FIELD: count = bytes / sizeof_type(type); if (count == 1) { len = sprintf(cache, "\t\t%s\tf%d_%s;\n", to_c(type, buf, 0), field1++, to_c(field, buf1, 0)); } else { len = sprintf(cache, "\t\t%s\tf%d_%s[%d];\n", to_c(type, buf, 0), field1++, to_c(field, buf1, 0), count); } output_cache(CACHE1, cache, len); break; case ITEM_FIELD_BINARY: break; case ITEM_FIELD_BINARY_HEADER: break; case ITEM_FIELD_BINARY_BITFIELD: break; case ITEM_ITEM_HEADER: len = sprintf(cache, "\t\tstruct stt%s *%s;\n", to_c(g_buf, buf, 1), to_c(g_buf, buf1, 0)); output_cache(CACHE1, cache, len); rewind_cache(CACHE2); field2 = 0; len = sprintf(cache, "\t\tstruct stt%s {\n", to_c(g_buf, buf, 1)); output_cache(CACHE2, cache, len); break; case ITEM_ITEM_FIELD: count = bytes / sizeof_type(type); if (count == 1) { len = sprintf(cache, "\t\t\t%s\tf%d_%s;\n", to_c(type, buf, 0), field2++, to_c(field, buf1, 0)); } else { len = sprintf(cache, "\t\t\t%s\tf%d_%s[%d];\n", to_c(type, buf, 0), field2++, to_c(field, buf1, 0), count); } output_cache(CACHE2, cache, len); break; case ITEM_ITEM_ITEM_HEADER: len = sprintf(cache, "\t\t\tstruct sttt%s *%s;\n", to_c(g_buf, buf, 1), to_c(g_buf, buf1, 0)); output_cache(CACHE2, cache, len); rewind_cache(CACHE3); field3 = 0; len = sprintf(cache, "\t\t\tstruct sttt%s {\n", to_c(g_buf, buf, 1)); output_cache(CACHE3, cache, len); break; case ITEM_ITEM_ITEM_FIELD: count = bytes / sizeof_type(type); if (count == 1) { len = sprintf(cache, "\t\t\t\t%s\tf%d_%s;\n", to_c(type, buf, 0), field3++, to_c(field, buf1, 0)); } else { len = sprintf(cache, "\t\t\t\t%s\tf%d_%s[%d];\n", to_c(type, buf, 0), field3++, to_c(field, buf1, 0), count); } output_cache(CACHE3, cache, len); break; default: ; } }
void second(FIELD *def) { int i; def->has_required = 0; to_c("\n/*\n"); to_c(" * If a group contains required fields, these are listed in the\n"); to_c(" * following arrays. Each list ends with -1. The variable names\n"); to_c(" * end with the group number.\n */\n\n"); dump_required(def,def,0); find_required(def); to_c("\n/*\n * Various information about groups.\n */\n\n"); to_c("typedef struct {\n int parent;\n int *required;\n"); to_c(" int start;\n int length;\n int offset;\n} GROUP;\n\n"); to_c("static GROUP groups[] = {\n"); if (def->has_required) to_c(" { -1, required_0 },\n"); else to_c(" { -1, NULL },\n"); to_test("static const char *groups[] = {\n"); groups(def,0); to_test(" NULL\n};\n\n"); to_c("};\n\n\n"); to_c("/*\n * Named case selectors only have a limited set of valid\n"); to_c(" * values. They are listed in the following arrays, each followed\n"); to_c(" * by the number of the group it enables.\n */\n\n"); values(def); to_c("\n/*\n * Various information about fields.\n */\n\n"); to_c("typedef struct {\n int parent;\n int pos,size;\n"); to_c(" int *values;\n int actual;\n} FIELD;\n\n"); to_c("static FIELD fields[] = {\n"); fields(def,0); to_c("};\n\n"); to_test("static int *unique[] = {\n"); for (i = 0; i < unique; i++) to_test(" unique_%d,\n",i); to_test(" NULL\n};\n\n"); if (dump) { to_dump("typedef struct {\n unsigned long value;\n"); to_dump(" const char *name;\n} SYM_NAME;\n\n"); symbolic_names(def); } }
ActionVec propose_plan(World *wo, const MetricVec& from_c0, const MetricVec& to_c0, const ai::Context& ctx) { using AstarEngine = AStarSearch<AstarNode>; AstarEngine engine; // For each actiondef in all actions - and for each requirement in each // actiondef - see if we need to add another metric from the world. MetricVec from_c(from_c0); MetricVec to_c(to_c0); check(ctx.actor_); AstarGlobalState glob_state { {}, ctx.actor_->ai_get_all_actions() }; for (auto& adef: glob_state.available_actions_) { //qDebug() << "Each avail action:" << adef; for (auto& req: adef.requires_) { if (not impl::have_metric(from_c, req.type_)) { auto extra_mtr = wo->read_metric(req, ctx); //qDebug() << "Extra metric:" << extra_mtr; from_c.push_back(extra_mtr); //to_c.push_back(extra_mtr); } } } // qDebug() << "HAVE" << from_c; // qDebug() << "WANT" << to_c; glob_state.goal_ = to_c; // to_c is probably changed - update AstarNode from(from_c, &glob_state, ActionType::None); AstarNode to(to_c, &glob_state, ActionType::None); engine.SetStartAndGoalStates(from, to); unsigned int search_state; unsigned int search_steps = 0; do { search_state = engine.SearchStep(); search_steps++; } while (search_state == AstarEngine::SEARCH_STATE_SEARCHING); ActionVec plan; if (search_state == AstarEngine::SEARCH_STATE_SUCCEEDED) { //qDebug() << "plan: Found a plan"; plan.reserve(search_steps); for (AstarNode* node = engine.GetSolutionStart(); node; node = engine.GetSolutionNext()) { if (node->action_ != ActionType::None) { // qDebug() << "plan: Step=" << node->action_; plan.push_back(node->action_); } } if (not glob_state.single_step_.empty()) { auto extra_action = glob_state.single_step_.front(); // qDebug() << "plan: [extra] Step=" << extra_action; plan.push_back(extra_action); } // Once you're done with the solution you can free the nodes up engine.FreeSolutionNodes(); } else { if (search_state == AstarEngine::SEARCH_STATE_FAILED) { //qDebug() << "plan: Did not find a plan"; } } engine.EnsureMemoryFreed(); return plan; }