예제 #1
0
파일: eval.c 프로젝트: tinkertim/slash
SLVAL
sl_do_file(sl_vm_t* vm, char* filename)
{
    filename = sl_realpath(vm, filename);
    FILE* f = fopen(filename, "rb");
    uint8_t* src;
    size_t file_size;
    SLVAL err;
    
    if(!f) {
        err = sl_make_cstring(vm, "Could not load file: ");
        err = sl_string_concat(vm, err, sl_make_cstring(vm, filename));
        err = sl_string_concat(vm, err, sl_make_cstring(vm, " - "));
        err = sl_string_concat(vm, err, sl_make_cstring(vm, strerror(errno)));
        sl_throw(vm, sl_make_error2(vm, vm->lib.Error, err));
    }
    fseek(f, 0, SEEK_END);
    file_size = ftell(f);
    fseek(f, 0, SEEK_SET);
    src = sl_alloc(vm->arena, file_size);
    if(file_size && !fread(src, file_size, 1, f)) {
        fclose(f);
        err = sl_make_cstring(vm, "Could not load file: ");
        err = sl_string_concat(vm, err, sl_make_cstring(vm, filename));
        err = sl_string_concat(vm, err, sl_make_cstring(vm, " - "));
        err = sl_string_concat(vm, err, sl_make_cstring(vm, strerror(errno)));
        sl_throw(vm, sl_make_error2(vm, vm->lib.Error, err));
    }
    fclose(f);
    
    return sl_do_string(vm, src, file_size, filename, 0);
}
예제 #2
0
void
sl_parse_error(sl_parse_state_t* ps, char* message)
{
    SLVAL err = sl_make_error2(ps->vm, ps->vm->lib.SyntaxError, sl_make_cstring(ps->vm, message));
    sl_error_add_frame(ps->vm, err, sl_make_cstring(ps->vm, "<parser>"), sl_make_cstring(ps->vm, (char*)ps->filename), sl_make_int(ps->vm, ps->line));
    sl_throw(ps->vm, err);
}
예제 #3
0
파일: parse.c 프로젝트: charliesome/slash
static void
error(sl_parse_state_t* ps, SLVAL err, sl_token_t* tok)
{
    err = sl_make_error2(ps->vm, ps->vm->lib.SyntaxError, err);
    sl_error_add_frame(ps->vm, err, sl_make_cstring(ps->vm, "<parser>"), sl_make_cstring(ps->vm, (char*)ps->filename), sl_make_int(ps->vm, tok->line));
    sl_throw(ps->vm, err);
}
예제 #4
0
파일: compile.c 프로젝트: Hmaal/slash
NODE(sl_node_var_t, var)
{
    size_t frame;
    sl_compile_state_t* xcs = cs;
    size_t index = 0xCAFE;
    SLVAL err;
    frame = 0;
    while(xcs) {
        if(sl_st_lookup(xcs->vars, (sl_st_data_t)node->name, (sl_st_data_t*)&index)) {
            if(frame == 0) {
                op_mov(cs, index, dest);
            } else {
                op_get_outer(cs, frame, index, dest);
                mark_upper_scopes_as_closure_unsafe(cs, frame);
            }
            return;
        }
        xcs = xcs->parent;
        frame++;
    }
    err = sl_make_formatted_string(cs->vm, "Undefined variable %QV", node->name);
    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);
}
예제 #5
0
파일: dispatch.c 프로젝트: Hmaal/slash
SLVAL
sl_apply_method(sl_vm_t* vm, SLVAL recv, sl_method_t* method, int argc, SLVAL* argv)
{
    SLVAL arg;
    if((void*)&arg < vm->stack_limit) {
        /* we're about to blow the stack */
        sl_throw(vm, vm->lib.StackOverflowError_instance);
    }
    if(method->arity < 0) {
        if(sl_unlikely(-method->arity - 1 > argc)) {
            sl_error(vm, vm->lib.ArgumentError, "Too few arguments. Expected %d, received %d.", (-method->arity - 1), argc);
        }
    } else {
        if(sl_unlikely(method->arity > argc)) {
            sl_error(vm, vm->lib.ArgumentError, "Too few arguments. Expected %d, received %d.", method->arity, argc);
        }
        if(sl_unlikely(method->arity < argc)) {
            sl_error(vm, vm->lib.ArgumentError, "Too many arguments. Expected %d, received %d.", method->arity, argc);
        }
    }
    if(method->base.user_flags & SL_FLAG_METHOD_IS_C_FUNC) {
        return call_c_func_guard(vm, recv, method, argc, argv);
    } else {
        return call_sl_func(vm, recv, method, argc, argv);
    }
}
예제 #6
0
void
sl_lex_error(sl_lex_state_t* st, char* text, int lineno)
{
    SLVAL msg = sl_make_formatted_string(st->vm, "Unexpected character '%s'", text);
    SLVAL err = sl_make_error2(st->vm, st->vm->lib.SyntaxError, msg);
    sl_error_add_frame(st->vm, err, sl_make_cstring(st->vm, "<lexer>"), sl_make_cstring(st->vm, (char*)st->filename), sl_make_int(st->vm, lineno));
    sl_throw(st->vm, err);
}
예제 #7
0
파일: compile.c 프로젝트: Hmaal/slash
static void
emit_assignment(sl_compile_state_t* cs, sl_node_base_t* lval, size_t reg)
{
    sl_node_assign_var_t a_var;
    sl_node_send_t send;

    size_t dest_reg = reg_alloc(cs);

    sl_node__register_t node;
    node.base.type = SL_NODE__REGISTER;
    node.base.line = 0;
    node.reg = reg;

    switch(lval->type) {
        case SL_NODE_VAR:    a_var.base.type = SL_NODE_ASSIGN_VAR;    break;
        case SL_NODE_IVAR:   a_var.base.type = SL_NODE_ASSIGN_IVAR;   break;
        case SL_NODE_CVAR:   a_var.base.type = SL_NODE_ASSIGN_CVAR;   break;
        case SL_NODE_CONST:  a_var.base.type = SL_NODE_ASSIGN_CONST;  break;
        case SL_NODE_ARRAY:  a_var.base.type = SL_NODE_ASSIGN_ARRAY;  break;
        case SL_NODE_SEND:
            /* special case that turns a.b = 1 into a.send("b=", 1) */
            /* this is separate to the other method of handling send assignments
               which also handles compound assignments. */
            memcpy(&send, lval, sizeof(sl_node_send_t));
            send.id = sl_id_make_setter(cs->vm, send.id);
            sl_node_base_t** args = sl_alloc(cs->vm->arena, sizeof(sl_node_base_t*) * (send.arg_count + 1));
            memcpy(args, send.args, sizeof(sl_node_base_t*) * send.arg_count);
            args[send.arg_count++] = (sl_node_base_t*)&node;
            send.args = args;
            compile_node(cs, (sl_node_base_t*)&send, dest_reg);
            reg_free(cs, dest_reg);
            return;
        default: {
            SLVAL err = sl_make_cstring(cs->vm, "Invalid lval in assignment");
            err = sl_make_error2(cs->vm, cs->vm->lib.SyntaxError, 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, lval->line));
            sl_throw(cs->vm, err);
        }
    }

    a_var.base.line = 0;
    a_var.lval = (void*)lval;
    a_var.rval = (sl_node_base_t*)&node;
    compile_node(cs, (sl_node_base_t*)&a_var, dest_reg);

    reg_free(cs, dest_reg);
}
예제 #8
0
파일: json.c 프로젝트: Hmaal/slash
static void
sl_json_parse_check_error(sl_vm_t* vm, sl_string_t* str, json_parse_t* json, yajl_status status)
{
    uint8_t* err_str;
    SLVAL err;
    if(status == yajl_status_client_canceled) {
        /* the only reason we'd cancel the parse is if the data structre is too deep */
        yajl_free(json->yajl);
        sl_throw_message2(vm, vm->store[cJSON_ParseError],
            "JSON structure recurses too deep");
    }
    if(status == yajl_status_error) {
        err_str = yajl_get_error(json->yajl, 0, (const uint8_t*)str->buff, (size_t)str->buff_len);
        err = sl_make_cstring(vm, (char*)err_str);
        yajl_free_error(json->yajl, err_str);
        yajl_free(json->yajl);
        sl_throw(vm, sl_make_error2(vm, vm->store[cJSON_ParseError], err));
    }
}
예제 #9
0
파일: compile.c 프로젝트: tinkertim/slash
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);
}