Ejemplo n.º 1
0
sl_value
sl_string_concat(struct sl_interpreter_state *state, sl_value s1, sl_value s2)
{
        char *str;
        sl_value s;
        int size;

        if (sl_type(s1) != state->tString) {
                s1 = sl_inspect(state, s1);
        }

        if (sl_type(s2) != state->tString) {
                s2 = sl_inspect(state, s2);
        }

        size = NUM2INT(sl_string_size(state, s1)) + NUM2INT(sl_string_size(state, s2)) + 1;
        str = sl_native_malloc(size * sizeof(char));

        sprintf(str, "%s%s", sl_string_cstring(state, s1), sl_string_cstring(state, s2));

        s = sl_string_new(state, str);
        free(str);

        return s;
}
Ejemplo n.º 2
0
Archivo: cli.c Proyecto: Hmaal/slash
static void
run_repl(sl_vm_t* vm)
{
    printf("Interactive Slash\n");
    cli_setup_readline();
    while(true) {
        char* line = cli_readline(">> ");
        if(!line) {
            printf("\n");
            shutdown_vm(vm, 0);
        }
        sl_vm_frame_t frame;
        SLVAL exception;
        SL_TRY(frame, SL_UNWIND_EXCEPTION, {
            SLVAL result = sl_do_string(vm, (uint8_t*)line, strlen(line), "(repl)", 1);
            result = sl_inspect(vm, result);
            printf("=> ");
            sl_string_t* str = (sl_string_t*)sl_get_ptr(result);
            fwrite(str->buff, str->buff_len, 1, stdout);
            printf("\n");
        }, exception, {
            SLVAL exception_str = sl_to_s_no_throw(vm, exception);
            sl_string_t* str = (sl_string_t*)sl_get_ptr(exception_str);
            fwrite(str->buff, str->buff_len, 1, stdout);
            printf("\n");
        });
Ejemplo n.º 3
0
sl_value
sl_eval(struct sl_interpreter_state *state, sl_value expression, sl_value environment)
{
        if (sl_type(expression) == state->tSymbol) {
                if (sl_env_has_key(state, environment, expression)) {
                        return sl_env_get(state, environment, expression);
                } else {
                        fprintf(stderr, "Error: `%s' is undefined\n", sl_string_cstring(state, sl_inspect(state, expression)));
                        abort();
                }
        } else if (sl_type(expression) != state->tList) {
                return expression;
        } else if (sl_empty(state, expression) == state->sl_true) {
                return expression;
        } else if (sl_type(sl_first(state, expression)) == state->tSymbol) {
                sl_value first = sl_first(state, expression);

                if (state->s_def == first) {
                        assert(NUM2INT(sl_list_size(state, expression)) == 3);

                        sl_value second = sl_second(state, expression);
                        sl_value third = sl_third(state, expression);
                        return sl_def(state, second, sl_eval(state, third, environment));
                } else if (state->s_quote == first) {
                        assert(NUM2INT(sl_list_size(state, expression)) == 2);

                        return sl_second(state, expression);
                } else if (state->s_if == first) {
                        assert(NUM2INT(sl_list_size(state, expression)) == 4);

                        sl_value rest = sl_rest(state, expression);
                        sl_value result = sl_eval(state, sl_first(state, rest), environment);

                        if (result == state->sl_false) {
                                return sl_eval(state, sl_third(state, rest), environment);
                        } else {
                                return sl_eval(state, sl_second(state, rest), environment);
                        }
                } else if (state->s_annotate == first) {
                        assert(NUM2INT(sl_list_size(state, expression)) == 3);

                        sl_value val = sl_eval(state, sl_second(state, expression), environment);
                        sl_value type = sl_eval(state, sl_third(state, expression), environment);

                        assert(sl_type(val) == type);

                        return val;
                } else {
                        sl_value f = sl_eval(state, first, environment);
                        sl_value new_expression = sl_list_new(state, f, sl_rest(state, expression));

                        return sl_eval(state, new_expression, environment);
                }
        } else if (sl_type(sl_first(state, expression)) == state->tFunction) {
                sl_value f = sl_first(state, expression);
                sl_value args = sl_rest(state, expression);

                /* TODO: make eval_each a map and eval */
                return sl_apply(state, f, eval_each(state, args, environment));
        } else {
                fprintf(stderr, "Error: %s is not implemented yet\n", sl_string_cstring(state, sl_inspect(state, expression)));
                abort();
        }
}
Ejemplo n.º 4
0
Archivo: string.c Proyecto: 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);
}