bool term_is_observable_after(Term* term, Term* location) { // Check if "term" can be observed after the "location". // // Typically, "location" uses "term" as an input, and we're trying to decide // whether the call at "location" can move/consume the value. if (term_is_observable_for_special_reasons(term)) return true; for (int i=0; i < user_count(term); i++) { Term* user = term_user(term, i); if (user->function == FUNCS.upvalue) return true; if (terms_are_in_different_switch_conditions(location, user)) continue; if (term_accesses_input_from_inside_loop(user, term)) { bool userOnlyAccessesOnFirstIteration = is_input_placeholder(user) && user->numInputs() == 2 && user->input(1) != term; if (!userOnlyAccessesOnFirstIteration) return true; } if (is_located_after(user, location)) return true; } return false; }
void write_block_contents(SourceWriter* writer, Block* block) { for (int i=0; i < block->length(); i++) { Term* term = block->get(i); if (is_input_placeholder(term) || is_output_placeholder(term)) continue; write_term(writer, term); } }
void Branch__get_documentation(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); caValue* out = circa_output(stack, 0); set_list(out, 0); for (int i=0; i < branch->length(); i++) { Term* term = branch->get(i); if (is_input_placeholder(term)) continue; if (is_comment(term)) set_string(list_append(out), term->stringProp("comment")); } }
void Term__is_input(VM* vm) { Term* t = as_term_ref(vm->input(0)); set_bool(vm->output(), t != NULL && is_input_placeholder(t)); }