static SLVAL sl_string_replace(sl_vm_t* vm, SLVAL self, SLVAL search, SLVAL replace) { if(sl_is_a(vm, search, vm->lib.String)) { return sl_enumerable_join(vm, sl_string_split(vm, self, 1, &search), 1, &replace); } sl_expect(vm, search, vm->lib.Regexp); SLVAL retn = sl_make_cstring(vm, ""); while(1) { SLVAL match = sl_regexp_match(vm, search, 1, &self); if(!sl_is_truthy(match)) { return sl_string_concat(vm, retn, self); } else { SLVAL part = sl_regexp_match_before(vm, match); if(sl_is_a(vm, replace, vm->lib.String)) { part = sl_string_concat(vm, part, replace); } else { part = sl_string_concat(vm, part, sl_send_id(vm, replace, vm->id.call, 1, match)); } retn = sl_string_concat(vm, retn, part); } self = sl_regexp_match_after(vm, match); } }
static SLVAL range_enumerator_next(sl_vm_t* vm, SLVAL self) { sl_range_enumerator_t* range_enum = get_range_enumerator(vm, self); check_range_enumerator(vm, range_enum); if(range_enum->state == ES_DONE) { return vm->lib._false; } if(range_enum->state == ES_BEFORE) { range_enum->state = ES_ITERATING; } else { range_enum->current = sl_send_id(vm, range_enum->current, vm->id.succ, 0); } if(sl_is_truthy(sl_send_id(vm, range_enum->current, range_enum->method, 1, range_enum->right))) { return vm->lib._true; } else { range_enum->state = ES_DONE; return vm->lib._false; } }
static void output(sl_vm_t* sub_vm, char* buff, size_t len) { slash_t* sl = sub_vm->data; sl_vm_t* vm = sl->host_vm; if(sl_responds_to2(vm, sl->output_handler, vm->id.call)) { SLVAL ex; sl_vm_frame_t catch_frame; SL_TRY(catch_frame, SL_UNWIND_ALL, { SLVAL string = sl_make_string(vm, (uint8_t*)buff, len); sl_send_id(vm, sl->output_handler, vm->id.call, 1, string); }, ex, {