Beispiel #1
0
static int
own_instance_methods_iter(sl_vm_t* vm, SLID name, SLVAL method, SLVAL ary)
{
    SLVAL namev = sl_id_to_string(vm, name);
    sl_array_push(vm, ary, 1, &namev);
    return SL_ST_CONTINUE;
    (void)method;
}
Beispiel #2
0
static SLVAL
sl_method_name(sl_vm_t* vm, SLVAL method)
{
    sl_method_t* methp = (sl_method_t*)sl_get_ptr(method);
    if(!methp->initialized) {
        return vm->lib.nil;
    }
    return sl_id_to_string(vm, methp->name);
}
Beispiel #3
0
static SLVAL
sl_method_name(sl_vm_t* vm, SLVAL method)
{
    sl_method_t* methp = (sl_method_t*)sl_get_ptr(method);
    if(!(methp->base.user_flags & SL_FLAG_METHOD_INITIALIZED)) {
        return vm->lib.nil;
    }
    return sl_id_to_string(vm, methp->extra->name);
}
Beispiel #4
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;
}
Beispiel #5
0
static SLVAL
sl_class_to_s(sl_vm_t* vm, SLVAL self)
{
    sl_class_t* klass = get_class(vm, self);
    sl_class_t* object = (sl_class_t*)sl_get_ptr(vm->lib.Object);
    if(klass == object || sl_get_ptr(klass->extra->in) == (sl_object_t*)object) {
        return sl_id_to_string(vm, klass->extra->name);
    } else {
        return sl_make_formatted_string(vm, "%V::%I", sl_class_to_s(vm, klass->extra->in), klass->extra->name);
    }
}
Beispiel #6
0
static SLVAL
sl_send_missing(sl_vm_t* vm, SLVAL recv, SLID id, int argc, SLVAL* argv)
{
    /* look for method_missing method */
    SLVAL argv2[argc + 1];
    memcpy(&argv2[1], argv, sizeof(SLVAL) * argc);
    argv2[0] = sl_id_to_string(vm, id);

    sl_method_t* method = sl_lookup_method(vm, recv, vm->id.method_missing);
    if(method) {
        return sl_apply_method(vm, recv, method, argc + 1, argv2);
    }

    /* nope */

    sl_error(vm, vm->lib.NoMethodError, "Undefined method %QI on %X", id, recv);
    return vm->lib.nil; /* shutup gcc */
}
Beispiel #7
0
static SLVAL
sl_class_name(sl_vm_t* vm, SLVAL self)
{
    return sl_id_to_string(vm, get_class(vm, self)->extra->name);
}
Beispiel #8
0
static sl_node_base_t*
def_expression(sl_parse_state_t* ps)
{
    SLID name;
    sl_node_base_t* on = NULL;
    sl_node_base_t* body;
    sl_token_t* tok;
    size_t req_arg_count = 0, req_arg_cap = 2;
    sl_string_t** req_args = sl_alloc(ps->vm->arena, sizeof(sl_string_t*) * req_arg_cap);
    size_t opt_arg_count = 0, opt_arg_cap = 2;
    sl_node_opt_arg_t* opt_args = sl_alloc(ps->vm->arena, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
    sl_parse_scope_t scope;
    expect_token(ps, SL_TOK_DEF);
    switch(peek_token(ps)->type) {
        case SL_TOK_IDENTIFIER:
            if(peek_token_n(ps, 2)->type == SL_TOK_DOT) {
                on = sl_make_var_node(ps, SL_NODE_VAR, next_token(ps)->str);
                next_token(ps);
                name = def_expression_method_name(ps);
            } else {
                on = NULL;
                name = def_expression_method_name(ps);
            }
            break;
        case SL_TOK_SELF:
        case SL_TOK_IVAR:
        case SL_TOK_CVAR:
        case SL_TOK_CONSTANT:
            on = primary_expression(ps);
            expect_token(ps, SL_TOK_DOT);
            name = def_expression_method_name(ps);
            break;
        default:
            name = def_expression_method_name(ps);
    }
    if(peek_token(ps)->type == SL_TOK_EQUALS) {
        next_token(ps);
        name = sl_intern2(ps->vm,
            sl_string_concat(ps->vm, sl_id_to_string(ps->vm, name), sl_make_cstring(ps->vm, "=")));
    }
    int at_opt_args = 0;
    if(peek_token(ps)->type != SL_TOK_OPEN_BRACE) {
        expect_token(ps, SL_TOK_OPEN_PAREN);
        if(peek_token(ps)->type == SL_TOK_SELF) {
            error(ps, sl_make_cstring(ps->vm, "not a chance"), peek_token(ps));
        }
        while(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
            tok = expect_token(ps, SL_TOK_IDENTIFIER);
            if(peek_token(ps)->type == SL_TOK_EQUALS) {
                at_opt_args = 1;
            }
            if(at_opt_args) {
                expect_token(ps, SL_TOK_EQUALS);
                if(opt_arg_count >= opt_arg_cap) {
                    opt_arg_cap *= 2;
                    opt_args = sl_realloc(ps->vm->arena, opt_args, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
                }
                opt_args[opt_arg_count].name = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
                opt_args[opt_arg_count++].default_value = expression(ps);
            } else {
                if(req_arg_count >= req_arg_cap) {
                    req_arg_cap *= 2;
                    req_args = sl_realloc(ps->vm->arena, req_args, sizeof(sl_string_t*) * req_arg_cap);
                }
                req_args[req_arg_count++] = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            }
            if(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
                expect_token(ps, SL_TOK_COMMA);
            }
        }
        expect_token(ps, SL_TOK_CLOSE_PAREN);
    }
    scope.prev = ps->scope;
    scope.flags = SL_PF_CAN_RETURN;
    ps->scope = &scope;
    body = body_expression(ps);
    ps->scope = scope.prev;
    ps->scope->flags |= SL_PF_SCOPE_CLOSURE;
    return sl_make_def_node(ps, name, on, req_arg_count, req_args, opt_arg_count, opt_args, body);
}
Beispiel #9
0
// 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);
}