};
#define BYTECODE_SZ (SZ_INT * 4)
+__attribute__((returns_nonnull)) ANN2(1) Instr
+new_instr(const MemPool mp, const f_instr f);
ANN void free_instr(const Gwion, const Instr);
INSTR(EOC);
INSTR(DTOR_EOC);
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
if (tdef->when_def) CHECK_BB(emit_func_def(emit, tdef->when_def));
-
- if (tflag(tdef->type, tflag_cdef)) {
- if(!tflag(tdef->type->info->parent, tflag_emit))
- return emit_class_def(emit, tdef->type->info->parent->info->cdef);
- }
- return tdef->type->info->cdef ? emit_class_def(emit, tdef->type->info->cdef) : GW_OK;
+ if (tflag(tdef->type, tflag_cdef))
+ return emit_class_def(emit, tdef->type->info->cdef);
+ return GW_OK;
}
ANN static m_bool emit_enum_def(const Emitter emit NUSED, const Enum_Def edef) {
}
__attribute__((returns_nonnull)) ANN2(1) Instr
-emit_add_instr(const Emitter emit, const f_instr f) {
- const Instr instr = mp_calloc(emit->gwion->mp, Instr);
+new_instr(const MemPool mp, const f_instr f) {
+ const Instr instr = mp_calloc(mp, Instr);
if ((m_uint)f < 255)
instr->opcode = (m_uint)f;
else {
instr->opcode = eOP_MAX;
instr->execute = f;
}
+ return instr;
+}
+__attribute__((returns_nonnull)) ANN2(1) Instr
+emit_add_instr(const Emitter emit, const f_instr f) {
+ const Instr instr = new_instr(emit->gwion->mp, f);
vector_add(&emit->code->instr, (vtype)instr);
return instr;
}
GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_struct_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
-
return GW_OK;
}
const bool spread = is_spread_tmpl(fdef->base->tmpl);
const uint32_t len = sl->len - spread;
Type_List tl = new_mp_vector(env->gwion->mp, Type_Decl*, len);
-
m_uint args_number = 0;
+
+ if(exp->other) {
+ for(uint32_t i = 0; i < len; i++) {
+ Specialized *spec = mp_vector_at(sl, Specialized, i);
+ if (spec->xid == fdef->base->td->xid) { // check no next?
+ CHECK_OO(check_exp(env, exp->other));
+ if(!is_func(env->gwion, exp->other->type)) {
+ Type_Decl *td = type2td(env->gwion, exp->other->type, fdef->base->pos);
+ mp_vector_set(tl, Type_Decl*, 0, td);
+ } else {
+ Func func = exp->other->type->info->func;
+ do {
+ if(mp_vector_len(func->def->base->args) == 1) {
+ Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
+ Type_Decl *td = cpy_type_decl(env->gwion->mp, arg->td);
+ mp_vector_set(tl, Type_Decl*, 0, td);
+ break;
+ }
+ } while((func = func->next));
+ }
+ ++args_number;
+ break;
+ }
+ }
+ }
for(uint32_t i = 0; i < len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
Arg_List args = fdef->base->args;
}
ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
+ if(bin->lhs->exp_type == ae_exp_call && !bin->lhs->d.exp_call.tmpl) {
+ CHECK_OO(check_exp(env, bin->lhs->d.exp_call.func));
+ // check is template?
+ bin->lhs->d.exp_call.other = bin->rhs;
+ }
CHECK_OO(check_exp(env, bin->lhs));
- const m_bool is_auto = bin->op == insert_symbol(":=>") &&
+ const m_bool is_auto = //bin->op == insert_symbol(":=>") &&
bin->rhs->exp_type == ae_exp_decl &&
bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
e->exp_type = ae_exp_unary;
unary->unary_type = unary_td;
unary->op = insert_symbol("new");
- unary->ctor.td = cpy_type_decl(env->gwion->mp, bin->rhs->d.exp_unary.ctor.td);
+ unary->ctor.td = new_type_decl(env->gwion->mp, insert_symbol("auto"), bin->rhs->d.exp_unary.ctor.td->pos);
unary->ctor.exp = lhs;
free_exp(env->gwion->mp, rhs);
return check_exp(env, e);
}
+ if(bin->rhs->exp_type == ae_exp_call && !bin->rhs->d.exp_call.tmpl)
+ bin->rhs->d.exp_call.other = bin->lhs;
+ const m_uint scope = env->scope->depth;
+ if(bin->op == insert_symbol(">=>"))
+ env_push_type(env, bin->lhs->type);
CHECK_OO(check_exp(env, bin->rhs));
+ if(bin->op == insert_symbol(">=>"))
+ env_pop(env, scope);
if (is_auto) {
assert(bin->rhs->type == bin->lhs->type);
set_vflag(bin->rhs->d.exp_decl.vd.value, vflag_assigned);
}
ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
- if(tdef->ext->array && tdef->ext->array->exp)
- CHECK_OB(check_exp(env, tdef->type->info->cdef->base.ext->array->exp));
if (tdef->when) {
set_tflag(tdef->type, tflag_contract);
struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos };
mp_vector_set(fdef->d.code->d.stmt_code.stmt_list, struct Stmt_, 1, ret);
ret_id->type = tdef->type;
}
+ if (tflag(tdef->type, tflag_cdef))
+ return check_class_def(env, tdef->type->info->cdef);
return GW_OK;
}
if (prim->prim_type == ae_prim_array && prim->d.array->exp)
return scan1_exp(env, prim->d.array->exp);
if (prim->prim_type == ae_prim_range) return scan1_range(env, prim->d.range);
+ if (env->func && prim->prim_type == ae_prim_perform && env->scope->depth <= 2)
+ env->func->memoize = 1;
return GW_OK;
}
}
ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
- if (!tdef->type) tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
+ //if (!tdef->type) tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
- if (!tflag(tdef->type, tflag_cdef)) {
- if(!tflag(tdef->type->info->parent, tflag_scan1))
- return scan1_class_def(env, tdef->type->info->parent->info->cdef);
- }
+ if (tflag(tdef->type, tflag_cdef))
+ return scan1_class_def(env, tdef->type->info->cdef);
return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK;
}
fdef->base->ret_type != env->gwion->type[et_void] && fdef->d.code &&
!fake.memoize)
ERR_B(fdef->base->td->pos,
- _("missing return statement in a non void function %u"), fake.memoize);
+ _("missing return statement in a non void function"));
if (fdef->base->xid == insert_symbol("@gack") && !fake.weight) {
gwerr_basic(_("`@gack` operator does not print anything"), NULL,
_("use `<<<` `>>>` in the function"), env->name, fdef->base->pos, 0);
ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f);
ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
if (tdef->when) CHECK_BB(scan2_exp(env, tdef->when));
- if (tflag(tdef->type, tflag_cdef)) {
- if(!tflag(tdef->type->info->parent, tflag_scan2))
- return scan2_class_def(env, tdef->type->info->parent->info->cdef);
- }
+ if (tflag(tdef->type, tflag_cdef))
+ return scan2_class_def(env, tdef->type->info->cdef);
if (!tdef->type->info->cdef) return GW_OK;
return tdef->type->info->cdef ? scan2_class_def(env, tdef->type->info->cdef) : GW_OK;
}
MUTEX_UNLOCK(s->mutex);
}
-ANN void shredule(const Shreduler s, const VM_Shred shred,
+ANN void _shredule(const Shreduler s, struct ShredTick_ *tk,
const m_float wake_time) {
- struct ShredTick_ *tk = shred->tick;
if(tk->prev == (struct ShredTick_*)-1) return;
- MUTEX_LOCK(s->mutex);
const m_float time = wake_time + (m_float)s->bbq->pos;
tk->wake_time = time;
if (s->list) {
} else
s->list = tk;
if (tk == s->curr) s->curr = NULL;
+}
+
+ANN void shredule(const Shreduler s, const VM_Shred shred,
+ const m_float wake_time) {
+ struct ShredTick_ *tk = shred->tick;
+ MUTEX_LOCK(s->mutex);
+ _shredule(s, tk, wake_time);
MUTEX_UNLOCK(s->mutex);
}
ANN void shreduler_add(const Shreduler s, const VM_Shred shred) {
shreduler_ini(s, shred);
shred->tick->xid = ++s->shred_ids;
+ MUTEX_LOCK(s->mutex);
vector_add(&s->active_shreds, (vtype)shred);
- shredule(s, shred, GWION_EPSILON);
+ _shredule(s, shred->tick, GWION_EPSILON);
+ MUTEX_UNLOCK(s->mutex);
}
ANN Shreduler new_shreduler(const MemPool mp) {
}
}
-ANN static uint16_t find_pc(const VM_Shred shred, const Symbol effect, const m_uint size) {
+ANN static uint16_t find_pc(const VM_Shred shred, const Symbol effect) {
const VM_Code code = shred->code;
const m_uint start = vector_at(&shred->info->frame, vector_size(&shred->info->frame) - 2);
if (start > shred->pc) return true;
return 0;
}
-ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect, const m_uint size) {
- const uint16_t pc = find_pc(shred, effect, size);
+ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect) {
+ const uint16_t pc = find_pc(shred, effect);
if (!pc) return false; // outside of a try statement
shred->reg = // restore reg
(m_bit *)VPTR(&shred->info->frame, VLEN(&shred->info->frame) - 1);
clean_values(shred);
if (!size) return false;
if (code->handlers.ptr)
- return find_handle(shred, effect, size);
+ return find_handle(shred, effect);
// there might be no more stack to unwind
if (shred->mem == (m_bit *)shred + sizeof(struct VM_Shred_) + SIZEOF_REG)
return false;