static void * gensub(gclass_t * cl, int x) { int i; gelm_t * elm; gclass_t * sub; // search through subclasses for (i = 0; i < cl->sub.cnt; i++) { sub = cl->sub.arr[i]; x -= sub->max_freq; if (x <= 0) { return gensub(sub, -x); } } // search through elements for (i = 0; i < cl->elm.cnt; i++) { elm = cl->elm.arr[i]; x -= elm->adj_freq; if (x <= 0) { return elm->stuff; } } assert(0); return NULL; }
int genbinop(int op, int p1, int p2) { binopchk(op, p1, p2); switch (op) { case PLUS: return genadd(p1, p2, 1); case MINUS: return gensub(p1, p2, 1); case STAR: genmul(); break; case SLASH: gendiv(1); break; case MOD: genmod(1); break; case LSHIFT: genshl(1); break; case RSHIFT: genshr(1); break; case AMPER: genand(); break; case CARET: genxor(); break; case PIPE: genior(); break; case EQUAL: queue_cmp(equal); break; case NOTEQ: queue_cmp(not_equal); break; case LESS: queue_cmp(less); break; case GREATER: queue_cmp(greater); break; case LTEQ: queue_cmp(less_equal); break; case GTEQ: queue_cmp(greater_equal); break; } return PINT; }
void genasop(int op, int p1, int p2, int swapped) { binopchk(op, p1, p2); switch (op) { case ASDIV: gendiv(swapped); break; case ASMUL: genmul(); break; case ASMOD: genmod(swapped); break; case ASPLUS: genadd(p1, p2, swapped); break; case ASMINUS: gensub(p1, p2, swapped); break; case ASLSHIFT: genshl(swapped); break; case ASRSHIFT: genshr(swapped); break; case ASAND: genand(); break; case ASXOR: genxor(); break; case ASOR: genior(); break; } }
static void * gen(gclass_t * cl, int lvl) { cache_tree(cl, lvl); assert(cl->max_freq); return gensub(cl, random() % cl->max_freq); }