-Subproject commit 21e5a7e33d5c13c56f61322c7b40fa2c6603f3b6
+Subproject commit 2b7ad3f0e5b241640e7be0576332e3fec0296662
char *escape;
VM_Code (*emit_code)(const Emitter);
VM_Code code;
- m_bool memoize;
+ uint memoize;
+// uint unroll;
};
struct Emitter_ {
#define did_you_mean_type(a, b) if(strlen(b) < DID_YOU_MEAN_LIMIT) did_you_mean_type(a,b);
ANN static inline void nspc_allocdata(MemPool mp, const Nspc nspc) {
- if(nspc->info->class_data_size)
-// nspc->info->class_data = (m_bit*)xcalloc(1, nspc->info->class_data_size);
+ if(nspc->info->class_data_size) {
nspc->info->class_data = (m_bit*)mp_calloc2(mp, nspc->info->class_data_size);
+ }
}
#endif
Union_Def udef;
Class_Def cdef;
Func func;
- Type base_type;
};
+ Type base_type;
struct TupleForm_* tuple;
struct VM_Code_ *gack;
struct Context_ *ctx;
ANN m_bool isres(const Env, const Symbol, const loc_t pos);
ANN Type array_type(const Env, const Type, const m_uint);
ANN Type find_common_anc(const Type, const Type) __attribute__((pure));
-ANN m_uint id_list_len(ID_List);
-ANN void type_path(const m_str, const ID_List);
ANN Type typedef_base(Type) __attribute__((pure));
ANN Type array_base(Type) __attribute__((pure));
ANN m_bool type_ref(Type) __attribute__((pure));
ANN static inline m_uint env_push_type(const Env env, const Type type) { return env_push(env, type, type->nspc); }
ANN m_bool is_fptr(const struct Gwion_*, const Type t);
ANN m_bool is_class(const struct Gwion_*, const Type t);
+ANN __attribute__((returns_nonnull))
+static inline Type _class_base(Type t) {
+ return t->info->base_type;
+}
ANN m_uint get_depth(const Type type);
ANN void inherit(const Type);
return t; // unreachable
}
-__attribute__((returns_nonnull))
-ANN Type get_type(const Type t);
-
typedef enum {
et_void, et_int, et_bool, et_char, et_float,
et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
- et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, et_none,
+ et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_auto, et_none,
MAX_TYPE
} type_enum;
#endif
// vflag_used = 1 << 3
} __attribute__((packed));
-union __attribute__((transparent_union)) value_data {
+union value_data {
m_uint num;
m_float fnum;
m_uint* ptr;
struct M_Object_ *obj;
Func func_ref;
-} __attribute__((transparent_union));
+};
struct Value_ {
Type type;
Ast body;
struct ImportCK *ck;
struct OperCK *oper; // _misc
+ uint tmpls;
loc_t loc;
};
}
ANN static inline void set_decl_ref(const Exp e) {
- if(e->exp_type == ae_exp_decl) {
- SET_FLAG(e->d.exp_decl.td, late);
+ if(e->exp_type == ae_exp_decl)
SET_FLAG(e->d.exp_decl.list->self->value, late);
- }
}
const Type base = array_base(t);
ArrayInfo* info = mp_calloc(emit->gwion->mp, ArrayInfo);
vector_init(&info->type);
- for(m_uint i = 1; i < t->array_depth; ++i)
+ info->depth = get_depth(t);
+ for(long i = 1; i < info->depth; ++i)
vector_add(&info->type, (vtype)array_type(emit->env, base, i));
vector_add(&info->type, (vtype)t);
- info->depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth;
info->base = base;
return info;
}
}
ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e, const uint is_ref) {
- CHECK_BO(extend_indices(emit, e, t->array_depth))
+ CHECK_BO(extend_indices(emit, e, get_depth(t)))
ArrayInfo* info = new_arrayinfo(emit, t);
const Instr alloc = emit_add_instr(emit, ArrayAlloc);
alloc->m_val = (m_uint)info;
regseti(emit, count);
const Instr instr = emit_add_instr(emit, ArrayInit);
instr->m_val = (m_uint)type;
- instr->m_val2 = type->array_depth == 1 ? array_base(type)->size : SZ_INT;
+ instr->m_val2 = array_base(type)->size;
emit_gc(emit, -SZ_INT);
emit_notpure(emit);
return GW_OK;
ANN static m_bool emit_cdef(const Emitter, const Type);
ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
- const Type base = get_type(t);
- if(tflag(base, tflag_emit) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+ if(tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK;//clean callers
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
.scope=emit->env->scope->depth, .flag=tflag_emit };
- return envset_run(&es, base);
+ return envset_run(&es, t);
}
ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var))
else
CHECK_BB(emit_exp_decl_global(emit, decl, list->self, r, var))
- if(GET_FLAG(v->type, abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) {
- env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name);
+ if(GET_FLAG(array_base(v->type), abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) {
+ env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name);
}
} while((list = list->next));
return GW_OK;
}
ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
- const Type t = get_type(decl->type);
+ const Type t = decl->type;
CHECK_BB(ensure_emit(emit, t))
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
const Type t = exp_self(unary)->type;
- const Type base = get_type(actual_type(emit->gwion, t));
+ const Type base = actual_type(emit->gwion, t);
CHECK_BB(ensure_emit(emit, base))
// no pos ?
struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
}
ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) {
- regpushi(emit, (m_uint)exp_self(td)->type->info->base_type);
+ regpushi(emit, (m_uint)_class_base(exp_self(td)->type));
return GW_OK;
}
CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to))
if(isa(e->type, emit->gwion->type[et_object]) > 0 &&
(e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
- e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && !exp_getvar(e)) {
+ e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && exp_getuse(e) && !exp_getvar(e)) {
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = -SZ_INT;
}
-
} while((exp = exp->next));
return GW_OK;
}
a->info->owner = type->info->owner;
a->info->owner_class = type->info->owner_class;
a->size = type->size;
- a->info->base_type = type->info->base_type;
a->array_depth = type->array_depth;
a->info->gack = type->info->gack;
return a;
ANN Type array_base(Type type) {
const Type t = typedef_base(type);
- return t->array_depth ? t->info->base_type : t;
+// return t->array_depth ? t->info->base_type : t;
+ return t->array_depth ? array_base(t->info->base_type) : t;
}
-ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) {
- size_t len = strlen(src->name);
+ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) {
+ const Type t = array_base(src);
+ size_t len = strlen(t->name);
char name[len + 2* depth + 1];
- strcpy(name, src->name);
- m_uint i = depth + 1;
+ strcpy(name, t->name);
+ m_uint i = src->array_depth + depth + 1;
while(--i) {
strcpy(name+len, "[]");
len += 2;
return insert_symbol(name);
}
+#include "instr.h"
+#include "operator.h"
+#include "import.h"
ANN Type array_type(const Env env, const Type src, const m_uint depth) {
const Symbol sym = array_sym(env, src, depth);
const Type type = nspc_lookup_type1(src->info->owner, sym);
if(type)
return type;
- const Type parent = src->info->parent ?
- array_type(env, src->info->parent, depth) : env->gwion->type[et_array];
- const Type t = new_type(env->gwion->mp, s_name(sym), parent);
- t->array_depth = depth + src->array_depth;
- t->info->base_type = array_base(src) ?: src;
- t->info->owner = src->info->owner;
- if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) {
- t->nspc = new_nspc(env->gwion->mp, s_name(sym));
- inherit(t);
- t->nspc->info->class_data_size = SZ_INT;
- nspc_allocdata(env->gwion->mp, t->nspc);
- *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
- object_release : struct_release;
- } else
- nspc_addref((t->nspc = parent->nspc));
- mk_class(env, t);
- nspc_add_type_front(src->info->owner, sym, t);
- return t;
+ const size_t tdepth = depth + src->array_depth;
+ const Type base = tdepth > 1 ? array_type(env, src, tdepth-1) : src;
+ struct TemplateScan ts = { .t=base, /*.td=td*/ };
+ struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=env->gwion->type[et_array], .data=(uintptr_t)&ts, .op_type=op_scan };
+ return op_check(env, &opi);
}
ANN m_bool type_ref(Type t) {
env_push_type(env, t);
}
+ANN2(1) void add_template(const Env env, const Type t) {
+ Tmpl* tmpl = t->info->cdef->base.tmpl;
+ if(tmpl) {
+ nspc_push_type(env->gwion->mp, env->curr);//
+ ID_List il = tmpl->list;
+ do nspc_add_type(env->curr, il->xid, env->gwion->type[et_auto]);
+ while((il = il->next));
+ }
+}
+
ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
const Type t = gwi->gwion->env->class_def;
if(ctor)
ANN static Type type_finish(const Gwi gwi, const Type t) {
gwi_add_type(gwi, t);
import_class_ini(gwi->gwion->env, t);
+ if(t->info->cdef && t->info->cdef->base.tmpl) {
+ gwi->tmpls++;
+ add_template(gwi->gwion->env, t);
+ }
return t;
}
if(!gwi->gwion->env->class_def)
GWI_ERR_B(_("import: too many class_end called."))
nspc_allocdata(gwi->gwion->mp, gwi->gwion->env->class_def->nspc);
+ const Type t = gwi->gwion->env->class_def;
+ if(tflag(t, tflag_tmpl)) {
+ --gwi->tmpls;
+ nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
+ }
env_pop(gwi->gwion->env, 0);
return GW_OK;
}
ANEW ANN m_str type2str(const Gwion gwion, const Type t, const loc_t pos NUSED) {
GwText text = { .mp=gwion->mp };
- if(t->info->owner_class)
+ if(t->info->owner_class) {
td_fullname(gwion->env, &text, t->info->owner_class);
+ text_add(&text, ".");
+ }
text_add(&text, t->name);
return text.str;
}
ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
const Func_Def fdef = import_fdef(gwi, ck);
if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
- /*return*/ section_fdef(gwi, fdef);
+ return section_fdef(gwi, fdef);
if(traverse_func_def(gwi->gwion->env, fdef) < 0)
return error_fdef(gwi, fdef);
builtin_func(gwi->gwion->mp, fdef->base->func, ck->addr);
- ck_end(gwi);
return GW_OK;
}
CHECK_BB(ck_ok(gwi, ck_fdef))
gwi->ck->addr = addr;
gwi->ck->flag = flag;
- if(gwi_func_valid(gwi, gwi->ck) > 0)
- return GW_OK;
- return GW_ERROR;
+ const m_bool ret = gwi_func_valid(gwi, gwi->ck);
+ ck_end(gwi);
+ return ret;
}
ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
}
static DTOR(array_dtor) {
- const Type t = o->type_ref;
if(*(void**)(o->data + SZ_INT))
xfree(*(void**)(o->data + SZ_INT));
struct M_Vector_* a = ARRAY(o);
- if(!a)
- return;
- if(t->nspc->info->class_data_size) {
- for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
- (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(a) + i * ARRAY_SIZE(a));
- }
free_m_vector(shred->info->mp, a);
}
+static DTOR(array_dtor_obj) {
+ struct M_Vector_* a = ARRAY(o);
+ for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
+ release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred);
+}
+
+static DTOR(array_dtor_struct) {
+ struct M_Vector_* a = ARRAY(o);
+ for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
+ struct_release(shred, array_base(o->type_ref), &*(m_bit*)(ARRAY_PTR(a) + i * SZ_INT));
+}
+
ANN M_Object new_array(MemPool p, const Type t, const m_uint length) {
const M_Object a = new_object(p, NULL, t);
const m_uint depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth;
const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size;
- ARRAY(a) = new_m_vector(p, size,length);
+ ARRAY(a) = new_m_vector(p, size, length);
return a;
}
}
static MFUN(vm_vector_rem) {
+ const m_int index = *(m_int*)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
+ return;
+ m_vector_rem(v, (vtype)index);
+}
+
+static MFUN(vm_vector_rem_obj) {
+ const m_int index = *(m_int*)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
+ return;
+ release(*(M_Object*)(ARRAY_PTR(v) + index * ARRAY_SIZE(v)), shred);
+ m_vector_rem(v, (vtype)index);
+}
+
+static MFUN(vm_vector_rem_struct) {
const m_int index = *(m_int*)(shred->mem + SZ_INT);
const M_Vector v = ARRAY(o);
if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
return;
const Type t = o->type_ref;
- if(t->nspc->info->class_data_size)
- (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
+ struct_release(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
m_vector_rem(v, (vtype)index);
}
+static MFUN(vm_vector_insert) {
+ const m_int index = *(m_int*)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+ return;
+ const size_t size = ARRAY_SIZE(v);
+ if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+ const m_uint cap = ARRAY_CAP(v) *=2;
+ v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+ }
+ memmove(ARRAY_PTR(v) + (index+1) * size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+ memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+}
+
+static MFUN(vm_vector_insert_obj) {
+ const m_int index = *(m_int*)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+ return;
+ const size_t size = SZ_INT;
+ if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+ const m_uint cap = ARRAY_CAP(v) *=2;
+ v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+ }
+ memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+ memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+ ++(*(M_Object*)(shred->mem + SZ_INT*2))->ref;
+}
+
+static MFUN(vm_vector_insert_struct) {
+ const m_int index = *(m_int*)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+ return;
+ const size_t size = ARRAY_SIZE(v);
+ if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+ const m_uint cap = ARRAY_CAP(v) *=2;
+ v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+ }
+ memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+ memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+ struct_addref(shred->info->vm->gwion, array_base(o->type_ref), shred->mem + SZ_INT*2);
+}
+
ANN m_bit* m_vector_addr(const M_Vector v, const m_uint i) {
return &*(m_bit*)(ARRAY_PTR(v) + i * ARRAY_SIZE(v));
}
*(m_uint*)RETURN = ARRAY_CAP(ARRAY(o));
}
-ANN static Type get_array_type(Type t) {
- while(t->array_depth && t->info->base_type)
- t = t->info->base_type;
- return t;
-}
-
#define ARRAY_OPCK(a, b, pos) \
- const Type l = get_array_type(a->type); \
- const Type r = get_array_type(b->type); \
- if(isa(l, r) < 0) \
+ const Type l = array_base(a->type); \
+ const Type r = array_base(b->type); \
+ if(isa(r, l) < 0) \
ERR_N(pos, _("array types do not match."))
static OP_CHECK(opck_array_at) {
ANN static Type check_array_shift(const Env env,
const Exp a, const Exp b, const m_str str, const loc_t pos) {
- if(a->type == env->gwion->type[et_error] &&
+/* if(a->type == env->gwion->type[et_error] &&
b->type->array_depth > 1)
- return a->type;
+ return a->type;*/
ARRAY_OPCK(a, b, pos)
if(a->type->array_depth == b->type->array_depth + 1)
return a->type;
// check me. use common ancestor maybe
static OP_CHECK(opck_array_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
- Type l = array_base(cast->exp->type);
- Type r = array_base(exp_self(cast)->type);
+ const Type l = array_base(cast->exp->type);
+ const Type r = array_base(exp_self(cast)->type);
if(get_depth(cast->exp->type) == get_depth(exp_self(cast)->type) && isa(l->info->base_type, r->info->base_type) > 0)
return l;
return NULL;
return exp ? emit_array_access(emit, info) : GW_ERROR;
}
+ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth);
+#include "template.h"
+static OP_CHECK(opck_array_scan) {
+ struct TemplateScan *ts = (struct TemplateScan*)data;
+ const Type t_array = env->gwion->type[et_array];
+ const Class_Def c = t_array->info->cdef;
+ const Type base = ts->t != t_array ?
+ ts->t : known_type(env, ts->td->types->td);
+ const Symbol sym = array_sym(env, array_base(base), base->array_depth + 1);
+ const Type type = nspc_lookup_type1(base->info->owner, sym);
+ if(type)
+ return type;
+ const Class_Def cdef = cpy_class_def(env->gwion->mp, c);
+ cdef->base.ext = type2td(env->gwion, t_array, (loc_t){});
+ cdef->base.xid = sym;
+ cdef->base.tmpl->base = 1; // could store depth here?
+ cdef->base.tmpl->call = new_type_list(env->gwion->mp, type2td(env->gwion, base, (loc_t){}), NULL);
+ const m_uint scope = env_push(env, NULL, base->info->owner);
+ (void)scan0_class_def(env, cdef);
+ const Type t = cdef->base.type;
+ (void)traverse_cdef(env, t);
+ env_pop(env, scope);
+ if(GET_FLAG(base, abstract))
+ SET_FLAG(t, abstract);
+ else
+ UNSET_FLAG(t, abstract);
+ set_tflag(t, tflag_emit);
+ t->array_depth = base->array_depth + 1;
+ t->info->base_type = array_base(base);
+ set_tflag(t, tflag_cdef | tflag_tmpl);
+ void* rem = isa(base, env->gwion->type[et_compound]) > 0 ?
+ !tflag(base, tflag_struct) ? vm_vector_rem_obj : vm_vector_rem_struct : vm_vector_rem;
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 0), rem);
+ void* insert = isa(base, env->gwion->type[et_compound]) > 0 ?
+ !tflag(base, tflag_struct) ? vm_vector_insert_obj : vm_vector_insert_struct : vm_vector_insert;
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 1), insert);
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 2), vm_vector_size);
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 3), vm_vector_depth);
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 4), vm_vector_cap);
+ if(isa(base, env->gwion->type[et_compound]) > 0) {
+ t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "array component dtor");
+ set_tflag(t, tflag_dtor);
+ t->nspc->dtor->native_func = (m_uint) (!tflag(base, tflag_struct) ?
+ array_dtor_obj : array_dtor_struct);
+ }
+ unset_tflag(t, tflag_ctor);
+ return t;
+}
+
+static OP_CHECK(opck_array_implicit) {
+ const struct Implicit* imp = (struct Implicit*)data;
+ if(imp->t->array_depth != imp->e->type->array_depth)
+ return env->gwion->type[et_error];
+ if(isa(array_base(imp->e->type), array_base(imp->t)) < 0)
+ return env->gwion->type[et_error];
+ return imp->t;
+}
+
GWION_IMPORT(array) {
- const Type t_array = gwi_class_ini(gwi, "@Array", NULL);
+ const Type t_array = gwi_class_ini(gwi, "Array:[T]", "Object");
gwi->gwion->type[et_array] = t_array;
gwi_class_xtor(gwi, NULL, array_dtor);
GWI_BB(gwi_item_ini(gwi, "@internal", "@array"))
GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data"))
GWI_BB(gwi_item_end(gwi, 0, num, 0))
+ // put functions using T first
+ GWI_BB(gwi_func_ini(gwi, "bool", "remove"))
+ GWI_BB(gwi_func_arg(gwi, "int", "index"))
+ GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none))
+
+ GWI_BB(gwi_func_ini(gwi, "bool", "insert"))
+ GWI_BB(gwi_func_arg(gwi, "int", "index"))
+ GWI_BB(gwi_func_arg(gwi, "T", "data"))
+ GWI_BB(gwi_func_end(gwi, vm_vector_insert, ae_flag_none))
+
GWI_BB(gwi_func_ini(gwi, "int", "size"))
GWI_BB(gwi_func_end(gwi, vm_vector_size, ae_flag_none))
GWI_BB(gwi_func_ini(gwi, "int", "depth"))
GWI_BB(gwi_func_ini(gwi, "int", "cap"))
GWI_BB(gwi_func_end(gwi, vm_vector_cap, ae_flag_none))
- GWI_BB(gwi_func_ini(gwi, "int", "remove"))
- GWI_BB(gwi_func_arg(gwi, "int", "index"))
- GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none))
-
GWI_BB(gwi_class_end(gwi))
- GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_at))
GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_array_implicit))
+ GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Array", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_sl))
GWI_BB(gwi_oper_emi(gwi, opem_array_sl))
GWI_BB(gwi_oper_end(gwi, "<<", NULL))
- GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_sr))
GWI_BB(gwi_oper_emi(gwi, opem_array_sr))
GWI_BB(gwi_oper_end(gwi, ">>", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_cast))
GWI_BB(gwi_oper_end(gwi, "$", NULL))
- GWI_BB(gwi_oper_ini(gwi, "int", "@Array", "int"))
+ GWI_BB(gwi_oper_ini(gwi, "int", "Array", "int"))
GWI_BB(gwi_oper_add(gwi, opck_array_slice))
GWI_BB(gwi_oper_emi(gwi, opem_array_slice))
GWI_BB(gwi_oper_end(gwi, "@slice", NULL))
- GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "int", "Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array))
GWI_BB(gwi_oper_emi(gwi, opem_array_access))
GWI_BB(gwi_oper_end(gwi, "@array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Array", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_array_scan))
+ GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
gwi_register_freearg(gwi, ArrayAlloc, freearg_array);
return GW_OK;
}
GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
GWI_BB(gwi_gack(gwi, t_class, gack_class))
- const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
- GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
set_tflag(t_auto, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
struct SpecialId_ spid = { .type=t_now, .exec=RegPushNow, .is_const=1 };
gwi_specialid(gwi, "now", &spid);
- const Type t_compound = gwi_mk_type(gwi, "@Compound", 0, NULL);
+ const Type t_compound = gwi_mk_type(gwi, "@Compound", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_compound, gack_compound))
GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound))
const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
"template", dt->base->base->tmpl->base);
DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
- if(isa(v->type, env->gwion->type[et_class]) > 0)
+ if(is_class(env->gwion, v->type))
return NULL;
if(vflag(v, vflag_builtin)) {
dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
t1 = info->rhs->def->base->tmpl->list;
nspc_push_type(env->gwion->mp, env->curr);
while(t0) {
- nspc_add_type(env->curr, t0->xid, env->gwion->type[et_undefined]);
- nspc_add_type(env->curr, t1->xid, env->gwion->type[et_undefined]);
+ nspc_add_type(env->curr, t0->xid, env->gwion->type[et_auto]);
+ nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]);
t0 = t0->next;
t1 = t1->next;
}
compound_release(shred, v->type, o->data + v->from->offset);
}
}
- if(tflag(t, tflag_dtor) && t->nspc->dtor) {
- // check flag for array types
+ if(tflag(t, tflag_dtor)) {
if(t->nspc->dtor->builtin)
((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
else {
return exp_self(cast)->type;
}
-static OP_CHECK(opck_implicit_null2obj) {
- const struct Implicit* imp = (struct Implicit*)data;
- return imp->t;
-}
-
-static OP_EMIT(opem_implicit_null2obj) {
- return GW_OK;
-}
-
ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
const Exp_Dot *member = (Exp_Dot*)data;
const m_str str = s_name(member->xid);
const m_bool base_static = is_class(env->gwion, member->base->type);
- const Type the_base = base_static ? member->base->type->info->base_type : member->base->type;
+ const Type the_base = base_static ? _class_base(member->base->type) : member->base->type;
// if(!the_base->nspc)
// ERR_N(&member->base->pos,
// _("type '%s' does not have members - invalid use in dot expression of %s"),
ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
const Class_Def c = info->base->info->cdef;
const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
- c->body ?cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
+ c->body ? cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
cdef->cflag = c->cflag;
cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types);
const m_bool ret = scan0_class_def(env, cdef);
GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
GWI_BB(gwi_oper_add(gwi, opck_object_cast))
GWI_BB(gwi_oper_end(gwi, "$", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
- GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
- GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
+//. GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
+// GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
+// GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
GWI_BB(gwi_oper_emi(gwi, opem_not_object))
GWI_BB(gwi_oper_end(gwi, "!", IntNot))
if(!cast->td->types || !cast->td->types->td)
ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast")
DECL_ON(const Type, t, = known_type(env, cast->td))
- const Type _t = get_type(t);
- if(_t->info->cdef && !tflag(_t, tflag_check))
- CHECK_BN(ensure_traverse(env, _t))
+ if(t->info->cdef && !tflag(t, tflag_check))
+ CHECK_BN(ensure_traverse(env, t))
const Type to = known_type(env, cast->td->types->td);
exp_setvar(cast->exp, 1);
if(isa(cast->exp->type, to) > 0)
if(access)
ERR_N(e->pos, _("can't cast %s value to Ptr"), access);
exp_setvar(e, 1);
- const Type t = get_type(imp->t);
+ const Type t = imp->t;
if(!tflag(t, tflag_check))
CHECK_BN(traverse_class_def(env, t->info->cdef))
return imp->t;
return GW_OK;
}
-ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Value v) {
- if(!exp_getvar(exp_self(decl)) && (GET_FLAG(v->type, abstract) ||
- GET_FLAG(decl->td, late) || is_fptr(gwion, v->type))) {
+ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Var_Decl var) {
+ const Value v = var->value;
+ const uint array_ref = (decl->td->array && !decl->td->array->exp) || (var->array && !var->array->exp);
+ if(!exp_getvar(exp_self(decl)) && (GET_FLAG(array_base(v->type), abstract) ||
+ GET_FLAG(decl->td, late) || is_fptr(gwion, v->type) || array_ref)) {
SET_FLAG(v, late);
} else
UNSET_FLAG(v, late);
CHECK_BB(check_var_td(env, var, decl->td))
if(is_fptr(env->gwion, decl->type))
CHECK_BB(check_fptr_decl(env, var))
- set_late(env->gwion, decl, list->self->value);
+ set_late(env->gwion, decl, list->self);
set_vflag(var->value, vflag_valid);
//set_vflag(var->value, vflag_used));
nspc_add_value(env->curr, var->xid, var->value);
}
ANN static inline m_bool ensure_check(const Env env, const Type t) {
- const Type base = get_type(t);
- if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+ if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
.scope=env->scope->depth, .flag=tflag_check };
- return envset_run(&es, base);
+ return envset_run(&es, t);
}
ANN m_bool ensure_traverse(const Env env, const Type t) {
- const Type base = get_type(t);
- if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+ if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
.scope=env->scope->depth, .flag=tflag_check };
- return envset_run(&es, base);
+ return envset_run(&es, t);
}
ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
if(!decl->type)
ERR_O(decl->td->pos, _("can't find type"));
{
- const Type t = get_type(decl->type);
- CHECK_BO(inferable(env, t, decl->td->pos))
- CHECK_BO(ensure_check(env, t))
+ CHECK_BO(inferable(env, decl->type, decl->td->pos))
+ CHECK_BO(ensure_check(env, decl->type))
}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
CHECK_OO(func->next);
return find_func_match_actual(env, func->next, args, implicit, specific);
}
- if(e1->type == env->gwion->type[et_undefined] ||
+ if(e1->type == env->gwion->type[et_auto] ||
(func->def->base->tmpl && is_fptr(env->gwion, func->value_ref->type) > 0)) {
const Type owner = func->value_ref->from->owner_class;
if(owner)
const Type ret = op_check(env, &opi);
if(!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
bin->rhs->d.exp_decl.list->self->value->type = env->gwion->type[et_auto];
+ exp_setuse(bin->lhs, 1);
+ exp_setuse(bin->rhs, 1);
return ret;
}
struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp),
.data=(uintptr_t)post, .pos=exp_self(post)->pos, .op_type=op_postfix };
CHECK_OO(opi.lhs)
+ exp_setuse(post->exp, 1);
const Type t = op_check(env, &opi);
if(t && isa(t, env->gwion->type[et_object]) < 0)
exp_setmeta(exp_self(post), 1);
ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
const Type rhs = unary->unary_type == unary_exp ? check_exp(env, unary->exp) : NULL;
- if(unary->unary_type == unary_exp)
+ if(unary->unary_type == unary_exp) {
CHECK_OO(rhs)
+ exp_setuse(unary->exp, 1);
+ }
struct Op_Import opi = { .op=unary->op, .rhs=rhs,
.data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary };
DECL_OO(const Type, ret, = op_check(env, &opi))
- const Type t = get_type(actual_type(env->gwion, ret));
+ const Type t = actual_type(env->gwion, ret);
CHECK_BO(ensure_traverse(env, t))
return ret;
}
}
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
- DECL_OB(const Type, ptr, = foreach_type(env, stmt->exp))
- const Type base = get_type(ptr);
+ DECL_OB(const Type, base, = foreach_type(env, stmt->exp))
CHECK_BB(ensure_traverse(env, base))
- char c[15 + strlen(ptr->name)];
- sprintf(c, "@Foreach:[%s]", ptr->name);
+ char c[15 + strlen(base->name)];
+ sprintf(c, "@Foreach:[%s]", base->name);
const Type ret = str2type(env->gwion, c, stmt->exp->pos);
- if(ptr->array_depth)
+ if(base->array_depth)
set_tflag(ret, tflag_typedef);
stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
set_vflag(stmt->v, vflag_valid);
ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->info->parent;
const Type_Decl *td = cdef->base.ext;
- if(td->array)
+// if(td->array)
+ if(td->array && td->array->exp)
CHECK_BB(check_subscripts(env, td->array, 1))
CHECK_BB(ensure_check(env, parent))
- if(tflag(parent, tflag_typedef)) {
- set_tflag(cdef->base.type, tflag_typedef);
- }
+// if(tflag(parent, tflag_typedef)) {
+// set_tflag(cdef->base.type, tflag_typedef);
+// }
return GW_OK;
}
return GW_OK;
}
+ANN static inline Type op_parent(const Env env, const Type t) {
+ const size_t depth = t->array_depth;
+ return !depth || !array_base(t)->info->parent ?
+ t->info->parent :
+ array_type(env, array_base(t)->info->parent, depth);
+}
+
ANN static Type op_check_inner(struct OpChecker* ock, const uint i) {
Type t, r = ock->opi->rhs;
do {
return NULL;
return ret;
}
- } while(l && (l = l->info->parent));
+ } while(l && (l = op_parent(env, l)));
} while((nspc = nspc->parent));
}
if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
} else if(mo->func || mo->instr)
return handle_instr(emit, mo);
}
- } while(r && (r = r->info->parent));
- } while(l && (l = l->info->parent));
+ } while(r && (r = op_parent(emit->env, r)));
+ } while(l && (l = op_parent(emit->env, l)));
} while((nspc = nspc->parent));
}
return GW_ERROR;
if(parent == (Type)GW_ERROR)
return NULL;
const Type t = scan0_type(env, s_name(cdef->base.xid), parent);
- if(cflag(cdef, cflag_struct))
+ if(cflag(cdef, cflag_struct)) {
+ t->size = 0;
set_tflag(t, tflag_struct);
+ }
t->info->tuple = new_tupleform(env->gwion->mp, parent);
t->info->owner = env->curr;
t->info->owner_class = env->class_def;
c->base.type = cdef->base.type;
c->base.type->info->cdef = cdef;
set_tflag(c->base.type, tflag_cdef);
- set_tflag(cdef->base.type, tflag_scan0);// redundant
}
return ret;
}
}
ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
- const Type base = get_type(t);
- if(tflag(base, tflag_scan1) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+ if(tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
.scope=env->scope->depth, .flag=tflag_scan1 };
- return envset_run(&es, base);
+ return envset_run(&es, t);
}
ANN static Type scan1_type(const Env env, Type_Decl* td) {
- DECL_OO(const Type, type, = known_type(env, td))
- const Type t = get_type(type);
+ DECL_OO(const Type, t, = known_type(env, td))
if(!env->func && env->class_def && !GET_FLAG(td, late))
CHECK_BO(type_cyclic(env, t, td))
CHECK_BO(ensure_scan1(env, t))
- return type;
+ return t;
}
ANN static Type void_type(const Env env, Type_Decl* td) {
ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
Var_Decl_List list = decl->list;
+ const uint decl_ref = array_ref(decl->td->array);
do {
const Var_Decl var = list->self;
CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
CHECK_BB(scan1_exp(env, var->array->exp))
t = array_type(env, decl->type, var->array->depth);
}
- if(t->array_depth && GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp)
+ if(GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp)
|| (decl->td->array && decl->td->array->exp)))
ERR_B(var->pos, _("arrays of abstract type '%s' must be declared empty"),
array_base(t)->name);
if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late))
SET_FLAG(v, late);
v->type = t;
- if(array_ref(var->array))
- SET_FLAG(decl->td, late);
+ if(decl_ref || array_ref(var->array))
+ SET_FLAG(v, late);
v->flag |= decl->td->flag;
if(!env->scope->depth) {
valuefrom(env, v->from);
ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
- if(array_ref(decl->td->array))
- SET_FLAG(decl->td, late);
CHECK_OB(decl->type)
const m_bool global = GET_FLAG(decl->td, global);
if(global) {
ANN static m_bool _scan1_fdef_base_tmpl(const Env env, Func_Base *base) {
ID_List id = base->tmpl->list;
- do nspc_add_type(env->curr, id->xid, env->gwion->type[et_undefined]);
+ do nspc_add_type(env->curr, id->xid, env->gwion->type[et_auto]);
while((id = id->next));
CHECK_OB((base->ret_type = known_type(env, base->td)))
if(base->args) {
ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
const loc_t pos = cdef->base.ext->pos;
- if(cdef->base.ext->array)
+ if(cdef->base.ext->array && cdef->base.ext->array->exp)
CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
if(isa(parent, env->gwion->type[et_object]) < 0)
ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
- const Type base = get_type(t);
- if(tflag(base, tflag_scan2) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+ if(tflag(t, tflag_scan2) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
.scope=env->scope->depth, .flag=tflag_scan2 };
- return envset_run(&es, base);
+ return envset_run(&es, t);
}
ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
- const Type t = get_type(decl->type);
+ const Type t = decl->type;
CHECK_BB(ensure_scan2(env, t))
Var_Decl_List list = decl->list;
do {
if(!fbflag(f->base, fbflag_internal))
ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
}
- const Func obase = !fptr ? overload->d.func_ref : overload->type->info->base_type->info->func;
+ const Func obase = !fptr ? overload->d.func_ref : _class_base(overload->type)->info->func;
if(GET_FLAG(obase->def->base, final))
ERR_B(f->pos, _("can't overload final function %s"), overload->name)
const m_bool base = tmpl_base(f->base->tmpl);
ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->info->parent;
CHECK_BB(ensure_scan2(env, parent))
- if(cdef->base.ext->array)
+ if(cdef->base.ext->array && cdef->base.ext->array->exp)
CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
return GW_OK;
}
return ret;
}
-__attribute__((returns_nonnull))
-ANN Type get_type(const Type t) {
- const Type type = !t->array_depth ? t : array_base(t);
- return type;
-}
-
-ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type t,
const _exp_func f_cdef, const _exp_func f_union) {
- const Type t = get_type(base);
if(t->info->parent != env->gwion->type[et_union])
return f_cdef(opt, t->info->cdef);
const m_bool ret = f_union(opt, t->info->udef);
return op_check(env, &opi);
} else if(td->types)
return maybe_func(env, t, td);
- Type_Decl *next = td->next;
- td->next = NULL;
- const Type ret = find_type(env, td);
- td->next = next;
- return ret;
+ return find_type(env, td);
}
ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {