Пример #1
0
SLVAL
sl_string_char_at_index(sl_vm_t* vm, SLVAL self, SLVAL index)
{
    sl_string_t* str = sl_get_string(vm, self);
    if(sl_is_a(vm, index, vm->lib.Range_Inclusive) || sl_is_a(vm, index, vm->lib.Range_Exclusive)) {
        return string_range_index(vm, self, index);
    }
    long idx = sl_get_int(sl_expect(vm, index, vm->lib.Int));
    if(idx < 0) {
        idx += str->char_len;
    }
    if(idx < 0 || idx >= (long)str->char_len) {
        return vm->lib.nil;
    }
    uint8_t* buff_ptr = str->buff;
    size_t len = str->buff_len;
    while(idx) {
        sl_utf8_each_char(vm, &buff_ptr, &len);
        idx--;
    }
    size_t slice_len = 1;
    while(slice_len < len && (buff_ptr[slice_len] & 0xc0) == 0x80) {
        slice_len++;
    }
    return sl_make_string(vm, buff_ptr, slice_len);
}
Пример #2
0
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);
    }
}
Пример #3
0
SLVAL
sl_float_pow(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(sl_is_a(vm, other, vm->lib.Bignum)) {
        return sl_float_pow(vm, self, sl_bignum_to_f(vm, other));
    }
    if(sl_is_a(vm, other, vm->lib.Int)) {
        return sl_float_pow(vm, self, sl_make_float(vm, sl_get_int(other)));
    }
    return sl_make_float(vm, pow(sl_get_float(vm, self), sl_get_float(vm, other)));
}
Пример #4
0
static void
parse_query_string(sl_vm_t* vm, SLVAL dict, size_t len, uint8_t* query_string)
{
    uint8_t *key = query_string, *value = NULL;
    size_t key_len = 0, value_len = 0;
    size_t i;
    SLVAL addee = dict, k, v;
    int bracket_mode = 0, in_bracket = 0;
    for(i = 0; i <= len; i++) {
        if(i == len || query_string[i] == '&') {
            if(key_len > 0) {
                k = sl_string_url_decode(vm, sl_make_string(vm, key, key_len));
                if(value) {
                    v = sl_string_url_decode(vm, sl_make_string(vm, value, value_len));
                }
                sl_dict_set(vm, addee, k, value ? v : vm->lib.nil);
            }
            key = query_string + i + 1;
            key_len = 0;
            value = NULL;
            value_len = 0;
            addee = dict;
            in_bracket = 0;
            bracket_mode = 0;
            continue;
        }
        if(query_string[i] == '=' && !value) {
            value = query_string + i + 1;
            continue;
        }
        if(value) {
            value_len++;
        } else {
            if(query_string[i] == '[') {
                k = sl_make_string(vm, key, key_len);
                key = query_string + i + 1;
                key_len = 0;
                if(!sl_is_a(vm, sl_dict_get(vm, addee, k), vm->lib.Dict)) {
                    sl_dict_set(vm, addee, k, sl_make_dict(vm, 0, NULL));
                }
                addee = sl_dict_get(vm, addee, k);
                in_bracket = 1;
                bracket_mode = 1;
                continue;
            }
            if(query_string[i] == ']' && in_bracket) {
                in_bracket = 0;
                continue;
            }
            if(bracket_mode && !in_bracket) {
                /* skip until \0, & or = */
                while(i + 1 < len && query_string[i + 1] != '&' && query_string[i + 1] != '=') {
                    i++;
                }
                continue;
            }
            key_len++;
        }
    }
}
Пример #5
0
SLVAL
sl_float_cmp(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(sl_is_a(vm, other, vm->lib.Int)) {
        return sl_float_cmp(vm, self, sl_make_float(vm, sl_get_int(other)));
    }
    if(sl_is_a(vm, other, vm->lib.Bignum)) {
        return sl_make_int(vm, -sl_get_int(sl_bignum_cmp(vm, other, self)));
    }
    sl_expect(vm, other, vm->lib.Float);
    if(sl_get_float(vm, self) < sl_get_float(vm, other)) {
        return sl_make_int(vm, -1);
    } else if(sl_get_float(vm, self) > sl_get_float(vm, other)) {
        return sl_make_int(vm, 1);
    } else {
        return sl_make_int(vm, 0);
    }
}
Пример #6
0
SLVAL
sl_float_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(sl_is_a(vm, other, vm->lib.Int)) {
        return sl_float_eq(vm, self, sl_make_float(vm, sl_get_int(other)));
    }
    if(sl_is_a(vm, other, vm->lib.Bignum)) {
        if(fmod(sl_get_float(vm, self), 1.0) == 0.0) {
            return sl_bignum_eq(vm, sl_make_bignum_f(vm, sl_get_float(vm, self)), other);
        } else {
            return vm->lib._false;
        }
    }
    if(!sl_is_a(vm, other, vm->lib.Float)) {
        return vm->lib._false;
    }
    return sl_make_bool(vm, sl_get_float(vm, self) == sl_get_float(vm, other));
}
Пример #7
0
SLVAL
sl_string_is_match(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(sl_is_a(vm, other, vm->lib.String)) {
        SLVAL idx = sl_string_index(vm, self, other);
        return sl_make_bool(vm, sl_get_ptr(idx) != sl_get_ptr(vm->lib.nil));
    }
    return sl_regexp_is_match(vm, other, self);
}
Пример #8
0
static SLVAL
string_range_index(sl_vm_t* vm, SLVAL self, SLVAL range)
{
    sl_string_t* str = sl_get_string(vm, self);
    SLVAL lowerv = sl_range_lower(vm, range);
    SLVAL upperv = sl_range_upper(vm, range);
    if(!sl_is_a(vm, lowerv, vm->lib.Int) || !sl_is_a(vm, upperv, vm->lib.Int)) {
        sl_throw_message2(vm, vm->lib.TypeError, "Expected range of integers");
    }
    long lower = sl_get_int(lowerv), upper = sl_get_int(upperv);
    if(lower < 0) {
        lower += str->char_len;
    }
    if(lower < 0 || (size_t)lower >= str->char_len) {
        return sl_make_cstring(vm, "");
    }
    if(upper < 0) {
        upper += str->char_len;
    }
    if(upper < 0) {
        return sl_make_cstring(vm, "");
    }
    if(sl_range_is_exclusive(vm, range)) {
        upper--;
    }
    if(upper < lower) {
        return sl_make_cstring(vm, "");
    }
    uint8_t* begin_ptr = str->buff;
    uint8_t* end_ptr;
    size_t len = str->buff_len;
    long idx = 0;
    while(idx < lower && len) {
        idx++;
        sl_utf8_each_char(vm, &begin_ptr, &len);
    }
    end_ptr = begin_ptr;
    while(lower <= upper) {
        lower++;
        sl_utf8_each_char(vm, &end_ptr, &len);
    }
    return sl_make_string(vm, begin_ptr, (size_t)end_ptr - (size_t)begin_ptr);
}
Пример #9
0
SLVAL
sl_string_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(!sl_is_a(vm, other, vm->lib.String)) {
        return vm->lib._false;
    }
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    return sl_make_bool(vm, str_cmp(vm, a, b) == 0);
}
Пример #10
0
static SLVAL
vm_helper_define_singleton_method(sl_vm_exec_ctx_t* ctx, SLVAL on, SLID name, sl_vm_section_t* section)
{
    SLVAL klass = on, method;
    if(!sl_is_a(ctx->vm, klass, ctx->vm->lib.Class)) {
        klass = sl_class_of(ctx->vm, klass);
    }
    method = sl_make_method(ctx->vm, klass, name, section, ctx);
    sl_define_singleton_method3(ctx->vm, on, name, method);
    return method;
}
Пример #11
0
static int
cap_index(sl_vm_t* vm, SLVAL regexp_match, SLVAL i)
{
    sl_regexp_match_t* match = get_regexp_match(vm, regexp_match);
    int index;
    if(sl_is_a(vm, i, vm->lib.String)) {
        char* named_cap = sl_to_cstr(vm, i);
        index = pcre_get_stringnumber(match->re->re, named_cap);
        if(index < 0) {
            return -1;
        }
    } else {
        index = sl_get_int(sl_expect(vm, i, vm->lib.Int));
    }
    if(index < 0 || index >= match->capture_count) {
        return -1;
    }
    return index * 2;
}
Пример #12
0
static SLVAL
sl_regexp_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(!sl_is_a(vm, other, vm->lib.Regexp)) {
        return vm->lib._false;
    }
    sl_regexp_t* re = get_regexp(vm, self);
    sl_regexp_t* oth = get_regexp(vm, other);
    if(!oth->re || !re->re) {
        return vm->lib._false;
    }
    if(!sl_is_truthy(sl_string_eq(vm, re->source, oth->source))) {
        return vm->lib._false;
    }
    if(re->options != oth->options) {
        return vm->lib._false;
    }
    return vm->lib._true;
}
Пример #13
0
void
sl_request_set_opts(sl_vm_t* vm, sl_request_opts_t* opts)
{
    size_t i;
    SLVAL n, v, cookies;
    sl_string_t* str;
    sl_request_internal_opts_t* req = sl_alloc(vm->arena, sizeof(sl_request_internal_opts_t));
    req->method       = sl_make_cstring(vm, opts->method);
    req->uri          = sl_make_cstring(vm, opts->uri);
    req->path_info    = sl_make_cstring(vm, opts->path_info ? opts->path_info : "");
    req->query_string = sl_make_cstring(vm, opts->query_string ? opts->query_string : "");
    req->remote_addr  = sl_make_cstring(vm, opts->remote_addr);
    req->headers      = sl_make_dict(vm, 0, NULL);
    req->env          = sl_make_dict(vm, 0, NULL);
    req->get          = sl_make_dict(vm, 0, NULL);
    req->post         = sl_make_dict(vm, 0, NULL);
    req->post_data    = sl_make_string(vm, (uint8_t*)opts->post_data, opts->post_length);
    req->cookies      = sl_make_dict(vm, 0, NULL);
    for(i = 0; i < opts->header_count; i++) {
        n = sl_make_cstring(vm, opts->headers[i].name);
        v = sl_make_cstring(vm, opts->headers[i].value);
        sl_dict_set(vm, req->headers, n, v);
    }
    for(i = 0; i < opts->env_count; i++) {
        n = sl_make_cstring(vm, opts->env[i].name);
        v = sl_make_cstring(vm, opts->env[i].value);
        sl_dict_set(vm, req->env, n, v);
    }
    if(opts->query_string) {
        parse_query_string(vm, req->get, strlen(opts->query_string), (uint8_t*)opts->query_string);
    }
    if(opts->content_type && strcmp(opts->content_type, "application/x-www-form-urlencoded") == 0) {
        parse_query_string(vm, req->post, opts->post_length, (uint8_t*)opts->post_data);
    }
    cookies = sl_dict_get(vm, req->headers, sl_make_cstring(vm, "Cookie"));
    if(sl_is_a(vm, cookies, vm->lib.String)) {
        str = (sl_string_t*)sl_get_ptr(cookies);
        parse_cookie_string(vm, req->cookies, str->buff_len, str->buff);
    }
    req->params = sl_dict_merge(vm, req->get, req->post);
    sl_vm_store_put(vm, &Request_opts, sl_make_ptr((sl_object_t*)req));
}
Пример #14
0
SLVAL
sl_string_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(!sl_is_a(vm, other, vm->lib.String)) {
        return vm->lib._false;
    }
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    if(a->encoding == b->encoding) {
        if(str_cmp((sl_string_t*)sl_get_ptr(self), (sl_string_t*)sl_get_ptr(other)) == 0) {
            return vm->lib._true;
        } else {
            return vm->lib._false;
        }
    }
    sl_vm_frame_t frame;
    SLVAL err;
    volatile SLVAL retn;
    SL_TRY(frame, SL_UNWIND_EXCEPTION, {
        retn = sl_string_eq(vm, self, sl_string_encode(vm, other, a->encoding));
    }, err, {
Пример #15
0
static SLVAL
vm_helper_define_class(sl_vm_exec_ctx_t* ctx, SLID name, SLVAL extends, sl_vm_section_t* section)
{
    SLVAL klass, in;
    sl_vm_exec_ctx_t* subctx;
    if(sl_class_has_const2(ctx->vm, ctx->self, name)) {
        /* @TODO: verify same superclass */
        klass = sl_class_get_const2(ctx->vm, ctx->self, name);
    } else {
        in = ctx->self;
        if(!sl_is_a(ctx->vm, in, ctx->vm->lib.Class)) {
            in = sl_class_of(ctx->vm, in);
        }
        klass = sl_define_class3(ctx->vm, name, extends, in);
    }
    subctx = sl_alloc(ctx->vm->arena, sizeof(sl_vm_exec_ctx_t));
    subctx->vm = ctx->vm;
    subctx->section = section;
    subctx->registers = sl_alloc(ctx->vm->arena, sizeof(SLVAL) * section->max_registers);
    subctx->self = klass;
    subctx->parent = ctx;
    sl_vm_exec(subctx, 0);
    return klass;
}
Пример #16
0
Файл: true.c Проект: Hmaal/slash
static SLVAL
true_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    (void)self;
    return sl_make_bool(vm, sl_is_a(vm, other, vm->lib.True));
}