Example #1
0
static int
own_instance_methods_iter(sl_vm_t* vm, SLID name, SLVAL method, SLVAL ary)
{
    if(sl_get_primitive_type(method) != SL_T_CACHED_METHOD_ENTRY) {
        SLVAL namev = sl_id_to_string(vm, name);
        sl_array_push(vm, ary, 1, &namev);
    }
    return SL_ST_CONTINUE;
}
Example #2
0
static SLVAL
sl_class_instance_method(sl_vm_t* vm, SLVAL self, SLVAL method_name)
{
    sl_class_t* klass = get_class(vm, self);
    SLVAL method;
    method_name = sl_to_s(vm, method_name);
    if(st_lookup(klass->instance_methods, (st_data_t)sl_get_ptr(method_name), (st_data_t*)&method)) {
        return method;
    } else if(sl_get_primitive_type(klass->super) == SL_T_CLASS) {
        return sl_class_instance_method(vm, klass->super, method_name);
    }
    return vm->lib.nil;
}
Example #3
0
static SLVAL
sl_class_instance_method(sl_vm_t* vm, SLVAL self, SLVAL method_name)
{
    sl_class_t* klass = get_class(vm, self);
    SLVAL method;
    SLID mid = sl_intern2(vm, method_name);
    method_name = sl_to_s(vm, method_name);
    if(sl_st_lookup(klass->instance_methods, (sl_st_data_t)mid.id, (sl_st_data_t*)&method)) {
        if(sl_get_primitive_type(method) == SL_T_CACHED_METHOD_ENTRY) {
            sl_cached_method_entry_t* cme = (void*)sl_get_ptr(method);
            // TODO - improve cache invalidation. this is too coarse
            if(cme->state == vm->state_method) {
                return sl_make_ptr((sl_object_t*)cme->method);
            }
        } else {
            return method;
        }
    }
    if(sl_get_primitive_type(klass->super) == SL_T_CLASS) {
        return sl_class_instance_method(vm, klass->super, method_name);
    }
    return vm->lib.nil;
}
Example #4
0
static SLVAL
sl_class_own_instance_method(sl_vm_t* vm, SLVAL self, SLVAL method_name)
{
    sl_class_t* klass = get_class(vm, self);
    SLVAL method;
    SLID mid = sl_intern2(vm, method_name);
    method_name = sl_to_s(vm, method_name);
    if(sl_st_lookup(klass->instance_methods, (sl_st_data_t)mid.id, (sl_st_data_t*)&method)) {
        if(sl_get_primitive_type(method) != SL_T_CACHED_METHOD_ENTRY) {
            return method;
        }
    }
    return vm->lib.nil;
}
Example #5
0
File: json.c Project: Hmaal/slash
static void
json_dump(json_dump_t* state, SLVAL object)
{
    sl_string_t* str;
    size_t i, len;
    SLVAL* keys;
    switch(sl_get_primitive_type(object)) {
        case SL_T_NIL:
            JSON_DUMP_NEED_BYTES(4);
            memcpy(state->buffer + state->buffer_len, "null", 4);
            state->buffer_len += 4;
            break;
        case SL_T_TRUE:
            JSON_DUMP_NEED_BYTES(4);
            memcpy(state->buffer + state->buffer_len, "true", 4);
            state->buffer_len += 4;
            break;
        case SL_T_FALSE:
            JSON_DUMP_NEED_BYTES(5);
            memcpy(state->buffer + state->buffer_len, "false", 5);
            state->buffer_len += 5;
            break;
        case SL_T_INT:
            str = (sl_string_t*)sl_get_ptr(sl_int_to_s(state->vm, object));
            JSON_DUMP_NEED_BYTES(str->buff_len);
            memcpy(state->buffer + state->buffer_len, str->buff, str->buff_len);
            state->buffer_len += str->buff_len;
            break;
        case SL_T_FLOAT:
            str = (sl_string_t*)sl_get_ptr(sl_float_to_s(state->vm, object));
            JSON_DUMP_NEED_BYTES(str->buff_len);
            memcpy(state->buffer + state->buffer_len, str->buff, str->buff_len);
            state->buffer_len += str->buff_len;
            break;
        case SL_T_BIGNUM:
            str = (sl_string_t*)sl_get_ptr(sl_bignum_to_s(state->vm, object));
            JSON_DUMP_NEED_BYTES(str->buff_len);
            memcpy(state->buffer + state->buffer_len, str->buff, str->buff_len);
            state->buffer_len += str->buff_len;
            break;
        case SL_T_STRING:
            str = (sl_string_t*)sl_get_ptr(sl_string_inspect(state->vm, object));
            JSON_DUMP_NEED_BYTES(str->buff_len);
            memcpy(state->buffer + state->buffer_len, str->buff, str->buff_len);
            state->buffer_len += str->buff_len;
            break;
        case SL_T_ARRAY:
            JSON_CHECK_RECURSION(object);
            JSON_DUMP_NEED_BYTES(1);
            state->buffer[state->buffer_len++] = '[';
            len = sl_get_int(sl_array_length(state->vm, object));
            for(i = 0; i < len; i++) {
                if(i) {
                    JSON_DUMP_NEED_BYTES(1);
                    state->buffer[state->buffer_len++] = ',';
                }
                json_dump(state, sl_array_get(state->vm, object, i));
            }
            JSON_DUMP_NEED_BYTES(1);
            state->buffer[state->buffer_len++] = ']';
            JSON_END_CHECK_RECURSION();
            break;
        case SL_T_DICT:
            JSON_CHECK_RECURSION(object);
            JSON_DUMP_NEED_BYTES(1);
            state->buffer[state->buffer_len++] = '{';
            keys = sl_dict_keys(state->vm, object, &len);
            for(i = 0; i < len; i++) {
                if(i) {
                    JSON_DUMP_NEED_BYTES(1);
                    state->buffer[state->buffer_len++] = ',';
                }
                json_dump(state, sl_to_s(state->vm, keys[i]));
                JSON_DUMP_NEED_BYTES(1);
                state->buffer[state->buffer_len++] = ':';
                json_dump(state, sl_dict_get(state->vm, object, keys[i]));
            }
            JSON_DUMP_NEED_BYTES(1);
            state->buffer[state->buffer_len++] = '}';
            JSON_END_CHECK_RECURSION();
            break;
        default:
            if(!sl_responds_to(state->vm, object, "to_json")) {
                SLVAL DumpError = state->vm->store[cJSON_DumpError];
                sl_error(state->vm, DumpError, "Can't convert type %V to JSON. You can implement #to_json to fix this.", sl_class_of(state->vm, object));
            }
            str = (sl_string_t*)sl_get_ptr(sl_to_s(state->vm, sl_send(state->vm, object, "to_json", 0, NULL)));
            JSON_DUMP_NEED_BYTES(str->buff_len);
            memcpy(state->buffer + state->buffer_len, str->buff, str->buff_len);
            state->buffer_len += str->buff_len;
            break;
    }
}
Example #6
0
File: string.c Project: richo/slash
// somewhat similar to sprintf
//
// Valid formats:
//
//   %V - Slash value, converted to string first with #to_s
//   %I - Slash ID
//   %s - C string
//   %d - integer
//   %% - literal '%' sign
//
// You may add the 'Q' modifier to a format specifier to quote it in double
// quotes. For example "%QV" would quote the value when interpolating it into
// the string
SLVAL
sl_make_formatted_string_va(struct sl_vm* vm, const char* format, va_list va)
{
    SLVAL strings = sl_make_array(vm, 0, NULL);
    const char *current_ptr = format, *next_ptr;
    SLVAL quote = vm->lib.nil;
    while((next_ptr = strchr(current_ptr, '%'))) {
        if(next_ptr != current_ptr) {
            SLVAL literal = sl_make_string(vm, (uint8_t*)current_ptr, (size_t)(next_ptr - current_ptr));
            sl_array_push(vm, strings, 1, &literal);
        }
        SLVAL element = vm->lib.nil;
        bool quoted = false;
    again:
        switch(next_ptr[1]) {
            case 'Q': {
                if(sl_get_primitive_type(quote) == SL_T_NIL) {
                    quote = sl_make_cstring(vm, "\"");
                }
                sl_array_push(vm, strings, 1, &quote);
                next_ptr++;
                quoted = true;
                goto again;
            }
            case 'V': {
                element = va_arg(va, SLVAL);
                break;
            }
            case 'X': {
                element = va_arg(va, SLVAL);
                element = sl_inspect(vm, element);
                break;
            }
            case 'I': {
                SLID id = va_arg(va, SLID);
                element = sl_id_to_string(vm, id);
                break;
            }
            case 's': {
                char* cstr = va_arg(va, char*);
                element = sl_make_cstring(vm, cstr);
                break;
            }
            case 'd': {
                char buff[32];
                int num = va_arg(va, int);
                sprintf(buff, "%d", num);
                element = sl_make_cstring(vm, buff);
                break;
            }
            case 'p': {
                char buff[32];
                void* ptr = va_arg(va, void*);
                sprintf(buff, "%p", ptr);
                element = sl_make_cstring(vm, buff);
                break;
            }
            case 0: {
                return vm->lib.nil;
            }
            default: {
                element = sl_make_string(vm, (uint8_t*)(next_ptr + 1), 1);
                break;
            }
        }
        sl_array_push(vm, strings, 1, &element);

        if(quoted) {
            sl_array_push(vm, strings, 1, &quote);
            quoted = false;
        }

        current_ptr = next_ptr + 2;
    }
    if(current_ptr[0]) {
        SLVAL element = sl_make_cstring(vm, current_ptr);
        sl_array_push(vm, strings, 1, &element);
    }

    return sl_array_join(vm, strings, 0, NULL);
}