void sl_init_string(sl_vm_t* vm) { sl_st_insert(((sl_class_t*)sl_get_ptr(vm->lib.Object))->constants, (sl_st_data_t)sl_intern(vm, "String").id, (sl_st_data_t)vm->lib.String.i); sl_define_method(vm, vm->lib.String, "length", 0, sl_string_length); sl_define_method(vm, vm->lib.String, "byte_length", 0, sl_string_byte_length); sl_define_method(vm, vm->lib.String, "concat", 1, sl_string_concat); sl_define_method(vm, vm->lib.String, "+", 1, sl_string_concat); sl_define_method(vm, vm->lib.String, "*", 1, sl_string_times); sl_define_method(vm, vm->lib.String, "to_s", 0, sl_string_to_s); sl_define_method(vm, vm->lib.String, "to_i", 0, sl_string_to_i); sl_define_method(vm, vm->lib.String, "to_f", 0, sl_string_to_f); sl_define_method(vm, vm->lib.String, "inspect", 0, sl_string_inspect); sl_define_method(vm, vm->lib.String, "html_escape", 0, sl_string_html_escape); sl_define_method(vm, vm->lib.String, "url_decode", 0, sl_string_url_decode); sl_define_method(vm, vm->lib.String, "url_encode", 0, sl_string_url_encode); sl_define_method(vm, vm->lib.String, "index", 1, sl_string_index); sl_define_method(vm, vm->lib.String, "[]", 1, sl_string_char_at_index); sl_define_method(vm, vm->lib.String, "split", -2, sl_string_split); sl_define_method(vm, vm->lib.String, "==", 1, sl_string_eq); sl_define_method(vm, vm->lib.String, "~", 1, sl_string_is_match); sl_define_method(vm, vm->lib.String, "<=>", 1, sl_string_spaceship); sl_define_method(vm, vm->lib.String, "hash", 0, sl_string_hash); sl_define_method(vm, vm->lib.String, "encode", 1, sl_string_encode2); sl_define_method(vm, vm->lib.String, "replace", 2, sl_string_replace); sl_define_method(vm, vm->lib.String, "upper", 0, sl_string_upper); sl_define_method(vm, vm->lib.String, "lower", 0, sl_string_lower); }
NODE(sl_node_def_t, def) { sl_compile_state_t sub_cs; size_t i, on_reg; size_t init_regs = 1 + node->req_arg_count + node->opt_arg_count; if(node->rest_arg) { init_regs++; } init_compile_state(&sub_cs, cs->vm, cs, init_regs); for(i = 0; i < node->req_arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->req_args[i], (sl_st_data_t)(i + 1)); } for(i = 0; i < node->opt_arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->opt_args[i].name, (sl_st_data_t)(node->req_arg_count + i + 1)); } if(node->rest_arg) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->rest_arg, (sl_st_data_t)(node->req_arg_count + node->opt_arg_count + 1)); sub_cs.section->has_extra_rest_arg = 1; } sub_cs.section->name = node->name; sub_cs.section->req_registers = node->req_arg_count; sub_cs.section->arg_registers = node->req_arg_count + node->opt_arg_count; sub_cs.section->opt_skip = sl_alloc(cs->vm->arena, sizeof(size_t) * (node->opt_arg_count + 1)); for(i = 0; i < node->opt_arg_count; i++) { sub_cs.section->opt_skip[i] = sub_cs.section->insns_count; compile_node(&sub_cs, node->opt_args[i].default_value, node->req_arg_count + i + 1); } sub_cs.section->opt_skip[node->opt_arg_count] = sub_cs.section->insns_count; compile_node(&sub_cs, node->body, 0); op_return(&sub_cs, 0); if(node->on) { on_reg = reg_alloc(cs); compile_node(cs, node->on, on_reg); op_define_on(cs, on_reg, node->name, node->doc, sub_cs.section, dest); reg_free(cs, on_reg); } else { op_define(cs, node->name, node->doc, sub_cs.section, dest); } }
NODE(sl_node_lambda_t, lambda) { sl_compile_state_t sub_cs; size_t i; init_compile_state(&sub_cs, cs->vm, cs, node->arg_count + 1); for(i = 0; i < node->arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->args[i], (sl_st_data_t)(i + 1)); } sub_cs.section->req_registers = node->arg_count; sub_cs.section->arg_registers = node->arg_count; sub_cs.section->name = sl_intern(cs->vm, "<lambda>"); compile_node(&sub_cs, node->body, 0); op_return(&sub_cs, 0); op_lambda(cs, sub_cs.section, dest); }
static SLID sl_intern2_no_check(sl_vm_t* vm, SLVAL str) { SLID id; if(sl_st_lookup(vm->intern.name_to_id, (sl_st_data_t)sl_get_ptr(str), (sl_st_data_t*)&id)) { return id; } id.id = vm->intern.id_to_name_size++; sl_st_insert(vm->intern.name_to_id, (sl_st_data_t)sl_get_ptr(str), (sl_st_data_t)id.id); if(vm->intern.id_to_name_size >= vm->intern.id_to_name_cap) { vm->intern.id_to_name_cap *= 2; vm->intern.id_to_name = sl_realloc(vm->arena, vm->intern.id_to_name, sizeof(SLVAL) * vm->intern.id_to_name_cap); } vm->intern.id_to_name[id.id] = str; return id; }