emit_add_instr(emit, ArrayPost);
}
-ANN ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e) {
- CHECK_BO(emit_exp(emit, e, 0))
+ANN2(1) static m_bool extend_indices(const Emitter emit, Exp e, const m_uint depth) {
+ if(e)
+ CHECK_BB(emit_exp(emit, e, 0))
+ m_uint count = 0;
+ while(e) {
+ ++count;
+ e = e->next;
+ }
+ for(m_uint i = count; i < depth; ++i)
+ regpushi(emit, 0);
+ return GW_OK;
+}
+
+ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) {
const Type base = array_base(t);
ArrayInfo* info = mp_calloc(emit->gwion->mp, ArrayInfo);
vector_init(&info->type);
vector_add(&info->type, (vtype)t);
info->depth = (m_int)t->array_depth;
info->base = base;
- const Instr alloc = emit_add_instr(emit, ArrayAlloc);
- alloc->m_val = (m_uint)info;
+ return info;
+}
+
+ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) {
+ const Type base = info->base;
if(isa(base, emit->gwion->type[et_object]) > 0 && !GET_FLAG(base, abstract)) {
emit_pre_constructor_array(emit, base);
info->is_obj = 1;
}
+}
+
+ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e) {
+ CHECK_BO(extend_indices(emit, e, t->array_depth))
+ ArrayInfo* info = new_arrayinfo(emit, t);
+ const Instr alloc = emit_add_instr(emit, ArrayAlloc);
+ alloc->m_val = (m_uint)info;
+ arrayinfo_ctor(emit, info);
return info;
}
++VPTR(&emit->info->pure, VLEN(&emit->info->pure) - 1);
}
-ANN static Array_Sub instantiate_typedef(MemPool p, const m_uint depth) {
- const Exp base = new_exp_prim_int(p, 0, new_loc(p, __LINE__));
- Exp e = base;
- for(m_uint i = 0; i < depth; ++i)
- e = (e->next = new_exp_prim_int(p, 0, new_loc(p, __LINE__)));
- return new_array_sub(p, base);
-}
-
ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
- const Array_Sub arr, const m_bool is_ref) {
+ const Array_Sub array, const m_bool is_ref) {
emit_notpure(emit);
if(type->array_depth) {
- assert(!arr || arr->depth == type->array_depth);
- const Array_Sub array = arr ?: instantiate_typedef(emit->gwion->mp, type->array_depth);
- assert(array->exp);
- ArrayInfo* info = emit_array_extend_inner(emit, type, array->exp);
+ ArrayInfo* info = emit_array_extend_inner(emit, type, array ? array->exp : NULL);
if(info)
info->is_ref = is_ref;
- if(!arr)
- free_array_sub(emit->gwion->mp, array);
return info ? GW_OK : GW_ERROR;
} else if(!is_ref) {
const Instr instr = emit_add_instr(emit, ObjectInstantiate);
return emit_dot_static_data(emit, value, emit_addr);
}
-ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl var_decl,
+ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl,
const uint is_ref, const uint emit_var) {
const Value v = var_decl->value;
const Type type = v->type;
const Array_Sub array = var_decl->array;
- const m_bool is_array = array && array->exp;
+ const m_bool is_array = (array && array->exp) || GET_FLAG(decl->td, force);
const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const uint emit_addr = ((is_ref && !array) || isa(type, emit->gwion->type[et_object]) < 0) ?
emit_var : 1;
- if(is_obj && (is_array || !is_ref)/* && !GET_FLAG(var_decl->value, ref)*/)
+ if(is_obj && (is_array || !is_ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
f_instr *exec = (f_instr*)allocmember;
if(!GET_FLAG(v, member)) {
if(is_obj && (is_array || !is_ref)) {
emit_add_instr(emit, Assign);
const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
- if(missing_depth) {
+ if(missing_depth && !GET_FLAG(decl->td, force)) {
const Instr push = emit_add_instr(emit, Reg2Reg);
- push->m_val = -(1 + missing_depth) * SZ_INT;
- regpop(emit, (missing_depth) * SZ_INT);
+ push->m_val = -(missing_depth) * SZ_INT;
}
}
return GW_OK;
if(GET_FLAG(decl->td, static))
CHECK_BB(emit_exp_decl_static(emit, list->self, r, var))
else if(!global)
- CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var))
+ CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var))
else
CHECK_BB(emit_exp_decl_global(emit, list->self, r, var))
if(GET_FLAG(list->self->value->type, nonnull))
CHECK_BO(scan1_exp(env, td->exp))
CHECK_BO(scan2_exp(env, td->exp))
CHECK_OO(check_exp(env, td->exp))
-// TODO: check me
const Type t = actual_type(env->gwion, td->exp->type);
assert(t);
- m_uint depth;
- td->xid = str2list(env, t->name, &depth, td->exp->pos);
- if(depth) {
- Exp base = new_exp_prim_int(env->gwion->mp, 0, new_loc(env->gwion->mp, __LINE__)), e = base;
- for(m_uint i = 0; i < depth - 1; ++i)
- e = (e->next = new_exp_prim_int(env->gwion->mp, 0, new_loc(env->gwion->mp, __LINE__)));
- td->array = new_array_sub(env->gwion->mp, base);
- }
+ td->xid = new_id_list(env->gwion->mp, insert_symbol("@resolved"),
+ loc_cpy(env->gwion->mp, td->exp->pos));
+ if(t->array_depth)
+ SET_FLAG(td, force);
return t;
}
}
ANN static Type no_xid(const Env env, const Exp_Decl *decl) {
- DECL_OO(const Type, t, = check_td(env, decl->td))
- ((Exp_Decl*)decl)->type = NULL;
+ CHECK_OO((((Exp_Decl*)decl)->type = check_td(env, decl->td)))
clear_decl(env, decl);
CHECK_BO(traverse_decl(env, decl))
return decl->type;