Пример #1
0
SLVAL
sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_regexp_t* re = get_regexp_check(vm, self);
    sl_string_t* str = sl_get_string(vm, argv[0]);
    int offset = 0, rc, ncaps;
    int* caps;
    sl_regexp_match_t* match;
    if(argc > 1) {
        offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int));
    }
    offset = sl_string_byte_offset_for_index(vm, argv[0], offset);
    if(offset < 0) {
        return vm->lib.nil;
    }
    pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps);
    ncaps += 1;
    ncaps *= 3;
    caps = sl_alloc(vm->arena, sizeof(int) * ncaps);
    rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps);
    if(rc == PCRE_ERROR_NOMATCH) {
        return vm->lib.nil;
    }
    check_pcre_error(vm, rc);
    match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match));
    match->re = re;
    match->match_string = argv[0];
    match->capture_count = ncaps / 3;
    match->captures = caps;
    return sl_make_ptr((sl_object_t*)match);
}
Пример #2
0
void
sl_pre_init_class(sl_vm_t* vm)
{
    sl_class_t* obj = (sl_class_t*)allocate_class(vm);
    vm->lib.Class = sl_make_ptr((sl_object_t*)obj);
    obj->extra->allocator = allocate_class;
    obj->base.klass = vm->lib.Class;
}
Пример #3
0
static SLVAL
range_enumerate(sl_vm_t* vm, SLVAL self)
{
    sl_range_t* range = get_range(vm, self);
    sl_range_enumerator_t* range_enum = get_range_enumerator(vm, sl_allocate(vm, vm->lib.Range_Enumerator));
    range_enum->current     = range->left;
    range_enum->right       = range->right;
    range_enum->method      = range->exclusive ? vm->id.op_lt : vm->id.op_lte;
    range_enum->state       = ES_BEFORE;
    return sl_make_ptr((sl_object_t*)range_enum);
}
Пример #4
0
SLVAL
sl_method_bind(sl_vm_t* vm, SLVAL method, SLVAL receiver)
{
    sl_method_t* methp = (sl_method_t*)sl_get_ptr(method);
    if(!(methp->base.user_flags & SL_FLAG_METHOD_INITIALIZED)) {
        sl_throw_message2(vm, vm->lib.TypeError, "Can't bind uninitialized Method");
    }
    sl_method_t* bmethp = method_dup(vm, methp);
    bmethp->extra->bound_self = sl_expect(vm, receiver, methp->extra->klass);
    bmethp->base.klass = vm->lib.BoundMethod;
    return sl_make_ptr((sl_object_t*)bmethp);
}
Пример #5
0
static sl_node_base_t*
call_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* left = primary_expression(ps);
    sl_node_base_t** nodes;
    size_t node_len;
    size_t node_cap;
    sl_token_t* tok;
    if(left->type == SL_NODE_VAR && peek_token(ps)->type == SL_TOK_OPEN_PAREN) {
        left = send_with_args_expression(ps, sl_make_self_node(ps),
            sl_intern2(ps->vm, sl_make_ptr((sl_object_t*)((sl_node_var_t*)left)->name)));
    }
    while(1) {
        tok = peek_token(ps);
        switch(tok->type) {
            case SL_TOK_DOT:
                next_token(ps);
                left = send_expression(ps, left);
                break;
            case SL_TOK_COLON:
                next_token(ps);
                left = sl_make_bind_method_node(ps, left, def_expression_method_name(ps));
                break;
            case SL_TOK_PAAMAYIM_NEKUDOTAYIM:
                next_token(ps);
                tok = expect_token(ps, SL_TOK_CONSTANT);
                left = sl_make_const_node(ps, left,
                    sl_intern2(ps->vm,
                        sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)));
                break;
            case SL_TOK_OPEN_BRACKET:
                next_token(ps);
                node_cap = 1;
                node_len = 0;
                nodes = sl_alloc(ps->vm->arena, sizeof(SLVAL) * node_cap);
                while(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                    if(node_len >= node_cap) {
                        node_cap *= 2;
                        nodes = sl_realloc(ps->vm->arena, nodes, sizeof(SLVAL) * node_cap);
                    }
                    nodes[node_len++] = expression(ps);
                    if(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                        expect_token(ps, SL_TOK_COMMA);
                    }
                }
                expect_token(ps, SL_TOK_CLOSE_BRACKET);
                left = sl_make_send_node(ps, left, sl_intern(ps->vm, "[]"), node_len, nodes);
                break;
            default:
                return left;
        }
    }
}
Пример #6
0
static SLVAL
bound_method_unbind(sl_vm_t* vm, SLVAL bmethod)
{
    sl_method_t* bmethp = (sl_method_t*)sl_get_ptr(bmethod);
    if(!(bmethp->base.user_flags & SL_FLAG_METHOD_INITIALIZED)) {
        sl_throw_message2(vm, vm->lib.TypeError, "Can't unbind uninitalized BoundMethod");
    }
    sl_method_t* methp = method_dup(vm, bmethp);
    methp->extra->bound_self = vm->lib.nil;
    methp->base.klass = vm->lib.Method;
    return sl_make_ptr((sl_object_t*)methp);
}
Пример #7
0
static SLVAL
bound_method_unbind(sl_vm_t* vm, SLVAL bmethod)
{
    sl_bound_method_t* bmethp = (sl_bound_method_t*)sl_get_ptr(bmethod);
    sl_method_t* methp = (sl_method_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Method));
    methp->name         = bmethp->method.name;
    methp->is_c_func    = bmethp->method.is_c_func;
    methp->arity        = bmethp->method.arity;
    methp->klass        = bmethp->method.klass;
    methp->as           = bmethp->method.as;
    methp->initialized  = 1;
    return sl_make_ptr((sl_object_t*)methp);
}
Пример #8
0
void
sl_response_set_opts(sl_vm_t* vm, sl_response_opts_t* opts)
{
    sl_response_internal_opts_t* iopts = sl_alloc(vm->arena, sizeof(sl_response_internal_opts_t));
    iopts->status        = 200;
    iopts->buffered      = opts->buffered;
    iopts->output_cap    = 4;
    iopts->output_len    = 0;
    iopts->output        = sl_alloc(vm->arena, sizeof(SLVAL) * iopts->output_cap);
    iopts->write         = opts->write;
    iopts->header_cap    = 2;
    iopts->header_count  = 0;
    iopts->headers       = sl_alloc(vm->arena, sizeof(sl_response_key_value_t) * iopts->header_cap);
    iopts->descriptive_error_pages = opts->descriptive_error_pages;
    sl_vm_store_put(vm, &Response_opts, sl_make_ptr((sl_object_t*)iopts));
}
Пример #9
0
void
sl_pre_init_class(sl_vm_t* vm)
{
    sl_class_t* obj = sl_alloc(vm->arena, sizeof(sl_class_t));
    vm->lib.Class = sl_make_ptr((sl_object_t*)obj);
    obj->name.id = 0;
    obj->super = vm->lib.Object;
    obj->in = vm->lib.Object;
    obj->constants = sl_st_init_table(vm, &sl_id_hash_type);
    obj->class_variables = sl_st_init_table(vm, &sl_id_hash_type);
    obj->instance_methods = sl_st_init_table(vm, &sl_id_hash_type);
    obj->allocator = allocate_class;
    obj->base.klass = vm->lib.Class;
    obj->base.primitive_type = SL_T_CLASS;
    obj->base.instance_variables = sl_st_init_table(vm, &sl_id_hash_type);
}
Пример #10
0
SLVAL
sl_string_times(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* str = sl_get_string(vm, self);
    long mul = sl_get_int(sl_expect(vm, other, vm->lib.Int));
    if(mul && (size_t)LONG_MAX / mul < str->buff_len) {
        sl_throw_message2(vm, vm->lib.ArgumentError, "String multiplier is too big");
    }
    sl_string_t* new_str = sl_get_string(vm, sl_make_string(vm, NULL, 0));
    new_str->buff_len = str->buff_len * mul;
    new_str->buff = sl_alloc(vm->arena, new_str->buff_len);
    for(size_t i = 0; i < new_str->buff_len; i += str->buff_len) {
        memcpy(new_str->buff + i, str->buff, str->buff_len);
    }
    new_str->char_len = str->char_len * mul;
    return sl_make_ptr((sl_object_t*)new_str);
}
Пример #11
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));
}
Пример #12
0
SLVAL
sl_method_bind(sl_vm_t* vm, SLVAL method, SLVAL receiver)
{
    sl_method_t* methp = (sl_method_t*)sl_get_ptr(method);
    sl_bound_method_t* bmethp = (sl_bound_method_t*)sl_get_ptr(sl_allocate(vm, vm->lib.BoundMethod));
    
    if(!methp->initialized) {
        sl_throw_message2(vm, vm->lib.TypeError, "Can't bind uninitialized Method");
    }
    
    bmethp->method.initialized  = 1;
    bmethp->method.name         = methp->name;
    bmethp->method.klass        = methp->klass;
    bmethp->method.is_c_func    = methp->is_c_func;
    bmethp->method.arity        = methp->arity;
    bmethp->method.as           = methp->as;
    
    bmethp->self = sl_expect(vm, receiver, methp->klass);
    return sl_make_ptr((sl_object_t*)bmethp);
}
Пример #13
0
SLVAL
sl_string_lower(sl_vm_t* vm, SLVAL selfv)
{
    sl_string_t* self = sl_get_string(vm, selfv);
    sl_string_t* retn = sl_get_string(vm, sl_allocate(vm, vm->lib.String));
    memcpy(retn, self, sizeof(sl_string_t));
    retn->buff = sl_alloc_buffer(vm->arena, retn->buff_len);

    size_t len = self->buff_len;
    uint8_t* buff = self->buff;
    size_t out_offset = 0;
    uint32_t lower_c;

    while(len) {
        uint32_t c = sl_utf8_each_char(vm, &buff, &len);
        lower_c = sl_unicode_tolower(c);
        out_offset += sl_utf32_char_to_utf8(vm, lower_c, retn->buff + out_offset);
    }

    return sl_make_ptr((sl_object_t*)retn);
}
Пример #14
0
SLVAL
sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_regexp_t* re = get_regexp_check(vm, self);
    sl_string_t* str = sl_get_string(vm, argv[0]);
    int offset = 0, rc, ncaps;
    int* caps;
    char err_buff[256];
    sl_regexp_match_t* match;
    if(argc > 1) {
        offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int));
    }
    offset = sl_string_byte_offset_for_index(vm, argv[0], offset);
    if(offset < 0) {
        return vm->lib.nil;
    }
    pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps);
    ncaps += 1;
    ncaps *= 3;
    caps = sl_alloc(vm->arena, sizeof(int) * ncaps);
    rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps);
    if(rc < 0) {
        if(rc == PCRE_ERROR_NOMATCH) {
            return vm->lib.nil;
        }
        if(rc == PCRE_ERROR_BADUTF8) {
            sl_throw_message2(vm, vm->lib.EncodingError, "Invalid UTF-8 in regular expression or match text");
        }
        sprintf(err_buff, "PCRE error (%d)", rc);
        sl_throw_message2(vm, vm->lib.Error, err_buff);
    }
    match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match));
    match->re = re;
    match->match_string = argv[0];
    match->capture_count = ncaps / 3;
    match->captures = caps;
    return sl_make_ptr((sl_object_t*)match);
}
Пример #15
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;
}
Пример #16
0
NODE(sl_node_var_t, var)
{
    sl_vm_insn_t insn;
    size_t frame;
    sl_compile_state_t* xcs = cs;
    size_t index = 0xCAFE;
    SLVAL err;
    frame = 0;
    while(xcs) {
        if(st_lookup(xcs->vars, (st_data_t)node->name, (st_data_t*)&index)) {
            if(frame == 0) {
                insn.opcode = SL_OP_MOV;
                emit(cs, insn);
            } else {
                insn.opcode = SL_OP_GET_OUTER;
                emit(cs, insn);
                insn.uint = frame;
                emit(cs, insn);
                mark_upper_scopes_as_closure_unsafe(cs, frame);
            }
            insn.uint = index;
            emit(cs, insn);
            insn.uint = dest;
            emit(cs, insn);
            return;
        }
        xcs = xcs->parent;
        frame++;
    }
    err = sl_make_cstring(cs->vm, "Undefined variable '");
    err = sl_string_concat(cs->vm, err, sl_make_ptr((sl_object_t*)node->name));
    err = sl_string_concat(cs->vm, err, sl_make_cstring(cs->vm, "' "));
    err = sl_make_error2(cs->vm, cs->vm->lib.NameError, err);
    sl_error_add_frame(cs->vm, err, sl_make_cstring(cs->vm, "<compiler>"), sl_make_cstring(cs->vm, (char*)cs->section->filename), sl_make_int(cs->vm, node->base.line));
    sl_throw(cs->vm, err);
}
Пример #17
0
static SLVAL
sl_regexp_match_regexp(sl_vm_t* vm, SLVAL self)
{
    return sl_make_ptr((sl_object_t*)get_regexp_match(vm, self)->re);
}
Пример #18
0
NODE(sl_node_var_t, cvar)
{
    SLID id = sl_intern2(cs->vm, sl_make_ptr((sl_object_t*)node->name));
    op_get_cvar(cs, id, dest);
}