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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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)); } }
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); }