void generate_condition(component condition, label slab, gencode scode, void *sdata, label flab, gencode fcode, void *fdata, fncode fn) { struct andordata data; switch (condition->vclass) { case c_builtin: switch (condition->u.builtin.fn) { case b_sc_and: case b_sc_or: { component arg1 = condition->u.builtin.args->c; data.arg2 = condition->u.builtin.args->next->c; data.lab = new_label(fn); data.slab = slab; data.scode = scode; data.sdata = sdata; data.flab = flab; data.fcode = fcode; data.fdata = fdata; if (condition->u.builtin.fn == b_sc_and) generate_condition(arg1, data.lab, andorcode, &data, flab, NULL, NULL, fn); else generate_condition(arg1, slab, NULL, NULL, data.lab, andorcode, &data, fn); return; } case b_not: /* Just swap conclusions */ generate_condition(condition->u.builtin.args->c, flab, fcode, fdata, slab, scode, sdata, fn); return; } /* Fall through */ default: generate_component(condition, NULL, FALSE, fn); if (scode) { branch(OPmbf3, flab, fn); scode(sdata, fn); if (fcode) fcode(fdata, fn); } else { branch(OPmbt3, slab, fn); if (fcode) fcode(fdata, fn); else branch(OPmba3, flab, fn); } break; } }
void generate_for(component init, component condition, component next, component iteration, const char *continue_label, bool discard, fncode fn) { struct whiledata wdata; env_block_push(NULL); /* init may have local declarations */ if (init) generate_component(init, NULL, TRUE, fn); start_block(NULL, FALSE, discard, fn); wdata.continue_label = continue_label; wdata.looplab = new_label(fn); wdata.mainlab = new_label(fn); wdata.endlab = new_label(fn); wdata.code = iteration; wdata.next = next; set_label(wdata.looplab, fn); if (condition) { generate_condition(condition, wdata.mainlab, wmain_code, &wdata, wdata.endlab, NULL, NULL, fn); set_label(wdata.endlab, fn); if (!discard) generate_component(component_undefined, NULL, FALSE, fn); } else wmain_code(&wdata, fn); end_block(fn); env_block_pop(); }
static void andorcode(void *_data, fncode fn) { struct andordata *data = _data; set_label(data->lab, fn); generate_condition(data->arg2, data->slab, data->scode, data->sdata, data->flab, data->fcode, data->fdata, fn); }
void generate_if(component condition, component success, component failure, bool discard, fncode fn) { struct ifdata ifdata; ifdata.slab = new_label(fn); ifdata.flab = new_label(fn); ifdata.endlab = new_label(fn); ifdata.success = success; ifdata.failure = failure; ifdata.discard = discard; if (failure) generate_condition(condition, ifdata.slab, ifs_code, &ifdata, ifdata.flab, iff_code, &ifdata, fn); else generate_condition(condition, ifdata.slab, ifs_code, &ifdata, ifdata.endlab, NULL, NULL, fn); set_label(ifdata.endlab, fn); if (!discard) adjust_depth(1, fn); }
static void generate_if(component condition, component success, component failure, fncode fn) { struct ifdata ifdata; ifdata.slab = new_label(fn); ifdata.flab = new_label(fn); ifdata.endlab = new_label(fn); ifdata.success = success; ifdata.failure = failure; generate_condition(condition, ifdata.slab, ifs_code, &ifdata, ifdata.flab, iff_code, &ifdata, fn); set_label(ifdata.endlab, fn); adjust_depth(1, fn); }
static void generate_while(component condition, component iteration, fncode fn) { struct whiledata wdata; wdata.looplab = new_label(fn); wdata.mainlab = new_label(fn); wdata.exitlab = new_label(fn); wdata.endlab = new_label(fn); wdata.code = iteration; env_start_loop(); set_label(wdata.looplab, fn); generate_condition(condition, wdata.mainlab, wmain_code, &wdata, wdata.exitlab, wexit_code, &wdata, fn); set_label(wdata.endlab, fn); env_end_loop(); adjust_depth(1, fn); }
void generate_dowhile(component iteration, component condition, const char *continue_label, bool discard, fncode fn) { struct whiledata wdata; start_block(NULL, FALSE, discard, fn); wdata.continue_label = continue_label; wdata.looplab = new_label(fn); wdata.mainlab = new_label(fn); wdata.endlab = new_label(fn); wdata.code = iteration; wdata.next = NULL; loop_body(&wdata, fn); generate_condition(condition, wdata.mainlab, NULL, NULL, wdata.endlab, NULL, NULL, fn); set_label(wdata.endlab, fn); if (!discard) generate_component(component_undefined, NULL, FALSE, fn); end_block(fn); }