void List__slice(caStack* stack) { caValue* input = circa_input(stack, 0); int start = circa_int_input(stack, 1); int end = circa_int_input(stack, 2); caValue* output = circa_output(stack, 0); if (start < 0) start = 0; else if (start > list_length(input)) start = list_length(input); if (end > list_length(input)) end = list_length(input); else if (end < 0) end = list_length(input) + end; if (end < start) { set_list(output, 0); return; } int length = end - start; set_list(output, length); for (int i=0; i < length; i++) copy(list_get(input, start + i), list_get(output, i)); }
void mod_i(caStack* stack) { int a = circa_int_input(stack, 0); int n = circa_int_input(stack, 1); int out = a % n; if (out < 0) out += n; set_int(circa_output(stack, 0), out); }
void List__insert(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); copy(circa_input(stack, 1), list_insert(out, circa_int_input(stack, 2))); }
void List__resize(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); int count = circa_int_input(stack, 1); circa_resize(out, count); }
void Branch__get_term(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); int index = circa_int_input(stack, 1); set_term_ref(circa_output(stack, 0), branch->get(index)); }
void empty_list(caStack* stack) { caValue* out = circa_output(stack, 0); int size = circa_int_input(stack, 1); caValue* initialValue = circa_input(stack, 0); set_list(out, size); for (int i=0; i < size; i++) { copy(initialValue, list_get(out, i)); } }
void List__set(caStack* stack) { caValue* self = circa_output(stack, 0); copy(circa_input(stack, 0), self); int index = circa_int_input(stack, 1); caValue* value = circa_input(stack, 2); touch(self); copy(value, list_get(self, index)); }
void String__substr(caStack* stack) { int start = circa_int_input(stack, 1); int end = circa_int_input(stack, 2); std::string const& s = as_string(circa_input(stack, 0)); if (start < 0) return circa_output_error(stack, "Negative index"); if (end < 0) return circa_output_error(stack, "Negative index"); if ((unsigned) start > s.length()) { std::stringstream msg; msg << "Start index is too high: " << start; return circa_output_error(stack, msg.str().c_str()); } if ((unsigned) (start+end) > s.length()) { std::stringstream msg; msg << "End index is too high: " << start; return circa_output_error(stack, msg.str().c_str()); } set_string(circa_output(stack, 0), s.substr(start, end)); }
void Term__input(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } int index = circa_int_input(stack, 1); if (index >= t->numInputs()) set_term_ref(circa_output(stack, 0), NULL); else set_term_ref(circa_output(stack, 0), t->input(index)); }
void String__slice(caStack* stack) { int start = circa_int_input(stack, 1); int end = circa_int_input(stack, 2); std::string const& s = as_string(circa_input(stack, 0)); // Negative indexes are relatve to end of string if (start < 0) start = (int) s.length() + start; if (end < 0) end = (int) s.length() + end; if (start < 0) return set_string(circa_output(stack, 0), ""); if (end < 0) return set_string(circa_output(stack, 0), ""); if ((unsigned) start > s.length()) start = (int) s.length(); if ((unsigned) end > s.length()) end = (int) s.length(); if (end < start) return set_string(circa_output(stack, 0), ""); set_string(circa_output(stack, 0), s.substr(start, end - start)); }
void String__char_at(caStack* stack) { const char* str = circa_string_input(stack, 0); int index = circa_int_input(stack, 1); if (index < 0) { circa_output_error(stack, "negative index"); return; } if ((unsigned) index >= strlen(str)) { set_string(circa_output(stack, 0), ""); return; } char output[1]; output[0] = str[index]; set_string(circa_output(stack, 0), output, 1); }
void hosted_get_index(caStack* stack) { caValue* list = circa_input(stack, 0); int index = circa_int_input(stack, 1); if (index < 0) { char indexStr[40]; sprintf(indexStr, "Negative index: %d", index); return circa_output_error(stack, indexStr); } else if (index >= list_length(list)) { char indexStr[40]; sprintf(indexStr, "Index out of range: %d", index); return circa_output_error(stack, indexStr); } caValue* result = get_index(list, index); copy(result, circa_output(stack, 0)); cast(circa_output(stack, 0), declared_type((Term*) circa_caller_term(stack))); }
void Branch__input(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); set_term_ref(circa_output(stack, 0), get_input_placeholder(branch, circa_int_input(stack, 1))); }
void remainder_i(caStack* stack) { set_int(circa_output(stack, 0), circa_int_input(stack, 0) % circa_int_input(stack, 1)); }
void min_i(caStack* stack) { set_int(circa_output(stack, 0), std::min(circa_int_input(stack, 0), circa_int_input(stack, 1))); }
void pow(caStack* stack) { set_int(circa_output(stack, 0), (int) std::pow((float) circa_int_input(stack, 0), circa_int_input(stack, 1))); }