emit_add_instr(emit, RegPushMem);
else if(prim->d.var == insert_symbol("me"))
emit_add_instr(emit, RegPushMe);
- else if(prim->d.var == insert_symbol("now"))
- emit_add_instr(emit, RegPushNow);
+ else if(prim->d.var == insert_symbol("now") && exp_self(prim)->type == t_now)
+ emit_add_instr(emit, RegPushNow);// 'now' is not reserved for ... now ;-)
else if(prim->d.var == insert_symbol("maybe"))
emit_add_instr(emit, RegPushMaybe);
else if(prim->d.var == insert_symbol("__func__")) {
CHECK_BB(exp_func[exp->exp_type](emit, &exp->d))
if(exp->cast_to)
CHECK_BB(emit_implicit_cast(emit, exp->type, exp->cast_to))
- if(ref && isa(exp->type, t_object) > 0 && isa(exp->type, t_fork) < 0 ) { // beware fork
+ if(ref && isa(exp->type, t_object) > 0 && isa(exp->type, t_shred) < 0 ) { // beware fork
const Instr instr = emit_add_instr(emit, RegAddRef);
instr->m_val = exp->emit_var;
}
if(stmt->val) {
OPTIMIZE_TCO
CHECK_BB(emit_exp(emit, stmt->val, 0))
- if(isa(stmt->val->type, t_object) > 0 && isa(stmt->val->type , t_fork) < 0) // beware fork
+ if(isa(stmt->val->type, t_object) > 0 && isa(stmt->val->type , t_shred) < 0) // beware shred
emit_add_instr(emit, RegAddRef);
}
vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
emit_func_def_code(emit, func);
emit->env->func = former;
emit_pop_code(emit);
+ if(GET_FLAG(func_def, op))
+ SET_FLAG(func->code, op);
if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl)
emit_func_def_global(emit, func->value_ref);
if(emit->memoize && GET_FLAG(func, pure))
Exp_Binary* bin = (Exp_Binary*)data;
emit_add_instr(emit, int_r_assign);
if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member)
- && !emit->env->class_def
-) {
+ && !emit->env->class_def) {
const Instr instr = emit_add_instr(emit, LambdaAssign);
instr->m_val = SZ_INT;
}
return GW_OK;
}
+
ANN static Type fptr_type(const Env env, Exp_Binary* bin) {
const Func l_func = bin->lhs->type->d.func;
const Func r_func = bin->rhs->type->d.func;
if(unary->exp && unary->exp->exp_type == ae_exp_call)
return unary->op == op_spork ? t_shred : t_fork;
else if(unary->code) {
- CHECK_BO(check_stmt(env, unary->code))
+ ++env->scope->depth; \
+ nspc_push_value(env->gwion->p, env->curr); \
+ const m_bool ret = check_stmt(env, unary->code);
+ nspc_pop_value(env->gwion->p, env->curr); \
+ --env->scope->depth;
+ CHECK_BO(ret)
return unary->op == op_spork ? t_shred : t_fork;
} else
ERR_O(exp_self(unary)->pos, "only function calls can be sporked...")
static SFUN(vm_shred_from_id) {
const m_int index = *(m_int*)MEM(0);
-// TODO vector_size_safe()
- if(index <= 0 && (m_uint)index < vector_size(&shred->tick->shreduler->shreds)) {
- const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index);
- if(s)
- *(M_Object*)RETURN = s->info->me;
- else
+ if(index > 0) {
+ for(m_uint i = 0; i < vector_size(&shred->tick->shreduler->shreds); ++i) {
+ const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, i);
+ if(s->tick->xid == (m_uint)index) {
+ *(M_Object*)RETURN = s->info->me;
+ return;
+ }
+ }
+ } else
*(m_uint*)RETURN = 0;
- }
}
static MFUN(shred_args) {
POP_REG(shred, offset); \
const type lhs = *(type*)REG(-SZ_INT);\
const M_Object rhs = *(M_Object*)REG(offset-SZ_INT);\
+ if(!rhs) \
+ Except(shred, "NullPtrException"); \
char str[(len)];\
sprintf(str, format, __VA_ARGS__);\
push_new_string(shred, str);\
const Type_List types = exp->tmpl->types;
Func m_func = exp->m_func, former = env->func;
const m_str tmpl_name = tl2str(env, types);
+ const m_uint sz = vector_size((Vector)env->curr->info->type);
const m_uint scope = env_push(env, v->owner_class, v->owner);
for(m_uint i = 0; i < v->offset + 1; ++i) {
Func_Def def = NULL;
}
}
}
+// check m_func => maybe assert
+ if(!m_func && sz != vector_size((Vector)env->curr->info->type))
+ nspc_pop_type(env->gwion->p, env->curr);
SET_FLAG(base, template);
}
end:
ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) {
struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp), .data=(uintptr_t)post, .pos=exp_self(post)->pos };
CHECK_OO(opi.lhs)
- return op_check(env, &opi);
+ const Type t = op_check(env, &opi);
+ if(t && isa(t, t_object) < 0)
+ exp_self(post)->meta = ae_meta_value;
+ return t;
}
ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
.data=(uintptr_t)unary, .pos=exp_self(unary)->pos };
if(unary->exp && !opi.rhs)
return NULL;
- return op_check(env, &opi);
+ const Type t = op_check(env, &opi);
+ if(t && isa(t, t_object) < 0)
+ exp_self(unary)->meta = ae_meta_value;
+ return t;
}
ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) {
}
ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
- if((unary->op == op_spork || unary->op == op_fork) && unary->code)
- return scan1_stmt(env, unary->code);
+ if((unary->op == op_spork || unary->op == op_fork) && unary->code) {
+ RET_NSPC(scan1_stmt(env, unary->code))
+ }
return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
}
}
ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
- if((unary->op == op_spork || unary->op == op_fork) && unary->code)
- return scan2_stmt(env, unary->code);
- else if(unary->exp)
+ if((unary->op == op_spork || unary->op == op_fork) && unary->code) {
+ RET_NSPC(scan2_stmt(env, unary->code))
+ } else if(unary->exp)
return scan2_exp(env, unary->exp);
return GW_OK;
}
vector_init(&v);
do {
const Type t = nspc_lookup_type0(env->curr, id->xid);
+ if(!t) {
+ vector_release(&v);
+ return NULL;
+ }
vector_add(&v, (vtype)t);
tlen += strlen(t->name);
} while((id = id->next) && ++tlen);
if(GET_FLAG(f, global))
scope = env_push_global(env);
const Value overload = nspc_lookup_value0(env->curr, f->base->xid);
+ const Value res = nspc_lookup_value1(env->global_nspc, f->base->xid);
m_str func_name = s_name(f->base->xid);
+ if(res)
+ ERR_B(f->pos, "'%s' already declared as type", func_name)
if(overload)
CHECK_BB(scan2_func_def_overload(env, f, overload))
if(tmpl_list_base(f->tmpl))
if(f->base->func)
func_name = f->base->func->name;
else
- func_name = func_tmpl_name(env, f);
+ CHECK_OB((func_name = func_tmpl_name(env, f)))
const Func func = nspc_lookup_func1(env->curr, insert_symbol(func_name));
if(func) {
if(GET_FLAG(func, member))
ANN static void unwind(const VM_Shred shred) {
VM_Code code = shred->code;
- while(1) {
+ while(code) {
const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
if(exec == eFuncReturn) {
- code = *(VM_Code*)(shred->mem - SZ_INT*3);
- REM_REF(code, shred->info->vm->gwion);
+ if(GET_FLAG(code, op))
+ code = *(VM_Code*)(shred->mem - SZ_INT);
+ else {
+ code = *(VM_Code*)(shred->mem - SZ_INT*3);
+ REM_REF(code, shred->info->vm->gwion);
+ }
shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4;
if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))break;
} else break;
mp_free(mp, ShredTick, shred->tick);
free_shredinfo(mp, shred->info);
mp_free(mp, Stack, shred);
-}
\ No newline at end of file
+}