const envset_func func;
const void *data;
const m_int scope;
- const ae_flag flag;
+ const enum tflag flag;
m_bool run;
};
#ifndef __FUNC
#define __FUNC
+
+enum fflag {
+ fflag_none = 1 << 0,
+ fflag_pure = 1 << 1,
+ fflag_ftmpl = 1 << 2,
+ fflag_tmpl = 1 << 3,
+ fflag_valid = 1 << 4,
+} __attribute__((packed));
+
struct Func_ {
m_str name;
Func_Def def;
size_t vt_index;
HAS_OBJ
ae_flag flag;
+ enum fflag fflag;
};
+static inline int fflag(const Func f, const enum fflag flag) {
+ return (f->fflag & flag) == flag;
+}
+#ifndef __cplusplus
+static inline void set_fflag(const Func f, const enum fflag flag) {
+ f->fflag |= flag;
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+ f->fflag &= ~flag;
+}
+#else
+static inline void set_fflag(const Func f, const enum fflag flag) {
+ const auto ff = f->fflag | flag;
+ f->fflag = static_cast<enum fflag>(ff);
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+ const auto ff = f->fflag & ~flag;
+ f->fflag = static_cast<enum fflag>(ff);
+}
+#endif
+
ANEW ANN Func new_func(MemPool, const m_str, const Func_Def);
ANN2(1,2) Symbol func_symbol(const Env, const m_str, const m_str, const m_str, const m_uint);
ANN m_bool check_lambda(const Env, const Type, Exp_Lambda*);
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr);
#endif
Type parent;
Nspc owner;
Type owner_class;
- Class_Def def;
+ union {
+ Union_Def udef;
+ Class_Def cdef;
+ };
union type_data {
Func func;
Type base_type;
struct Context_ *ctx;
};
+enum tflag {
+ tflag_none = 1 << 0,
+ tflag_scan0 = 1 << 1,//
+ tflag_scan1 = 1 << 2,//
+ tflag_scan2 = 1 << 3,//
+ tflag_check = 1 << 4,//
+ tflag_emit = 1 << 5,//
+ tflag_infer = 1 << 6,
+ tflag_empty = 1 << 7,
+ tflag_ftmpl = 1 << 8,
+ tflag_ntmpl = 1 << 9, // do NOT need types
+ tflag_ctmpl = 1 << 10, // child template
+ tflag_udef = 1 << 11,
+ tflag_cdef = 1 << 12,
+ tflag_struct = 1 << 13,
+ tflag_ctor = 1 << 14,
+ tflag_dtor = 1 << 15,
+ tflag_tmpl = 1 << 16,
+ tflag_typedef = 1 << 17,
+ tflag_nonnull = 1 << 18,
+ tflag_force = 1 << 19,
+} __attribute__((packed));
+
struct Type_ {
m_str name;
Nspc nspc;
size_t array_depth;
HAS_OBJ
ae_flag flag;
+ enum tflag tflag;
};
+ANN static inline int tflag(const Type t, const enum tflag flag) {
+ return (t->tflag & flag) == flag;
+}
+static inline int safe_tflag(const Type t, const enum tflag flag) {
+ return t ? ((t->tflag & flag) == flag) : 0;
+}
+#ifndef __cplusplus
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+ t->tflag |= flag;
+}
+#else
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+ auto ff = t->tflag | flag;
+ t->tflag = static_cast<enum tflag>(ff);
+}
+#endif
ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
ANEW ANN Type type_copy(MemPool, const Type type);
ANN m_str get_type_name(const Env, const Type t, const m_uint);
__attribute__((returns_nonnull))
ANN Type get_type(const Type t);
ANN static inline int is_special(const Type t) {
- return GET_FLAG(t, nonnull) || GET_FLAG(t, force);
+ return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
}
typedef enum {
size_t offset;
};
+enum vflag {
+ vflag_none = 1 << 0,
+ vflag_func = 1 << 1,
+ vflag_union = 1 << 2,
+ vflag_enum = 1 << 3,
+ vflag_freeme = 1 << 4,
+ vflag_fglobal = 1 << 5,
+ vflag_valid = 1 << 6,
+ vflag_direct = 1 << 7,
+ vflag_builtin = 1 << 8,
+ vflag_member = 1 << 9
+// vflag_used = 1 << 3
+} __attribute__((packed));
+
struct Value_ {
Type type;
m_str name;
} d;
HAS_OBJ
ae_flag flag;
+ enum vflag vflag;
};
+static inline int vflag(const Value v, const enum vflag flag) {
+ return (v->vflag & flag) == flag;
+}
+
+#ifndef __cplusplus
+static inline void set_vflag(const Value v, const enum vflag flag) {
+ v->vflag |= flag;
+}
+#else
+static inline void set_vflag(const Value v, const enum vflag flag) {
+ auto ff = v->vflag | flag;
+ v->vflag = static_cast<enum vflag>(ff);
+}
+#endif
+
ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
ANN void valuefrom(const Env, struct ValueFrom_*);
#endif
ID_List curr;// enum
};
ae_flag flag; // ????
+ uint variadic;
enum importck_type type;
} ImportCK;
Nspc owner;
size_t vt_index;
Type_List tl;
+ void* xfun;// (type is f_xfun)
};
ANN void free_dottmpl(struct dottmpl_*);
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt);
ANN m_uint union_push(const Env, const Union_Def);
ANN void union_pop(const Env, const Union_Def, const m_uint);
-ANN void union_flag(const Union_Def, const ae_flag);
+ANN void union_flag(const Union_Def, const enum tflag);
ANN m_bool check_stmt(const Env env, const Stmt stmt);
typedef m_bool (*_exp_func)(const void*, const void*);
}
#define env_body(a,b,c) env_body(a,b,(_exp_func)c)
-ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
+ANN m_bool scanx_cdef(const Env, void *, const Type,
const _exp_func f_cdef, const _exp_func f_union);
-#define xxx_cdef(prefix) \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
- return scanx_cdef(env, env, cdef, \
- (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
+#define xxx_cdef(prefix) \
+static inline m_bool prefix##_cdef(const Env env, const Type t) { \
+ return scanx_cdef(env, env, t, \
+ (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
}
-#define xxx_cdef_flag(prefix) \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
- SET_FLAG(cdef, prefix); \
- return scanx_cdef(env, env, cdef, \
- (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
-}
-xxx_cdef_flag(scan0)
-xxx_cdef_flag(scan1)
-xxx_cdef_flag(scan2)
-xxx_cdef_flag(check)
+xxx_cdef(scan0)
+xxx_cdef(scan1)
+xxx_cdef(scan2)
+xxx_cdef(check)
xxx_cdef(traverse)
ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
m_str name;
HAS_OBJ
ae_flag flag;
+ int builtin;
};
typedef struct Shreduler_* Shreduler;
struct ShredTick_ * tick;
struct ShredInfo_ * info;
};
-ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name);
+ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const int builtin, const m_str name);
ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
ANN static void clean_func_def(Clean *a, Func_Def b) {
clean_func_base(a, b->base);
++a->scope;
- if(b->d.code && !GET_FLAG(b->base, builtin))
+ if(b->d.code && !(b->base->func && vflag(b->base->func->value_ref, vflag_builtin)))
clean_stmt(a, b->d.code);
else
b->d.code = NULL;
if(isa(t, emit->gwion->type[et_object]) > 0) {
const Instr instr = emit_add_instr(emit, ObjectRelease);
instr->m_val = offset + vector_at(&type->e->tuple->offset, i);
- } else if(GET_FLAG(t, struct))
+ } else if(tflag(t, tflag_struct))
struct_pop(emit, t, offset + vector_at(&type->e->tuple->offset, i));
}
}
Frame *frame = emit->code->frame;
DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
frame->curr_offset -= l->type->size;
- if(GET_FLAG(l->type, struct)) {
+ if(tflag(l->type, tflag_struct)) {
struct_pop(emit, l->type, l->offset);
return frame_pop(emit);
}
ANN void emit_ext_ctor(const Emitter emit, const Type t);
ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
- if(!is_special(t) && GET_FLAG(t, ctor))
+ if(!is_special(t) && tflag(t, tflag_ctor))
emit_ext_ctor(emit, t);
}
if(type->e->parent)
emit_pre_ctor(emit, type->e->parent);
maybe_ctor(emit, type);
- if(GET_FLAG(type, typedef) && type->e->parent->array_depth)
- emit_array_extend(emit, type->e->parent, type->e->def->base.ext->array->exp);
+ if(tflag(type, tflag_typedef) && type->e->parent->array_depth)
+ emit_array_extend(emit, type->e->parent, type->e->cdef->base.ext->array->exp);
}
#define regxxx(name, instr) \
const m_uint start_index = emit_code_size(emit);
const Instr top = emit_add_instr(emit, ArrayTop);
top->m_val2 = (m_uint)type;
- if(GET_FLAG(type, struct)) {
+ if(tflag(type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, ArrayStruct);
instr->m_val = type->size;
}
emit_pre_ctor(emit, type);
- if(!GET_FLAG(type, struct))
+ if(!tflag(type, tflag_struct))
emit_add_instr(emit, ArrayBottom);
else
regpop(emit, SZ_INT);
ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
const Value v = prim_self(data)->value;
- if(GET_FLAG(v, union)) {
+ if(vflag(v, vflag_direct)) {
const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), dotstatic);
instr->m_val = (m_uint)v->d.ptr;
}
if(v->from->owner_class)
return emit_symbol_owned(emit, data);
- if(GET_FLAG(v, builtin) || GET_FLAG(v, union) || GET_FLAG(v, enum))
+ if(vflag(v, vflag_builtin) || vflag(v, vflag_direct) || vflag(v, vflag_enum))
return emit_symbol_builtin(emit, data);
const m_uint size = v->type->size;
- const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !GET_FLAG(v, global) ? regpushmem : regpushbase);
+ const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
instr->m_val = v->from->offset;
return GW_OK;
}
}
ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
- if(GET_FLAG(info->array.type, typedef)) {
+ if(tflag(info->array.type, tflag_typedef)) {
info->array.type = info->array.type->e->parent;
return emit_array_access(emit, info);
}
regseti(emit, (m_uint)e->info->type);
interp_size(emit, e->info->type);
const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
- if(isobj && !GET_FLAG(e->info->type, force))
+ if(isobj && !tflag(e->info->type, tflag_force))
emit_add_instr(emit, GackType);
const Instr instr = emit_add_instr(emit, Gack);
instr->m_val = emit_code_offset(emit);
}
ANN static inline int struct_ctor(const Value v) {
- return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor;
+ return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor;
}
ANN static void decl_expand(const Emitter emit, const Type t) {
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_obj || (is_ref && !is_array)) ? emit_var : 1;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
f_instr *exec = (f_instr*)allocmember;
- if(!GET_FLAG(v, member)) {
+ if(!vflag(v, vflag_member)) {
v->from->offset = emit_local(emit, type);
exec = (f_instr*)(allocword);
- if(GET_FLAG(v, ref)) { // ref or emit_var ?
+ if(GET_FLAG(decl->td, ref)) { // ref or emit_var ?
const Instr clean = emit_add_instr(emit, MemSetImm);
clean->m_val = v->from->offset;
}
}
- const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
+ const Instr instr = !(safe_tflag(emit->env->class_def, tflag_struct) && !emit->env->scope->depth) ?
emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
instr->m_val = v->from->offset;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
if(!emit_var)
emit_add_instr(emit, Assign);
else {
instr->m_val = -SZ_INT;
}
const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
- if(missing_depth && !GET_FLAG(decl->td, force)) {
+ if(missing_depth) {
const Instr push = emit_add_instr(emit, Reg2Reg);
push->m_val = -(missing_depth) * SZ_INT;
}
const m_bool is_array = array && array->exp;
const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
- SET_FLAG(v, union);
+if(isa(type, emit->gwion->type[et_union]) < 0)
+ set_vflag(v, vflag_direct);// mpalloc
instr->m_val = (m_uint)v->d.ptr;
instr->m_val2 = v->type->size;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
const Instr assign = emit_add_instr(emit, Assign);
const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
- if(missing_depth && !GET_FLAG(decl->td, force)) {
+ if(missing_depth) {
const Instr push = emit_add_instr(emit, Reg2Reg);
push->m_val = -(missing_depth) * SZ_INT;
}
}
ANN static m_bool emit_class_def(const Emitter, const Class_Def);
-ANN static m_bool emit_cdef(const Emitter, const Class_Def);
+ANN static m_bool emit_cdef(const Emitter, const Type);
ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+ .scope=emit->env->scope->depth, .flag=tflag_emit };
return envset_run(&es, t);
}
ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
const Type t = get_type(decl->type);
- if(!GET_FLAG(t, emit) && t->e->def)
+ if(!tflag(t, tflag_emit))
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);
CHECK_BB(emit_exp(emit, exp_call->args))
emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
}
- if(exp_call->m_func && GET_FLAG(exp_call->m_func->def->base, variadic))
+ if(exp_call->m_func && fbflag(exp_call->m_func->def->base, fbflag_variadic))
emit_func_arg_vararg(emit, exp_call);
return GW_OK;
}
const Instr instr = emit_add_instr(emit, Reg2RegAddr);
instr->m_val = -SZ_INT;
instr->m_val2 = -SZ_INT;
- } else if(!exp_call->m_func && GET_FLAG(e->info->type, struct))
+ } else if(!exp_call->m_func && tflag(e->info->type, tflag_struct))
regpop(emit, SZ_INT);
return GW_OK;
}
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
const m_uint scope = emit->env->scope->depth;
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=scope, .flag=ae_flag_emit };
+ .scope=scope, .flag=tflag_emit };
CHECK_BB(envset_push(&es, dt->owner_class, dt->owner))
(void)emit_push(emit, dt->owner_class, dt->owner);
const m_bool ret = traverse_emit_func_def(emit, dt->def);
const Value v = f->value_ref;
const size_t scope = emit->env->scope->depth;
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=scope, .flag=ae_flag_emit };
+ .scope=scope, .flag=tflag_emit };
CHECK_BB(envset_push(&es, v->from->owner_class, v->from->owner))
(void)emit_push(emit, v->from->owner_class, v->from->owner);
const m_bool ret = emit_func_def(emit, f->def);
}
ANN static void emit_args(const Emitter emit, const Func f) {
- const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
if((f->def->stack_depth - member) == SZ_INT) {
const Instr instr = emit_add_instr(emit, Reg2Mem);
instr->m_val = member;
ANN static Instr emit_call(const Emitter emit, const Func f) {
const Instr prelude = get_prelude(emit, f);
prelude->m_val = f->def->stack_depth;
- const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
if(member) {
const Instr instr = emit_add_instr(emit, Reg2Mem);
instr->m_val2 = f->def->stack_depth - SZ_INT;
}
ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
- if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
- if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
+ const int tmpl = fflag(f, fflag_tmpl);
+ if(!f->code || (fflag(f, fflag_ftmpl) && !vflag(f->value_ref, vflag_builtin))) {
+ if(tmpl && !is_fptr(emit->gwion, f->value_ref->type)) {
if(emit->env->func != f)
CHECK_BO(emit_template_code(emit, f))
else { // recursive function. (maybe should be used only for global funcs)
back->m_val = 0;
}
} else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
- if(GET_FLAG(f->def->base, op)) {
+ if(fbflag(f->def->base, fbflag_op)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
back->m_val = (m_uint)f;
} else {
instr->m_val2 = -SZ_INT;
}
}
- } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) ||
- !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
+ } else if((f->value_ref->from->owner_class && tflag(f->value_ref->from->owner_class, tflag_struct)) ||
+ !f->value_ref->from->owner_class || (tmpl &&
!is_fptr(emit->gwion, f->value_ref->type)))
push_func_code(emit, f);
else if(vector_size(&emit->code->instr)) {
if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
back->m_val = f->vt_index;
}
- if(vector_size(&emit->code->instr) && GET_FLAG(f, member) &&
+ if(vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
is_fptr(emit->gwion, f->value_ref->type)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
m_bit exec = back->opcode;
emit->code->stack_depth += SZ_INT;
}
-static inline void stack_alloc_this(const Emitter emit) {
- SET_FLAG(emit->code, member);
- stack_alloc(emit);
-}
-
static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
++emit->env->scope->depth;
emit_push_scope(emit);
}
ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) {
- if(GET_FLAG(exp->m_func, member))
- SET_FLAG(emit->code, member);
return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
}
ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *sp) {
emit_add_instr(emit, RegPushImm);
push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos);
- if(SAFE_FLAG(emit->env->func, member))
- stack_alloc_this(emit);
+ if(emit->env->func && vflag(emit->env->func->value_ref, vflag_member))
+ stack_alloc(emit);
return scoped_stmt(emit, sp->code, 0);
}
ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
const Func f = sp->exp->d.exp_call.m_func;
- if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+ if(vflag(f->value_ref, vflag_member) && is_fptr(emit->gwion, f->value_ref->type)) {
regpush(emit, SZ_INT*2);
// (re-)emit owner
if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
const Type t = exp_self(unary)->info->type;
const Type base = get_type(actual_type(emit->gwion, t));
- if(base->e->def && !GET_FLAG(base, emit))
+ if(base->e->cdef && !tflag(base, tflag_emit)) // ???
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_lambda(const Emitter emit, const Exp_Lambda * lambda) {
CHECK_BB(emit_func_def(emit, lambda->def))
- if(GET_FLAG(lambda->def->base, member) && !exp_getvar(exp_self(lambda)))
+ if(vflag(lambda->def->base->func->value_ref, vflag_member) && !exp_getvar(exp_self(lambda)))
emit_add_instr(emit, RegPushMem);
regpushi(emit, (m_uint)lambda->def->base->func->code);
return GW_OK;
return GW_OK;
}
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+ .scope=emit->env->scope->depth, .flag=tflag_emit };
CHECK_BB(envset_push(&es, lambda->owner, lambda->def->base->func->value_ref->from->owner))
const m_bool ret = emit_lambda(emit, lambda);
if(es.run)
const Instr instr = emit_addref(emit, emit_var);
instr->m_val = size;
instr->m_val2 = vector_at(&type->e->tuple->offset, i);
- } else if(GET_FLAG(t, struct))
+ } else if(tflag(t, tflag_struct))
struct_addref(emit, t, size, offset + vector_at(&type->e->tuple->offset, i), emit_var);
}
}
(exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
const Instr instr = emit_addref(emit, exp_getvar(exp));
instr->m_val = size;
- } else if(GET_FLAG(exp->info->type, struct)) // check cast_to ?
+ } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
}
}
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
- return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : GW_OK;
+ return tdef->type->e->cdef ? emit_class_def(emit, tdef->type->e->cdef) : GW_OK;
}
ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
if(global) {
const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
udef->value->d.ptr = (m_uint*)o;
- SET_FLAG(udef->value, builtin);
- UNSET_FLAG(udef->value, union);
+ set_vflag(udef->value, vflag_builtin);
}
scope = emit_push_type(emit, udef->value->type);
} else if(udef->type_xid) {
void* ptr = (void*)xcalloc(1, udef->s);
l = udef->l;
udef->value->d.ptr = ptr;
- SET_FLAG(udef->value, enum);
- SET_FLAG(udef->value, dtor);
+ udef->value->vflag |= (vflag_enum | vflag_freeme);
do {
Var_Decl_List list = l->self->d.exp_decl.list;
list->self->value->d.ptr = ptr;
- SET_FLAG(list->self->value, union);
+ set_vflag(list->self->value, vflag_direct);// xcalloc
} while((l = l->next));
- SET_FLAG(udef->l->self->d.exp_decl.list->self->value, enum);
- SET_FLAG(udef->l->self->d.exp_decl.list->self->value, dtor);
+ udef->l->self->d.exp_decl.list->self->value->vflag |= (vflag_enum | vflag_freeme);
}
if(udef->xid)
regpop(emit, SZ_INT);
emit_union_offset(udef->l, udef->o);
if(udef->xid || udef->type_xid || global)
emit_pop(emit, scope);
- union_flag(udef, ae_flag_emit);
+ union_flag(udef, tflag_emit);
return GW_OK;
}
instr->m_val = val;
}
vector_clear(&emit->code->stack_return);
- if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) {
+ if(emit->info->memoize && fflag(emit->env->func, fflag_pure)) {
const Instr instr = emit_add_instr(emit, MemoizeStore);
instr->m_val = emit->env->func->def->stack_depth;
}
}
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
- if(GET_FLAG(func->def->base, typedef))
+ if(fbflag(func->def->base, fbflag_internal))
return emit_internal(emit, func);
else
return finalyze(emit, FuncReturn);
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
if(fdef->base->args)
emit_func_def_args(emit, fdef->base->args);
- if(GET_FLAG(fdef->base, variadic))
+ if(fbflag(fdef->base, fbflag_variadic))
stack_alloc(emit);
if(fdef->d.code)
CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
}
ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
- if(emit->info->memoize && GET_FLAG(fdef->base->func, pure))
+ if(emit->info->memoize && fflag(fdef->base->func, fflag_pure))
CHECK_BB(emit_memoize(emit, fdef))
CHECK_BB(emit_func_def_body(emit, fdef))
emit_func_def_return(emit);
func->code = emit_func_def_code(emit, func);
if(fdef_is_file_global(emit, fdef))
emit_func_def_global(emit, func->value_ref);
- if(emit->info->memoize && GET_FLAG(func, pure))
+ if(emit->info->memoize && fflag(func, fflag_pure))
func->code->memoize = memoize_ini(emit, func);
}
const Func former = emit->env->func;
if(func->code || tmpl_base(fdef->base->tmpl))
return GW_OK;
- if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
+ if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
return GW_OK;
if(fdef_is_file_global(emit, fdef))
func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
emit_func_def_init(emit, func);
- if(GET_FLAG(func, member))
- stack_alloc_this(emit);
+ if(vflag(func->value_ref, vflag_member))
+ stack_alloc(emit);
emit->env->func = func;
emit_push_scope(emit);
if(!strcmp(s_name(fdef->base->xid), "@gack")) {
char c[len];
snprintf(c, len, "class %s", name);
emit_push_code(emit, c);
- stack_alloc_this(emit);
+ stack_alloc(emit);
return emit->code;
}
ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
- return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
+ return !tflag(parent, tflag_emit) ? ensure_emit(emit, parent) : GW_OK;
}
-ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
- return scanx_cdef(emit->env, emit, cdef,
+ANN static inline m_bool emit_cdef(const Emitter emit, const Type t) {
+ return scanx_cdef(emit->env, emit, t,
(_exp_func)emit_class_def, (_exp_func)emit_union_def);
}
-ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
- nspc->pre_ctor = finalyze(emit, FuncReturn);
- SET_FLAG(nspc->pre_ctor, ctor);
-}
-
ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
if(cdef->base.tmpl && cdef->base.tmpl->list)
CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, emit))
+ if(tflag(t, tflag_emit))
return GW_OK;
- SET_FLAG(t, emit);
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
+ set_tflag(t, tflag_emit);
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_emit))
CHECK_BB(ensure_emit(emit, t->e->owner_class))
- if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
+ if(cdef->base.ext && t->e->parent->e->cdef && !tflag(t->e->parent, tflag_emit)) // ?????
CHECK_BB(cdef_parent(emit, cdef))
nspc_allocdata(emit->gwion->mp, t->nspc);
if(cdef->body) {
emit_class_code(emit, t->name);
if(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit) > 0)
- emit_class_finish(emit, t->nspc);
+ t->nspc->pre_ctor = finalyze(emit, FuncReturn);
else {
free_code(emit->gwion->mp, emit->code);
emit_pop_code(emit);
static ANEW ANN VM_Code emit_code(const Emitter emit) {
Code* const c = emit->code;
- const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
- c->flag, c->name);
+ const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth, 0, c->name);
return code;
}
const Type v_type = type_copy(env->gwion->mp, env->gwion->type[et_class]);
ADD_REF(v_type);
v_type->e->d.base_type = type;
- SET_FLAG(type, builtin);
const Symbol sym = insert_symbol(type->name);
nspc_add_type_front(env->curr, sym, type);
const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
- SET_FLAG(v, valid | ae_flag_const | ae_flag_global | ae_flag_builtin);
+ SET_FLAG(v, const | ae_flag_global);
+ set_vflag(v, vflag_valid | vflag_builtin);
nspc_add_value(env->curr, insert_symbol(type->name), v);
v->from->owner = type->e->owner = env->curr;
v->from->owner_class = type->e->owner_class = env->class_def; // t owner_class ?
t->e->parent = t_class;
t->e->ctx = base->e->ctx;
t->e->d.base_type = base;
- SET_FLAG(t, infer);
+ set_tflag(t, tflag_infer);
return t;
}
const Symbol sym = insert_symbol(base->name);
const Value v = new_value(env->gwion->mp, t, s_name(sym));
valuefrom(env, v->from);
- SET_FLAG(v, const | ae_flag_valid);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_valid);
nspc_add_value_front(base->e->owner, sym, v);
return v;
}
}
ANN static m_bool push(struct EnvSet *es, const Type t) {
+ es->env->scope->depth = 0;
if(t->e->owner_class)
CHECK_BB(push(es, t->e->owner_class))
else
env_push(es->env, NULL, t->e->ctx ? t->e->ctx->nspc : es->env->curr);
- if(es->func && !(t->flag & es->flag))
- CHECK_BB(es->func((void*)es->data, t->e->def))
- if(GET_FLAG(t, template))
- CHECK_BB(template_push_types(es->env, t->e->def->base.tmpl))
+ if(es->func && !(t->tflag & es->flag))
+ CHECK_BB(es->func((void*)es->data, t))
+ if(tflag(t, tflag_tmpl))
+ CHECK_BB(template_push_types(es->env, t->e->cdef->base.tmpl)) // incorrect templates
env_push_type((void*)es->env, t);
return GW_OK;
}
env_pop(es->env, es->scope);
if(!t)
return;
- if(GET_FLAG(t, template))
+ if(tflag(t, tflag_tmpl))
nspc_pop_type(es->env->gwion->mp, es->env->curr);
if(t->e->owner_class)
envset_pop(es, t->e->owner_class);
check(es, t);
if(es->run)
CHECK_BB(push(es, t->e->owner_class))
- const m_bool ret = !(t->flag & es->flag) ?
- es->func(es->data, t->e->def) : GW_OK;
+ const m_bool ret = t->e->cdef &&
+ !(t->tflag & es->flag) ?
+ es->func(es->data, t) : GW_OK;
if(es->run)
envset_pop(es, t->e->owner_class);
return ret;
#include "clean.h"
ANN static void free_func(Func a, Gwion gwion) {
- if(GET_FLAG(a, template))
+// if(GET_FLAG(a, template))
+ if(fflag(a, fflag_tmpl))
func_def_cleaner(gwion, a->def);
if(a->code)
REM_REF(a->code, gwion);
i, nspc))
return insert_symbol(env->gwion->st, name);
}
+
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr) {
+ set_vflag(f->value_ref, vflag_builtin);
+ f->code = new_vm_code(mp, NULL, f->def->stack_depth, 1, f->name);
+ f->code->native_func = (m_uint)func_ptr;
+}
}
ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwion) {
- if(!GET_FLAG(value, pure) && ((GET_FLAG(value, static) && a->info->class_data) ||
- (value->d.ptr && GET_FLAG(value, builtin)))) {
+ if(!vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+ (value->d.ptr && vflag(value, vflag_builtin)))) {
const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
*(M_Object*)(a->info->class_data + value->from->offset);
release(obj, gwion->vm->cleaner_shred);
}
ANN2(1,3) static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) {
- if(!SAFE_FLAG(value, pure) && ((SAFE_FLAG(value, static) && a->info->class_data) ||
- (SAFE_FLAG(value, builtin) && value->d.ptr))) {
+ if(value && !vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+ (vflag(value, vflag_builtin) && value->d.ptr))) {
const m_bit *ptr = (value && value->d.ptr) ? (m_bit*)value->d.ptr:
(m_bit*)(a->info->class_data + value->from->offset);
for(m_uint i = 0; i < vector_size(&value->type->e->tuple->types); ++i) {
const Type t = (Type)vector_at(&value->type->e->tuple->types, i);
if(isa(t, gwion->type[et_object]) > 0)
release(*(M_Object*)(ptr + vector_at(&value->type->e->tuple->offset, i)), gwion->vm->cleaner_shred);
- else if(GET_FLAG(t, struct))
+ else if(tflag(t, tflag_struct))
nspc_release_struct(t->nspc, NULL, gwion);
}
}
while(scope_iter(&iter, &v) > 0) {
if(isa(v->type, gwion->type[et_object]) > 0)
nspc_release_object(a, v, gwion);
- else if(GET_FLAG(v->type, struct))
+ else if(tflag(v->type, tflag_struct))
nspc_release_struct(a, v, gwion);
REM_REF(v, gwion);
}
#include "object.h"
ANN static inline m_bool freeable(const Type a) {
- return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
+ return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
}
ANN static void free_type(Type a, Gwion gwion) {
if(freeable(a)) {
- if(GET_FLAG(a, union)) {
- if(a->e->def->union_def) {
- if(!GET_FLAG(a, pure))
- free_union_def(gwion->mp, a->e->def->union_def);
- else
- free_decl_list(gwion->mp, a->e->def->list);
- }
- a->e->def->union_def = NULL;
- }
- if(a->e->def)
- class_def_cleaner(gwion, a->e->def);
+ if(tflag(a, tflag_udef))
+ free_union_def(gwion->mp, a->e->udef);
+ if(tflag(a, tflag_cdef))
+ class_def_cleaner(gwion, a->e->cdef);
}
if(a->nspc)
REM_REF(a->nspc, gwion);
free_tupleform(a->e->tuple, gwion);
mp_free(gwion->mp, TypeInfo, a->e);
mp_free(gwion->mp, Type, a);
+
}
Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
//describe_find(func, Func)
ANN Type typedef_base(Type t) {
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
return t;
}
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 || !GET_FLAG(src, struct)) ?
+ *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
object_release : struct_release;
} else
ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
- SET_FLAG(t, valid);
mk_class(env, t);
nspc_add_type_front(src->e->owner, sym, t);
return t;
ANN m_bool type_ref(Type t) {
do {
- if(GET_FLAG(t, empty))
+ if(tflag(t, tflag_empty))
return GW_OK;
- if(GET_FLAG(t, typedef) && t->e->def)
- if(t->e->def->base.ext && t->e->def->base.ext->array) {
- if(!t->e->def->base.ext->array->exp)
+ if(tflag(t, tflag_typedef) && t->e->cdef)
+ if(t->e->cdef->base.ext && t->e->cdef->base.ext->array) {
+ if(!t->e->cdef->base.ext->array->exp)
return GW_OK;
else {
const Type type = t->e->parent->e->d.base_type;
- if(SAFE_FLAG(type, empty))
+ if(tflag(type, tflag_empty))
return GW_OK;
}
}
static m_str const special_name[] = { "^nonnull", "^force" };
#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force };
+static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
typedef struct {
const Type type;
Symbol name;
- ae_flag flag;
+ enum tflag flag;
uint st_type;
} SpecialType;
if(t->nspc)
ADD_REF(t->nspc)
t->name = s_name(s->name);
- t->flag = s->type->flag | s->flag;
+ t->flag = s->type->flag;
+ t->tflag |= s->type->tflag | s->flag;
t->e->parent = unflag_type(s->type);
nspc_add_type_front(s->type->e->owner, s->name, t);
mk_class(env, t);
return t;
}
-static inline int get_flag(const Type t, const ae_flag flag) {
- return (t->flag & flag) == flag;
+static inline int get_flag(const Type t, const enum tflag flag) {
+ return (t->tflag & flag) == flag;
}
ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) {
- const ae_flag flag = special_flag[i];
+ const enum tflag flag = special_flag[i];
if(i == s->st_type || get_flag(s->type, flag)) {
strcat(c, special_name[i]);
s->flag |= flag;
ANN static void free_value(Value a, Gwion gwion) {
const Type t = a->type;
- if(!GET_FLAG(a, func) && a->d.ptr && !GET_FLAG(a, union) &&
- !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->from->owner_class)
+ if(!vflag(a, vflag_func) && a->d.ptr && !vflag(a, vflag_direct) &&
+ !(vflag(a, vflag_enum) && vflag(a, vflag_builtin) && a->from->owner_class)
&& isa(t, gwion->type[et_object]) < 0)
_mp_free(gwion->mp, t->size, a->d.ptr);
- else if(GET_FLAG(a, enum) && GET_FLAG(a, dtor))
+ else if(vflag(a, vflag_freeme))
xfree(a->d.ptr);
if(is_class(gwion, t))
REM_REF(t, gwion)
}
ANN static void gwion_cleaner(const Gwion gwion) {
- const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
+ const VM_Code code = new_vm_code(gwion->mp, NULL, 0, 1, "in code dtor");
gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
}
#include "specialid.h"
#include "template.h"
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
- VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
+ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const enum tflag e) {
+ VM_Code* code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
const m_str name = type->name;
- *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
+ *code = new_vm_code(p, NULL, SZ_INT, 1, name);
(*code)->native_func = (m_uint)d;
- type->flag |= e;
+ type->tflag |= e;
return GW_OK;
}
ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
do {
- if(GET_FLAG(t, valid))
+ if(tflag(t, tflag_check))
break;
- if(t->e->def)
- CHECK_BB(traverse_class_def(env, t->e->def))
+ if(t->e->cdef)
+ CHECK_BB(traverse_class_def(env, t->e->cdef))
} while((t = t->e->parent));
return GW_OK;
}
inherit(t);
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
- SET_FLAG(t, valid);
env_push_type(env, t);
}
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)
- mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
+ mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
if(dtor)
- mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
+ mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
}
ANN static inline void gwi_type_flag(const Type t) {
- SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
+ set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
}
ANN static Type type_finish(const Gwi gwi, const Type t) {
CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
const Type base = find_type(gwi->gwion->env, td);
const Type_List tl = td->types;
- if(GET_FLAG(base, unary))
+ if(tflag(base, tflag_ntmpl))
td->types = NULL;
const Type p = !td->types ? handle_class(gwi, td) : NULL;
td->types = tl;
nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
CHECK_OO(p)
const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
- t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
- t->e->def->base.tmpl = tmpl;
- t->e->def->base.type = t;
+ t->e->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
+ t->e->cdef->base.tmpl = tmpl;
+ t->e->cdef->base.type = t;
t->e->tuple = new_tupleform(gwi->gwion->mp, p);
t->e->parent = p;
if(td->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
if(ck.tmpl)
- SET_FLAG(t, template);
+ set_tflag(t, tflag_tmpl);
else
gwi_type_flag(t);
return type_finish(gwi, t);
const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
t->e->tuple = new_tupleform(gwi->gwion->mp, NULL);
gwi_type_flag(t);
- SET_FLAG(t, struct);
+ set_tflag(t, tflag_struct);
return type_finish(gwi, t);
}
for(m_uint i = 0; i < vector_size(v); i++) {
const Value value = (Value)vector_at(v, i);
const m_uint addr = vector_at(&ck->v, i);
- SET_FLAG(value, builtin);
+ set_vflag(value, vflag_builtin);
// ADD_REF(value->type); // what ?
if(!gwi->gwion->env->class_def)
value->d.ptr = (m_uint*)(addr ? addr : i);
ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v);
- Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag | ae_flag_builtin);
+ Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag);
+ if(ck->variadic)
+ base->fbflag |= fbflag_variadic;
ck->td = NULL;
if(ck->tmpl) {
base->tmpl = gwi_tmpl(gwi);
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
Func_Base* base = gwi_func_base(gwi, ck);
const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
- fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr;
- if(base->tmpl)
- SET_FLAG(fdef->base, template);
return fdef;
}
ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
const Func_Def fdef = import_fdef(gwi, ck);
- if(SAFE_FLAG(gwi->gwion->env->class_def, template))
+ if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
/*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;
}
ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
CHECK_BB(ck_ok(gwi, ck_fdef))
+ if(gwi->ck->variadic)
+ GWI_ERR_B(_("already decalred as variadic"));
+ if(!strcmp(n, "...")) {
+ gwi->ck->variadic = 1;
+ return GW_OK;
+ }
DECL_OB(Type_Decl*, td, = gwi_str2decl(gwi, t))
const Var_Decl var = gwi_str2var(gwi, n);
if(var) {
// what happens if it is in a template class ?
const m_bool ret = traverse_fptr_def(gwi->gwion->env, fptr);
if(fptr->base->func) // is it needed ?
- SET_FLAG(fptr->base->func, builtin);
+ set_vflag(fptr->base->func->value_ref, vflag_builtin);
const Type t = ret > 0 ? fptr->type : NULL;
free_fptr_def(gwi->gwion->mp, fptr);
if(fptr->type)
#include "gwi.h"
void gwi_body(const Gwi gwi, const Ast body) {
- const Class_Def cdef = gwi->gwion->env->class_def->e->def;
+ const Class_Def cdef = gwi->gwion->env->class_def->e->cdef;
if(!cdef->body)
cdef->body = body;
else
const Env env = gwi->gwion->env;
gwi->ck->exp->d.exp_decl.list->self->addr = (m_uint*)addr;
gwi->ck->exp->d.exp_decl.td->flag = flag;
- if(env->class_def && GET_FLAG(env->class_def, template))
+ if(env->class_def && tflag(env->class_def, tflag_tmpl))
return gwi_item_tmpl(gwi);
CHECK_BB(traverse_exp(env, gwi->ck->exp))
const Value value = gwi->ck->exp->d.exp_decl.list->self->value;
- SET_FLAG(value, builtin);
+ set_vflag(value, vflag_builtin);
+ if(!env->class_def)
+ SET_FLAG(value, global);
const m_uint offset = value->from->offset;
free_exp(gwi->gwion->mp, gwi->ck->exp);
ck_end(gwi);
}
ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
- const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+ const VM_Code code = new_vm_code(p, NULL, SZ_INT, 1, "@gack");
code->native_func = (m_uint)d;
- SET_FLAG(code, builtin);
type->e->gack = code;
return GW_OK;
}
gwi->gwion->env->class_def->nspc->info->offset =
udef->o + udef->s;
if(udef->xid || !udef->type_xid) {
- SET_FLAG(udef->value, builtin);
+ set_vflag(udef->value, vflag_builtin);
const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
udef->value->d.ptr = (m_uint*)o;
return udef->value->type;
gwi->ck->tmpl = NULL;
}
const Type t = union_type(gwi, udef);
- if(!SAFE_FLAG(t, template))
+ if(!safe_tflag(t, tflag_tmpl))
free_union_def(gwi->gwion->mp, udef);
ck_end(gwi);
return t;
OP_EMIT(opem_object_dot);
ANN static m_bool import_core_libs(const Gwi gwi) {
const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
+ set_tflag(t_class, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
GWI_BB(gwi_add_type(gwi, t_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_FLAG(t_auto, infer);
+ set_tflag(t_auto, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
- SET_FLAG(t_class, infer);
const Type t_void = gwi_mk_type(gwi, "void", 0, NULL);
GWI_BB(gwi_gack(gwi, t_void, gack_void))
GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
- SET_FLAG(t_lambda, infer);
+ set_tflag(t_lambda, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
gwi->gwion->type[et_event] = t_event; // use func
GWI_BB(gwi_item_ini(gwi, "@internal", "@shreds"))
- GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
GWI_BB(gwi_func_ini(gwi, "void", "signal"))
GWI_BB(gwi_func_end(gwi, event_signal, ae_flag_none))
GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
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)
return NULL;
+ if(vflag(v, vflag_builtin)) {
+ dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
+ v->d.func_ref->def->d.dl_func_ptr = NULL;
+ }
const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
+ if(vflag(v, vflag_builtin))
+ v->d.func_ref->def->d.dl_func_ptr = dt->xfun;
def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
def->base->tmpl->base = dt->vt_index;
dt->def = def;
dt->owner = v->from->owner;
dt->owner_class = v->from->owner_class;
- SET_FLAG(def->base, template);
return def;
}
ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
CHECK_BO(traverse_dot_tmpl(emit, dt))
+ if(dt->xfun)
+ builtin_func(emit->gwion->mp, def->base->func, dt->xfun);
return def;
}
struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
const m_str name = dt->name;
const M_Object o = *(M_Object*)REG(-SZ_INT);
- Type t = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
+ Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->e->parent;
do {
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
if(f) {
if(!f->code)
break;
- if(GET_FLAG(f, member))
+ if(vflag(f->value_ref, vflag_member))
shred->reg += SZ_INT;
*(VM_Code*)(shred->reg-SZ_INT) = f->code;
return;
if(!def)
continue;
const Func f = def->base->func;
- if(GET_FLAG(f, member))
+ if(vflag(f->value_ref, vflag_member))
shred->reg += SZ_INT;
*(VM_Code*)(shred->reg-SZ_INT) = f->code;
return;
if(bin->rhs->info->type->e->d.func->def->base->tmpl)
fptr_instr(emit, bin->lhs->info->type->e->d.func, 2);
const Instr instr = emit_add_instr(emit, int_r_assign);
- if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) {
+ if(!is_fptr(emit->gwion, bin->lhs->info->type) && vflag(bin->rhs->info->type->e->d.func->value_ref, vflag_member)) {
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
const Instr cpy = emit_add_instr(emit, Reg2Reg);
ERR_B(info->pos, _("can't assign non member function to member function pointer"))
} else if(l_type && isa(r_type, l_type) < 0)
ERR_B(info->pos, _("can't assign member function to a pointer of an other class"))
- if(GET_FLAG(info->rhs, member)) {
- if(!GET_FLAG(info->lhs, member))
+ if(vflag(info->rhs->value_ref, vflag_member)) {
+ if(!vflag(info->lhs->value_ref, vflag_member))
ERR_B(info->pos, _("can't assign static function to member function pointer"))
- } else if(GET_FLAG(info->lhs, member))
+ } else if(vflag(info->lhs->value_ref, vflag_member))
ERR_B(info->pos, _("can't assign member function to static function pointer"))
return GW_OK;
}
}
ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
- return GET_FLAG(info->lhs->def->base, variadic) ==
- GET_FLAG(info->rhs->def->base, variadic);
+ return fbflag(info->lhs->def->base, fbflag_variadic) ==
+ fbflag(info->rhs->def->base, fbflag_variadic);
}
ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
l->def->base->flag = def->base->flag;
l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
- SET_FLAG(l->def->base, abstract); // mark as non immediate lambda
map_set(&env->curr->info->func->map, (m_uint)l->def->base, env->scope->depth);
const m_bool ret = check_traverse_fdef(env, l->def);
map_remove(&env->curr->info->func->map, (m_uint)l->def->base);
ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
const Func_Def fdef = t->e->d.func->def;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
l->owner = t->e->owner_class;
CHECK_BB(envset_push(&es, l->owner, t->e->owner))
const m_bool ret = _check_lambda(env, l, fdef);
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
- m_bool nonnull = GET_FLAG(info->exp->info->type, nonnull);
+ m_bool nonnull = tflag(info->exp->info->type, tflag_nonnull);
CHECK_BB(fptr_check(env, info))
DECL_OB(const Type, t, = fptr_type(env, info))
info->exp->info->type = !nonnull ? t : nonnul_type(env, t);
}
static int is_member(const Type from, const Type to) {
- return GET_FLAG(from->e->d.func, member) &&
- !(GET_FLAG(from, nonnull) || GET_FLAG(to, nonnull));
+ return vflag(from->e->d.func->value_ref, vflag_member) &&
+ !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
}
static OP_EMIT(opem_fptr_cast) {
return env->gwion->type[et_fork];
char c[21 + strlen(t->name)];
sprintf(c, "nonnull TypedFork:[%s]", t->name);
- return str2type(env->gwion, c, exp_self(unary)->pos);
+ const Type fork = env->gwion->type[et_fork];
+ UNSET_FLAG(fork, final);
+ const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
+ UNSET_FLAG(typed, final);
+ const Type ret = str2type(env->gwion, c, exp_self(unary)->pos);
+ SET_FLAG(typed, final);
+ SET_FLAG(fork, final);
+ return ret;
}
static OP_CHECK(opck_spork) {
struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
Value v;
while(scope_iter(&iter, &v) > 0) {
- if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
+ if(!GET_FLAG(v, static) && !vflag(v, vflag_union) &&
isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
release(*(M_Object*)(o->data + v->from->offset), shred);
- else if(GET_FLAG(v->type, struct) &&
- !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) {
+ else if(tflag(v->type, tflag_struct) &&
+ !GET_FLAG(v, static) && !vflag(v, vflag_union) && v->type->e->tuple) {
const TupleForm tf = v->type->e->tuple;
for(m_uint i = 0; i < vector_size(&tf->types); ++i) {
const m_bit *data = o->data + v->from->offset;
}
}
}
- if(GET_FLAG(t, dtor) && t->nspc->dtor) {
- if(GET_FLAG(t->nspc->dtor, builtin))
+ if(tflag(t, tflag_dtor) && t->nspc->dtor) {
+ // check flag for array types
+ if(t->nspc->dtor->builtin)
((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
else {
o->type_ref = t;
static ID_CHECK(opck_this) {
if(!env->class_def)
ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
- if(env->func && !GET_FLAG(env->func, member))
+ if(env->func && !vflag(env->func->value_ref, vflag_member))
ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
return force_type(env, get_gack(env->class_def->e->parent)); // get_gack ?
}
static ID_EMIT(opem_this) {
- if(!exp_getvar(exp_self(prim)) && GET_FLAG(exp_self(prim)->info->type, struct)) {
+ if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->info->type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, RegPushMemDeref);
instr->m_val2 = emit->env->class_def->size;
return (Instr)GW_OK;
describe_logical(Eq, ==)
describe_logical(Neq, !=)
static inline m_bool nonnull_check(const Type l, const Type r) {
- return !GET_FLAG(l, nonnull) && GET_FLAG(r, nonnull);
+ return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
}
static inline Type check_nonnull(const Env env, const Type l, const Type r,
const m_str action, const loc_t pos) {
- if(GET_FLAG(r, nonnull)) {
+ if(tflag(r, tflag_nonnull)) {
if(isa(l, env->gwion->type[et_null]) > 0)
ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
if(isa(l, r) < 0)
return env->gwion->type[et_null];
if(check_nonnull(env, l, r, "assign", exp_self(bin)->pos) == env->gwion->type[et_null])
return env->gwion->type[et_null];
- if(bin->rhs->exp_type == ae_exp_decl) {
+ if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
- SET_FLAG(bin->rhs->d.exp_decl.list->self->value, ref);
- }
exp_setvar(bin->rhs, 1);
return r;
}
static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
ANN static void emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
- if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
+ if(v->d.ptr && vflag(v, vflag_builtin) && GET_FLAG(v, const)) {
const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
instr->m_val = (m_uint)v->d.ptr;
if(f->def->base->tmpl)
emit_add_instr(emit, DotTmplVal);
else
- if(is_class(emit->gwion, member->t_base) || GET_FLAG(member->base->info->type, force)) {
+ if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
// if(f->def->base->tmpl)
// emit_add_instr(emit, DotTmplVal);
else {
- if(GET_FLAG(member->t_base, struct)) {
+ if(tflag(member->t_base, tflag_struct)) {
if(!GET_FLAG(f->def->base, static)) {
exp_setvar(member->base, 1);
emit_exp(emit, member->base);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
}
- const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
+ const Instr instr = emit_add_instr(emit, vflag(f->value_ref, vflag_member) ? DotFunc : DotStaticFunc);
instr->m_val = f->vt_index;
}
return;
else if(GET_FLAG(value, protect))
exp_setprot(exp_self(member), 1);
}
- if(base_static && GET_FLAG(value, member))
+ if(base_static && vflag(value, vflag_member))
ERR_N(exp_self(member)->pos,
_("cannot access member '%s.%s' without object instance..."),
the_base->name, str)
const Exp_Dot *member = (Exp_Dot*)data;
const Type t_base = actual_type(emit->gwion, member->t_base);
const Value value = find_value(t_base, member->xid);
- if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
+ if(!is_class(emit->gwion, member->t_base) && (vflag(value, vflag_member) ||
(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
!is_fptr(emit->gwion, exp_self(member)->info->type)))) {
- if(!GET_FLAG(t_base, struct))
+ if(!tflag(t_base, tflag_struct))
CHECK_BO(emit_exp(emit, member->base))
if(isa(member->t_base, emit->env->gwion->type[et_object]) > 0)
emit_except(emit, member->t_base);
}
if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
emit_member_func(emit, member);
- else if(GET_FLAG(value, member)) {
- if(!GET_FLAG(t_base, struct))
+ else if(vflag(value, vflag_member)) {
+ if(!tflag(t_base, tflag_struct))
emit_member(emit, value, exp_getvar(exp_self(member)));
else {
// exp_setvar(member->base, exp_getvar(exp_self(member)));
}
struct tmpl_info {
- const Class_Def cdef;
+// const Class_Def cdef;
+ Symbol name;
+ ID_List list;
Type_List call;
+ Type ret;
+ Type base;
struct Vector_ type;
struct Vector_ size;
uint8_t index;
}
ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
- ID_List base = info->cdef->base.tmpl->list;
+ ID_List base = info->list; // ???
Type_List call = info->call;
size_t size = 0;
do {
DECL_OB(const Type, t, = known_type(env, call->td))
size += tmpl_set(info, t);
} while((call = call->next) && (base = base->next) && ++size);
- size += tmpl_set(info, info->cdef->base.type);
+// } while((call = call->next) && ++size);
+ size += tmpl_set(info, info->base);
return size + 4;
}
*str = '\0';
}
-ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
- struct tmpl_info info = { .cdef=c, .call=call };
- vector_init(&info.type);
- vector_init(&info.size);
- ssize_t sz = template_size(env, &info);
+ANEW ANN static Symbol template_id(const Env env, struct tmpl_info* info) {
+ vector_init(&info->type);
+ vector_init(&info->size);
+ ssize_t sz = template_size(env, info);
char name[sz];
if(sz > GW_ERROR)
- template_name(&info, name);
- vector_release(&info.type);
- vector_release(&info.size);
+ template_name(info, name);
+ vector_release(&info->type);
+ vector_release(&info->size);
return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
}
return !call ? GW_OK : GW_ERROR;
}
-ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
- DECL_OO(const Symbol, name, = template_id(env, def, call))
+ANN static Type tmpl_exists(const Env env, const Symbol name) {
if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
- return env->class_def->e->def;
- const Type t = nspc_lookup_type1(env->curr, name);
- if(t)
- return t->e->def;
- const Class_Def c = cpy_class_def(env->gwion->mp, def);
- c->base.xid = name;
- SET_FLAG(c, template | ae_flag_ref);
- UNSET_FLAG(c, scan0 | ae_flag_scan1 | ae_flag_scan2 |
- ae_flag_check | ae_flag_emit | ae_flag_valid);
- return c;
-}
-
-ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
- a->union_def = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, a->list),
- loc_cpy(env->gwion->mp, t->e->def->pos));
- a->union_def->type_xid = a->base.xid;
- if(GET_FLAG(t, global))
- SET_FLAG(a->union_def, global);
- CHECK_BB(scan0_union_def(env, a->union_def))
- a->base.type = a->union_def->type;
- a->base.type->e->def = a;
- a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
- return GW_OK;
+ return env->class_def;
+ return nspc_lookup_type1(env->curr, name);
+}
+
+ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
+ const Class_Def c = info->base->e->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,
+ loc_cpy(env->gwion->mp, c->pos));
+ cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
+ const m_bool ret = scan0_class_def(env, cdef);
+ if((info->ret = cdef->base.type)) {
+ info->ret->e->cdef = cdef;
+ set_tflag(info->ret, tflag_cdef);
+ set_tflag(info->ret, tflag_ctmpl);
+ } else
+ free_class_def(env->gwion->mp, cdef);
+ return ret;
+}
+
+ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
+ const Union_Def u = info->base->e->udef;
+ const Union_Def udef = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, u->l),
+ loc_cpy(env->gwion->mp, u->pos));
+ udef->type_xid = info->name;
+ udef->tmpl = mk_tmpl(env, u->tmpl, info->call);
+ if(GET_FLAG(info->base, global))
+ SET_FLAG(udef, global);
+ const m_bool ret = scan0_union_def(env, udef);
+ if(udef->type) {
+ udef->type->e->udef = udef;// mark as udef
+ info->ret = udef->type;
+ set_tflag(info->ret, tflag_udef);
+// set_tflag(info->ret, tflag_tmpl);
+ } else
+ free_union_def(env->gwion->mp, udef);
+ return ret;
}
-ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) {
- if(t->e->parent != env->gwion->type[et_union])
- CHECK_BB(scan0_class_def(env, a))
+ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
+ if(info->base->e->parent != env->gwion->type[et_union])
+ CHECK_BO(scantmpl_class_def(env, info))
else
- CHECK_BB(class2udef(env, a, t))
- SET_FLAG(a->base.type, template);
- if(GET_FLAG(t, builtin))
- SET_FLAG(a->base.type, builtin);
- return GW_OK;
+ CHECK_BO(scantmpl_union_def(env, info))
+ return info->ret;
}
ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
- if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
- ERR_O(td->pos, _("invalid template types number"))
- DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
- if(a->base.type)
- return a->base.type;
+ if(template_match(t->e->cdef->base.tmpl->list, td->types) < 0) // invalid template
+ ERR_O(td->pos, _("invalid template types number"))
+ struct tmpl_info info = { .base=t, .call=td->types, .list=t->e->cdef->base.tmpl->list };
+ DECL_OO(const Symbol, name, = info.name = template_id(env, &info))
+ const Type exists = tmpl_exists(env, name);
+ if(exists)
+ return exists;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan0 };
-// CHECK_BO(envset_push(&es, t->e->owner_class, env->context ? env->context->nspc : env->curr))
+ .scope=env->scope->depth, .flag=tflag_scan0 };
CHECK_BO(envset_push(&es, t->e->owner_class, t->e->ctx ? t->e->ctx->nspc : env->curr))
- a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
- const m_bool ret = _scan_class(env, t, a);
+ const Type ret = _scan_class(env, &info);
if(es.run)
envset_pop(&es, t->e->owner_class);
- if(ret > 0)
- return a->base.type;
- if(!a->base.type)
- free_class_def(env->gwion->mp, a);
- return NULL;
+ return ret;
}
ANN static inline Symbol dot_symbol(SymTable *st, const Value v) {
if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0)
continue;
const m_uint offset = vector_at(offsets, i);
- if(!GET_FLAG(t, struct))
+ if(!tflag(t, tflag_struct))
release(*(M_Object*)(ptr + offset), shred);
else
struct_release(shred, t, *(m_bit**)(ptr + offset));
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->e->def && !GET_FLAG(_t, check))
+ if(_t->e->cdef && !tflag(_t, tflag_check))
CHECK_BN(ensure_traverse(env, _t))
const Type to = known_type(env, cast->td->types->td);
if(isa(cast->exp->info->type, to) > 0)
e->info->cast_to = imp->t;
exp_setvar(e, 1);
const Type t = get_type(imp->t);
- if(!GET_FLAG(t, check))
- CHECK_BN(traverse_class_def(env, t->e->def))
+ if(!tflag(t, tflag_check))
+ CHECK_BN(traverse_class_def(env, t->e->cdef))
return imp->t;
}
return NULL;
static OP_CHECK(opck_ptr_scan) {
struct TemplateScan *ts = (struct TemplateScan*)data;
DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
- const Type base = known_type(env, t->e->def->base.tmpl->call->td);
+set_tflag(t, tflag_tmpl);
+//if(!tflag(t, tflag_scan1))exit(3);
+ const Type base = known_type(env, t->e->cdef->base.tmpl->call->td);
if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
- t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor");
- if(!GET_FLAG(t, struct))
+ t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
+ if(!tflag(t, tflag_struct))
t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
else
t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
- SET_FLAG(t, dtor);
+ set_tflag(t, tflag_dtor);
}
return t;
}
GWION_IMPORT(ptr) {
const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
GWI_BB(gwi_class_end(gwi))
- SET_FLAG(_t_ptr, unary);
+ set_tflag(_t_ptr, tflag_ntmpl);
+// set_tflag(_t_ptr, tflag_tmpl);
GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
GWI_BB(gwi_item_end(gwi, 0, NULL))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG(t_ptr, unary);
+ set_tflag(t_ptr, tflag_ntmpl);
+// set_tflag(t_ptr, tflag_tmpl);
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
gwi_func_ini(gwi, "float", "get_now");
GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
+ SET_FLAG(t_shred, abstract | ae_flag_final);
gwi_set_global_type(gwi, t_shred, et_shred);
struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
gwi_specialid(gwi, "me", &spid);
- SET_FLAG(t_shred, abstract);
-
const Type t_fork= gwi_class_ini(gwi, "Fork", "Shred");
gwi_class_xtor(gwi, NULL, fork_dtor);
gwi->gwion->type[et_fork] = t_fork;
gwi_func_ini(gwi, "void", "test_cancel");
GWI_BB(gwi_func_end(gwi, fork_test_cancel, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG((t_fork), abstract);
+ SET_FLAG(t_fork, abstract | ae_flag_final);
const Type t_typed = gwi_class_ini(gwi, "TypedFork:[A]", "Fork");
gwi_item_ini(gwi, "A", "retval");
GWI_BB((gwi_item_end(gwi, ae_flag_const, NULL)))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG((t_typed), abstract);
-
+ SET_FLAG(t_typed, abstract | ae_flag_final);
+ set_tflag(t_typed, tflag_ntmpl);
return GW_OK;
}
gwi->gwion->type[et_ugen] = t_ugen; // use func
GWI_BB(gwi_item_ini(gwi, "@internal", "@ugen"))
- GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
GWI_BB(gwi_func_ini(gwi, "UGen", "chan"))
GWI_BB(gwi_func_arg(gwi, "int", "arg0"))
const Type t = (Type)vector_at(&arg->t, i);
if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
release(*(M_Object*)(arg->d + offset), shred);
- else if(GET_FLAG(t, struct))
+ else if(tflag(t, tflag_struct))
struct_release(shred, t, *(m_bit**)(arg->d + offset));
offset += t->size;
}
}
static ID_CHECK(idck_vararg) {
- if(env->func && GET_FLAG(env->func->def->base, variadic))
+ if(env->func && fbflag(env->func->def->base, fbflag_variadic))
return nonnul_type(env, exp_self(prim)->info->type);
ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
}
return GW_OK;
}
-#define describe_check_decl(a, b) \
+#define describe_check_decl(a, b, flag) \
ANN static inline void decl_##a(const Env env, const Value v) { \
- const Nspc nspc = env->curr;\
- SET_FLAG(v, a); \
+ const Nspc nspc = env->curr; \
+ flag; \
v->from->offset = nspc->info->b; \
nspc->info->b += v->type->size; \
}
-describe_check_decl(member, offset)
-describe_check_decl(static, class_data_size)
+describe_check_decl(member, offset, v->vflag |= vflag_member)
+describe_check_decl(static, class_data_size, SET_FLAG(v, static))
ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
const Value v = var->value;
Type t = v->type;
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
if(!t->e->d.func)
return GW_ERROR;
const Type type = func->value_ref->from->owner_class;
if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
ERR_B(var->pos, _("can't use non global fptr of other class."))
- if(GET_FLAG(func, member) && GET_FLAG(v, static))
+ if(vflag(func->value_ref, vflag_member) && GET_FLAG(v, static))
ERR_B(var->pos, _("can't use static variables for member function."))
return GW_OK;
}
ANN Type check_td(const Env env, Type_Decl *td) {
CHECK_BO(check_td_exp(env, td))
const Type t = actual_type(env->gwion, td->exp->info->type);
- assert(t);
- if(GET_FLAG(t, template) && !GET_FLAG(t, ref))
- ERR_O(td_pos(td), _("type '%s' needs template types"), t->name)
td->xid = insert_symbol("auto");
return t;
}
ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) {
const Value v = var->value;
if(env->class_def) {
- if(GET_FLAG(td, member)) {
+ if(vflag(v, vflag_member)) {
decl_member(env, v);
if(env->class_def->e->tuple)
tuple_info(env, v);
CHECK_BB(check_var_td(env, var, decl->td))
if(is_fptr(env->gwion, decl->type))
CHECK_BB(check_fptr_decl(env, var))
- SET_FLAG(var->value, valid | ae_flag_used);
+ set_vflag(var->value, vflag_valid);
+ //set_vflag(var->value, vflag_used));
nspc_add_value(env->curr, var->xid, var->value);
} while((list = list->next));
return GW_OK;
ANN static inline m_bool ensure_check(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
return envset_run(&es, t);
}
ANN m_bool ensure_traverse(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
return envset_run(&es, t);
}
ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
- if(!GET_FLAG(t, infer))
+ if(!tflag(t, tflag_infer))
return GW_OK;
ERR_B(pos, _("can't infer type."))
}
{
const Type t = get_type(decl->type);
CHECK_BO(inferable(env, t, td_pos(decl->td)))
- if(!GET_FLAG(t, check) && t->e->def)
+ if(!tflag(t, tflag_check))
CHECK_BO(ensure_check(env, t))
}
const m_bool global = GET_FLAG(decl->td, global);
CHECK_BO(not_from_owner_class(env, env->class_def, value, prim_pos(data)))
const Value v = value ?: find_value(env->class_def, var);
if(v) {
- if(env->func && GET_FLAG(env->func->def->base, static) && GET_FLAG(v, member))
+ if(env->func && GET_FLAG(env->func->def->base, static) && vflag(v, vflag_member))
ERR_O(prim_pos(data),
_("non-static member '%s' used from static function."), s_name(var))
}
return v;
} else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def->base, global))) {
- if(!SAFE_FLAG(value, abstract))
+ if(!value || !GET_FLAG(value, global))
ERR_O(prim_pos(data),
_("non-global variable '%s' used from global function/class."), s_name(var))
}
const Symbol sym = insert_symbol(val->name);
const Vector vec = (Vector)&env->curr->info->value->ptr;
const m_uint scope = map_get(&env->curr->info->func->map, (m_uint)env->func->def->base);
- if(GET_FLAG(val, abstract))
+ if(GET_FLAG(val, global))
return GW_OK;
if(val->from->owner_class && isa(val->from->owner_class, env->class_def) > 0)
return GW_OK;
ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
const Symbol sym = *data;
const Value v = check_non_res_value(env, data);
- if(!v || !GET_FLAG(v, valid) || (v->from->ctx && v->from->ctx->error)) {
+ if(!v || !vflag(v, vflag_valid) || (v->from->ctx && v->from->ctx->error)) {
env_err(env, prim_pos(data),
_("variable %s not legit at this point."), s_name(sym));
if(v)
}
prim_self(data)->value = v;
if(env->func) {
- if(GET_FLAG(env->func->def->base, abstract))
+ if(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0)
CHECK_BO(lambda_valid(env, prim_self(data)))
- if(env->func && !GET_FLAG(v, const) && v->from->owner)
- UNSET_FLAG(env->func, pure);
+ if(env->func && !GET_FLAG(v, const) && v->from->owner)
+ unset_fflag(env->func, fflag_pure);
}
- SET_FLAG(v, used);
+ //v->vflag |= used;
if(GET_FLAG(v, const))
exp_setmeta(prim_exp(data), 1);
if(v->from->owner_class) {
ANN static Type check_prim_hack(const Env env, const Exp *data) {
if(env->func)
- UNSET_FLAG(env->func, pure);
+ unset_fflag(env->func, fflag_pure);
CHECK_OO(check_prim_interp(env, data))
return env->gwion->type[et_gack];
}
Arg_List e1 = func->def->base->args;
while(e) {
if(!e1) {
- if(GET_FLAG(func->def->base, variadic))
+ if(fbflag(func->def->base, fbflag_variadic))
return func;
CHECK_OO(func->next);
return find_func_match_actual(env, func->next, args, implicit, specific);
ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
struct Vector_ v = {};
const m_uint scope = env->scope->depth;
- env->scope->depth = 1;
+ env->scope->depth = 0;
vector_init(&v);
while(vector_size((Vector)&env->curr->info->value->ptr) > 1)
vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr));
CHECK_OB((arg_list->type = v->type = check_td(env, arg_list->td)))
// TODO: use coumpound instead of object?
if(isa(v->type, env->gwion->type[et_object]) > 0 || isa(v->type, env->gwion->type[et_function]) > 0)
- UNSET_FLAG(env->func, pure);
+ unset_fflag(env->func, fflag_pure);
CHECK_BB(already_defined(env, decl->xid, decl->pos))
- SET_FLAG(v, valid);
+ set_vflag(v, vflag_valid);
nspc_add_value(env->curr, decl->xid, v);
} while((arg_list = arg_list->next));
return GW_OK;
DECL_OO(const Func, func, = v->d.func_ref ?: predefined_func(env, v, exp, tm))
if(!fdef->base->ret_type) { // template fptr
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
- SET_FLAG(func->def->base, typedef);
+ func->def->base->fbflag |= fbflag_internal;
const m_bool ret = check_traverse_fdef(env, func->def);
if(es.run)
envset_pop(&es, v->from->owner_class);
ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
CHECK_BO(check_traverse_fdef(env, l->def))
if(env->class_def)
- SET_FLAG(l->def->base, member);
+ set_vflag(l->def->base->func->value_ref, vflag_member);
((Exp_Call*)exp)->m_func = l->def->base->func;
return l->def->base->ret_type ?: (l->def->base->ret_type = env->gwion->type[et_void]);
}
}
if(exp->func->info->type == env->gwion->type[et_lambda])
return check_lambda_call(env, exp);
- if(GET_FLAG(exp->func->info->type->e->d.func, ref)) {
+ if(fflag(exp->func->info->type->e->d.func, fflag_ftmpl)) {
const Value value = exp->func->info->type->e->d.func->value_ref;
- if(value->from->owner_class && !GET_FLAG(value->from->owner_class, check))
+ if(value->from->owner_class && !tflag(value->from->owner_class, tflag_check))
CHECK_BO(ensure_traverse(env, value->from->owner_class))
}
if(exp->args)
CHECK_OO(check_exp(env, exp->args))
- if(GET_FLAG(exp->func->info->type, func))
+ if(tflag(exp->func->info->type, tflag_ftmpl))
return check_exp_call_template(env, (Exp_Call*)exp);
const Func func = find_func_match(env, exp->func->info->type->e->d.func, exp->args);
if((exp_self(exp)->d.exp_call.m_func = func)) {
env_err(env, pos, _("Type '%s' has '%s' as pre-defined types."),
t->name, str);
free_mstr(env->gwion->mp, str);
- if(GET_FLAG(t, typedef)) {
+ if(tflag(t, tflag_typedef)) {
loc_header(t->e->d.func->def->pos, env->name);
gw_err(_("from definition:\n"));
loc_err(t->e->d.func->def->pos, env->name);
return NULL;
DECL_OO(const Type, ret, = op_check(env, &opi))
const Type t = get_type(actual_type(env->gwion, ret));
- if(t->e->def && !GET_FLAG(t, check))
+ if(!tflag(t, tflag_check))
CHECK_BO(ensure_traverse(env, t))
return ret;
}
}
ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
- return tdef->type->e->def ? check_class_def(env, tdef->type->e->def) : GW_OK;
+ return tdef->type->e->cdef ? check_class_def(env, tdef->type->e->cdef) : GW_OK;
}
ANN static Type check_exp_lambda(const Env env,
const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
do {
CHECK_OO((curr->info->type = check_exp_func[curr->exp_type](env, &curr->d)))
if(env->func && isa(curr->info->type, env->gwion->type[et_lambda]) < 0 && isa(curr->info->type, env->gwion->type[et_function]) > 0 &&
- !GET_FLAG(curr->info->type->e->d.func, pure))
- UNSET_FLAG(env->func, pure);
+ !fflag(curr->info->type->e->d.func, fflag_pure))
+ unset_fflag(env->func, fflag_pure);
} while((curr = curr->next));
return exp->info->type;
}
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
DECL_OB(Type, t, = check_exp(env, stmt->exp))
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
Type ptr = array_base(t);
const m_uint depth = t->array_depth - 1;
sprintf(c, "nonnull Ptr:[%s]", ptr->name);
ptr = str2type(env->gwion, c, stmt->exp->pos);
const Type base = get_type(ptr);
- if(!GET_FLAG(base, check))
+ if(!tflag(base, tflag_check))
CHECK_BB(ensure_traverse(env, base))
}
t = (!stmt->is_ptr && depth) ? array_type(env, ptr, depth) : ptr;
stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
- SET_FLAG(stmt->v, valid);
+ set_vflag(stmt->v, vflag_valid);
nspc_add_value(env->curr, stmt->sym, stmt->v);
return check_conts(env, stmt_self(stmt), stmt->body);
}
do {
CHECK_OB(check_exp(env, l->self))
Var_Decl_List list = l->self->d.exp_decl.list;
- do SET_FLAG(list->self->value, pure);
+ do set_vflag(list->self->value, vflag_union);
while((list = list->next));
if(l->self->info->type->size > udef->s)
udef->s = l->self->info->type->size;
if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
env->class_def->nspc->info->offset = udef->o + udef->s;
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_check);
- union_flag(udef, ae_flag_valid);
+ union_flag(udef, tflag_check);
return ret;
}
const Symbol sym = prim->d.var;
const Value v = new_value(env->gwion->mp,
((Exp)VKEY(&env->scope->match->map, i))->info->type, s_name(sym));
- SET_FLAG(v, valid);
+ set_vflag(v, vflag_valid);
nspc_add_value(env->curr, sym, v);
VVAL(&env->scope->match->map, i) = (vtype)v;
return v;
}
ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
+ if(GET_FLAG(parent->def->base, final))
+ ERR_B(td_pos(fdef->base->td), _("can't override final function '%s'\n"), parent->name)
if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
const m_str p_name = parent->value_ref->from->owner_class->name;
ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->args)
CHECK_BB(check_func_args(env, fdef->base->args))
- if(!GET_FLAG(fdef->base, builtin)) {
- if(fdef->d.code)
- CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
- } else
- fdef->base->func->code->stack_depth = fdef->stack_depth;
+ if(fdef->d.code)
+ CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
return GW_OK;
}
++env->scope->depth;
nspc_push_value(env->gwion->mp, env->curr);
struct Op_Import opi = { };
- if(GET_FLAG(fdef->base, op)) {
+ if(fbflag(fdef->base, fbflag_op)) {
func_operator(f, &opi);
operator_suspend(env->curr, &opi);
}
const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
- if(GET_FLAG(fdef->base, op))
+ if(fbflag(fdef->base, fbflag_op))
operator_resume(&opi);
nspc_pop_value(env->gwion->mp, env->curr);
--env->scope->depth;
env->func = former;
if(ret > 0)
- SET_FLAG(fdef->base, valid);
+ set_fflag(fdef->base->func, fflag_valid);
if(GET_FLAG(fdef->base, global))
env_pop(env,scope);
return ret;
const Type_Decl *td = cdef->base.ext;
if(td->array)
CHECK_BB(check_subscripts(env, td->array, 1))
- if(parent->e->def && !GET_FLAG(parent, check))
+ if(!tflag(parent, tflag_check))
CHECK_BB(ensure_check(env, parent))
- if(GET_FLAG(parent, typedef))
- SET_FLAG(cdef->base.type, typedef);
+ if(tflag(parent, tflag_typedef)) {
+ set_tflag(cdef->base.type, tflag_typedef);
+ }
return GW_OK;
}
return ret;
}
+ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
+ if(!cdef->base.type->nspc->info->vtable.ptr)
+ return GW_OK;
+ for(m_uint i = 0; i < vector_size(&cdef->base.type->nspc->info->vtable); ++i) {
+ Func f = (Func)vector_at(&cdef->base.type->nspc->info->vtable, i);
+ if(GET_FLAG(f->def->base, abstract))
+ ERR_B(cdef->pos, _("'%s' must be declared 'abstract'"), s_name(cdef->base.xid))
+ }
+ return GW_OK;
+}
+
ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_check))
CHECK_BB(ensure_check(env, t->e->owner_class))
- if(GET_FLAG(t, check))return GW_OK;
- SET_FLAG(t, check);
+ if(tflag(t, tflag_check))
+ return GW_OK;
+ set_tflag(t, tflag_check);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
- if(!GET_FLAG(cdef, struct))
+ if(!tflag(t, tflag_struct))
inherit(t);
if(cdef->body) {
CHECK_BB(env_body(env, cdef, check_section))
- SET_FLAG(t, ctor);
+ set_tflag(t, tflag_ctor);
}
- SET_FLAG(t, valid);
+ if(!GET_FLAG(cdef, abstract))
+ CHECK_BB(check_abstract(env, cdef))
return GW_OK;
}
ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
opi->op =fdef->base->xid;
const m_str str = s_name(fdef->base->xid);
- const uint is_unary = GET_FLAG(fdef->base, unary) +
+ const uint is_unary = fbflag(fdef->base, fbflag_unary) +
(!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
const Arg_List args = fdef->base->args;
opi->lhs = is_unary ? NULL :
}
ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
- const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0;
+ const m_bool ret = (fdef->base->func && fflag(fdef->base->func, fflag_valid)) || check_traverse_fdef(env, fdef) > 0;
if(ret) {
const Func f = fdef->base->func;
const Func next = f->next;
const Func func = find_func_match(env, f, exp->args);
f->next = next;
if(func) {
- SET_FLAG(func, valid | ae_flag_template);
+ set_fflag(func, fflag_tmpl);
+ set_fflag(func, fflag_valid);
return func;
}
}
if(exists)
return exists->e->d.func;
- Func m_func = f_ptr_args->m_func;
+ Func m_func = f_ptr_args->m_func;
Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
fbase->xid = sym;
const Value v = f_ptr_args->v;
const m_str tmpl_name = f_ptr_args->tmpl_name;
const Exp_Call *exp = f_ptr_args->e;
- Func m_func = f_ptr_args->m_func;
+ Func m_func = f_ptr_args->m_func;
Type_List types = f_ptr_args->types;
for(m_uint i = 0; i < v->from->offset + 1; ++i) {
const Value exists = template_get_ready(env, v, tmpl_name, i);
const Value value = template_get_ready(env, v, "template", i);
if(!value)
continue;
- if(GET_FLAG(v, builtin)) {
- SET_FLAG(value, builtin);
- SET_FLAG(value->d.func_ref, builtin);
- }
+ if(vflag(v, vflag_builtin))
+ set_vflag(value, vflag_builtin);
const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
- SET_FLAG(fdef->base, template);
fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
fdef->base->tmpl->base = i;
if((m_func = ensure_tmpl(env, fdef, exp))) {
DECL_OO(const m_str, tmpl_name, = tl2str(env, types))
const m_uint scope = env->scope->depth;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=scope, .flag=ae_flag_check };
+ .scope=scope, .flag=tflag_check };
struct ResolverArgs f_ptr_args = {.v = v, .e = exp, .tmpl_name = tmpl_name, m_func = m_func, .types = types};
CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
(void)env_push(env, v->from->owner_class, v->from->owner);
}
ANN static Type op_parent(const Env env, const Type t) {
- if(GET_FLAG(t, template) && GET_FLAG(t, ref)) {
+ if(tflag(t, tflag_ctmpl)) {
const Type type = typedef_base(t);
char name[strlen(type->name) + 1];
strcpy(name, type->name);
if(t == OP_ANY_TYPE || mo == OP_ANY_TYPE)
return GW_OK;
Type type = t;
- while(SAFE_FLAG(type, template) && type->e->def && type->e->def->base.tmpl && type->e->def->base.tmpl->call) type = type->e->parent;
if((type && mo && mo->xid == type->xid) || (!type && !mo))
return GW_OK;
return 0;
}
ANN static inline void set_nonnull(const Type t, const Exp exp) {
- if(t != OP_ANY_TYPE && GET_FLAG(t, nonnull))
+ if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
exp_setnonnull(exp, 1);
}
SET_FLAG(fptr->base->func, global);
SET_FLAG(def->base, global);
} else if(!GET_FLAG(fptr->base, static)) {
- SET_FLAG(fptr->value, member);
- SET_FLAG(fptr->base->func, member);
- SET_FLAG(def->base, member);
+ set_vflag(fptr->value, vflag_member);
+ set_vflag(fptr->base->func->value_ref, vflag_member);
def->stack_depth += SZ_INT;
} else {
SET_FLAG(fptr->value, static);
SET_FLAG(fptr->base->func, static);
SET_FLAG(def->base, static);
}
- if(GET_FLAG(def->base, variadic))
+ if(fbflag(def->base, fbflag_variadic))
def->stack_depth += SZ_INT;
- fptr->value->from->owner_class = env->class_def;
}
static void fptr_def(const Env env, const Fptr_Def fptr) {
if(GET_FLAG(fptr->base, global))
context_global(env);
t->nspc = new_nspc(env->gwion->mp, name);
- t->flag = fptr->base->flag;
+ t->flag |= fptr->base->flag;
fptr->type = t;
fptr->value = mk_class(env, t);
valuefrom(env, fptr->value->from);
fptr_def(env, fptr);
if(env->class_def)
fptr_assign(env, fptr);
- SET_FLAG(fptr->value, func);
+ set_vflag(fptr->value, vflag_func);
add_type(env, t->e->owner, t);
mk_class(env, t);
ADD_REF(t);
tdef->type = t;
if(base->nspc)
ADD_REF((t->nspc = base->nspc));
- t->flag = tdef->ext->flag | ae_flag_valid;
+ t->flag = tdef->ext->flag;
scan0_implicit_similar(env, t, base);
if(tdef->ext->array && !tdef->ext->array->exp)
- SET_FLAG(t, empty);
+ set_tflag(t, tflag_empty);
}
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
- const ae_flag flag = base->e->def ? base->e->def->flag : 0;
+ const ae_flag flag = base->e->cdef ? base->e->cdef->flag : 0;
const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
cpy_type_decl(env->gwion->mp, tdef->ext), NULL,
loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
add_type(env, env->curr, tdef->type);
mk_class(env, tdef->type);
if(base->e->d.func->def->base->tmpl)
- SET_FLAG(tdef->type, func);
+ set_tflag(tdef->type, tflag_ftmpl);
}
ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
CHECK_BB(typedef_complex(env, tdef, base))
} else
typedef_fptr(env, tdef, base);
- SET_FLAG(tdef->type, typedef);
+ set_tflag(tdef->type, tflag_typedef);
return GW_OK;
}
add_type(env, env->curr, t);
if(add)
mk_class(env, t);
- SET_FLAG(t, union);
return t;
}
ANN static void union_tmpl(const Env env, const Union_Def udef) {
if(tmpl_base(udef->tmpl)) {
- assert(udef->type_xid);
- const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid,
- NULL, (Ast)cpy_decl_list(env->gwion->mp, udef->l), loc_cpy(env->gwion->mp, udef->pos));
- udef->type->e->def = cdef;
- cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
- cdef->base.type = udef->type;
- SET_FLAG(cdef, union);
- SET_FLAG(udef->type, pure);
- SET_FLAG(udef, template);
- SET_FLAG(udef->type, template);
+ const Union_Def u = cpy_union_def(env->gwion->mp, udef);
+ u->type = udef->type;
+ udef->type->e->udef = u;
+ set_tflag(u->type, tflag_tmpl);
+ set_tflag(u->type, tflag_udef);
}
if(GET_FLAG(udef, global))
SET_FLAG(udef->type, global);
- SET_FLAG(udef->type, union);
}
ANN static Value union_value(const Env env, const Type t, const Symbol sym) {
const Value v = new_value(env->gwion->mp, t, s_name(sym));
valuefrom(env, v->from);
nspc_add_value(env->curr, sym, v);
- SET_FLAG(v, valid | ae_flag_pure);
+ set_vflag(v, vflag_union);
return v;
}
udef->value = union_value(env, t, udef->xid);
udef->value->flag |= udef->flag;
SET_ACCESS(udef, t);
- if(env->class_def && !GET_FLAG(udef, static)) {
- SET_FLAG(udef->value, member);
- SET_FLAG(udef, member);
- }
+ if(env->class_def && !GET_FLAG(udef, static))
+ set_vflag(udef->value, vflag_member);
} else if(udef->type_xid) {
CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos))
udef->type = union_type(env, udef->type_xid, 1);
SET_ACCESS(udef, udef->type);
- SET_FLAG(udef->type, valid);
} else {
const Symbol sym = scan0_sym(env, "union", udef->pos);
CHECK_BB(scan0_defined(env, sym, udef->pos))
union_tmpl(env, udef);
if(GET_FLAG(udef, global))
env_pop(env, scope);
- union_flag(udef, ae_flag_scan0);
+ union_flag(udef, tflag_scan0);
return GW_OK;
}
}
ANN static void cdef_flag(const Class_Def cdef, const Type t) {
- if(cdef->base.tmpl) {
- SET_FLAG(t, template);
- SET_FLAG(cdef, template);
- }
+ if(cdef->base.tmpl)
+ set_tflag(t, tflag_tmpl);
if(cdef->base.ext && cdef->base.ext->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
}
ANN static Type get_parent_base(const Env env, Type_Decl *td) {
return t;
}
-ANN static Type check_abstract(const Env env, Type_Decl *td) {
+ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
DECL_OO(const Type, t, = known_type(env, td))
- if(!GET_FLAG(t, abstract)) // could be final
+ if(!GET_FLAG(t, final))
return t;
- ERR_O(td_pos(td), _("can't inherit from abstract parent class '%s'\n."), t->name);
+ ERR_O(td_pos(td), _("can't inherit from final parent class '%s'\n."), t->name);
}
ANN static Type get_parent(const Env env, const Class_Def cdef) {
- if(GET_FLAG(cdef, struct))
+ if(cflag(cdef, cflag_struct))
return env->gwion->type[et_compound];
if(!cdef->base.ext)
return env->gwion->type[et_object];
return get_parent_base(env, cdef->base.ext);
if(cdef->base.tmpl)
template_push_types(env, cdef->base.tmpl);
- const Type t = check_abstract(env, cdef->base.ext);
+ const Type t = scan0_final(env, cdef->base.ext);
if(cdef->base.tmpl)
nspc_pop_type(env->gwion->mp, env->curr);
return t ?: (Type)GW_ERROR;
if(parent == (Type)GW_ERROR)
return NULL;
const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent);
- if(GET_FLAG(cdef, struct))
- SET_FLAG(t, struct);
+// if(GET_FLAG(parent, abstract))
+// SET_FLAG(t, abstract);
+ if(cflag(cdef, cflag_struct))
+ t->flag |= tflag_struct;
t->e->tuple = new_tupleform(env->gwion->mp, parent);
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
t->nspc = new_nspc(env->gwion->mp, t->name);
t->nspc->parent = env->curr;
- t->e->def = cdef;
- t->flag = cdef->flag;
+ t->e->cdef = cdef;
+ t->flag |= cdef->flag;
add_type(env, t->e->owner, t);
cdef_flag(cdef, t);
if(cdef->base.ext && cdef->base.ext->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
return t;
}
ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
- SET_FLAG(cdef->base.type, scan0);
+ set_tflag(cdef->base.type, tflag_scan0);
if(cdef->body)
CHECK_BB(env_body(env, cdef, scan0_section))
(void)mk_class(env, cdef->base.type);
}
ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
- const Class_Def cdef = !tmpl_base(c->base.tmpl) ?
- c : cpy_class_def(env->gwion->mp, c);
- if(GET_FLAG(cdef, global)) {
+ const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global);
+ const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c);
+ if(GET_FLAG(cdef, global)) { // could be updated
vector_add(&env->scope->nspc_stack, (vtype)env->curr);
env->curr = env->global_nspc;
context_global(env);
scan0_class_def_inner(env, cdef) : GW_ERROR;
if(GET_FLAG(cdef, global))
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
- CHECK_BB(ret)
- if(GET_FLAG(cdef, global) || (cdef->base.tmpl && !cdef->base.tmpl->call))
+ if(cpy && cdef->base.type) {
c->base.type = cdef->base.type;
- SET_FLAG(cdef->base.type, scan0);
- return GW_OK;
+ c->base.type->e->cdef = cdef;
+ set_tflag(c->base.type, tflag_cdef);
+ set_tflag(cdef->base.type, tflag_scan0);// redundant
+ }
+ return ret;
}
ANN m_bool scan0_ast(const Env env, Ast ast) {
ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan1 };
+ .scope=env->scope->depth, .flag=tflag_scan1 };
return envset_run(&es, t);
}
const Type t = get_type(type);
if(!env->func && env->class_def && !GET_FLAG(td, ref))
CHECK_BO(type_cyclic(env, t, td))
- if(!GET_FLAG(t, scan1) && t->e->def)
+ if(!tflag(t, tflag_scan1))
CHECK_BO(ensure_scan1(env, t))
return type;
}
DECL_OO(const Type ,t, = void_type(env, decl->td))
if(decl->td->xid == insert_symbol("auto") && decl->type)
return decl->type;
- if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
- SET_FLAG(decl->td, member);
if(GET_FLAG(t, private) && t->e->owner != env->curr)
ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
Type t = decl->type;
CHECK_BB(scan1_defined(env, var))
- if(var->array) {
+ if(var->array) {
if(var->array->exp) {
if(GET_FLAG(decl->td, ref))
ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
ERR_B(exp_self(decl)->pos, _("Type '%s' is abstract, declare as ref. (use @)"), t->name)
}
const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
- if(SAFE_FLAG(env->class_def, struct) && !GET_FLAG(decl->td, static)) {
+// rewrite logic
+ if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
+ set_vflag(v, vflag_member);
+ if(safe_tflag(env->class_def, tflag_struct) && !GET_FLAG(decl->td, static)) {
v->from->offset = env->class_def->size;
env->class_def->size += t->size;
}
nspc_add_value(env->curr, var->xid, v);
- v->flag = decl->td->flag;
+ v->flag |= decl->td->flag;
v->type = t;
if(var->array && !var->array->exp)
- SET_FLAG(v, ref);
+ SET_FLAG(decl->td, ref);
if(env->class_def) {
if(env->class_def->e->tuple)
tuple_contains(env, v);
} else if(!env->scope->depth)
- SET_FLAG(v, global);
+ set_vflag(v, vflag_fglobal);// file global
v->d.ptr = var->addr;
if(GET_FLAG(decl->td, global))
- SET_FLAG(v, abstract);
+ SET_FLAG(v, global);
if(!env->scope->depth)
valuefrom(env, v->from);
} while((list = list->next));
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
CHECK_OB(decl->type)
- if(GET_FLAG(decl->type, const))
- exp_setmeta(exp_self(decl), 1);
const m_bool global = GET_FLAG(decl->td, global);
if(global) {
if(env->context)
SET_ACCESS(edef, v)
SET_ACCESS(edef, edef->t)
}
- SET_FLAG(v, const | ae_flag_enum | ae_flag_valid);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_valid);
+ set_vflag(v, vflag_enum);
nspc_add_value(edef->t->e->owner, list->xid, v);
vector_add(&edef->values, (vtype)v);
} while((list = list->next));
const Value v = new_value(env->gwion->mp, list->type, var->xid ? s_name(var->xid) : (m_str)__func__);
if(var->array)
v->type = list->type = array_type(env, list->type, var->array->depth);
- if(list->td)
- v->flag = list->td->flag | ae_flag_abstract;
+ if(list->td) {
+ v->flag = list->td->flag;
+// SET_FLAG(v, global); ???
+ }
return v;
}
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->e->def)return GW_OK;
- return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
+ if(!tdef->type->e->cdef)return GW_OK;
+ return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type) : GW_OK;
}
ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
const Decl_List l) {
const Exp_Decl decl = l->self->d.exp_decl;
- SET_FLAG(decl.td, valid | udef->flag);
+ decl.td->flag |= udef->flag;
const m_bool global = GET_FLAG(udef, global);
if(global)
UNSET_FLAG(decl.td, global);
- if(GET_FLAG(udef, member))
- SET_FLAG(decl.td, member);
else if(GET_FLAG(udef, static))
SET_FLAG(decl.td, static);
CHECK_BB(scan1_exp(env, l->self))
}
const m_bool ret = scan1_union_def_inner(env, udef);
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_scan1);
+ union_flag(udef, tflag_scan1);
return ret;
}
ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
if(fdef->base->args) {
- if(!GET_FLAG(fdef->base, builtin))
- CHECK_BB(scan1_fdef_args(env, fdef->base->args))
+ CHECK_BB(scan1_fdef_args(env, fdef->base->args))
CHECK_BB(scan1_args(env, fdef->base->args))
}
- if(!GET_FLAG(fdef->base, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
+ if(fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
return GW_OK;
}
ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->td)
CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
- if(GET_FLAG(fdef->base, typedef))
+ if(fbflag(fdef->base, fbflag_internal))
CHECK_BB(scan_internal(env, fdef->base))
- else if(GET_FLAG(fdef->base, op) && env->class_def)
+ else if(fbflag(fdef->base, fbflag_op) && env->class_def)
SET_FLAG(fdef->base, static);
RET_NSPC(scan1_fbody(env, fdef))
return GW_OK;
if(cdef->base.ext->array)
CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
+// if(GET_FLAG(parent, abstract)) // could be final
+//SET_FLAG(cdef->base.type, abstract);
+// ERR_B(td_pos(cdef->base.ext), _("can't inherit from abstract parent class '%s'\n."), parent->name);
if(isa(parent, env->gwion->type[et_object]) < 0)
ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
- if(parent->e->def && !GET_FLAG(parent, scan1))
+ if(!tflag(parent, tflag_scan1))
CHECK_BB(ensure_scan1(env, parent))
if(type_ref(parent))
ERR_B(pos, _("can't use ref type in class extend"))
- if(GET_FLAG(parent, nonnull))
+ if(tflag(parent, tflag_nonnull))
ERR_B(pos, _("can't use nonnull type in class extend"))
return GW_OK;
}
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, scan1))
+ if(tflag(t, tflag_scan1))
return GW_OK;
- SET_FLAG(t, scan1);
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
+ set_tflag(t, tflag_scan1);
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan1))
CHECK_BB(ensure_scan1(env, t->e->owner_class))
- SET_FLAG(cdef->base.type, scan1);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan2 };
+ .scope=env->scope->depth, .flag=tflag_scan2 };
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);
- if(t->e->def && !GET_FLAG(t, scan2))
+ if(!tflag(t, tflag_scan2))
CHECK_BB(ensure_scan2(env, t))
Var_Decl_List list = decl->list;
do {
ANN static Value scan2_func_assign(const Env env, const Func_Def d,
const Func f, const Value v) {
valuefrom(env, v->from);
- SET_FLAG(v, func | ae_flag_const);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_func);
if(!env->class_def)
- SET_FLAG(v, global);
+ set_vflag(v, vflag_fglobal);
else {
- if(GET_FLAG(f, member))
- SET_FLAG(v, member);
- else SET_FLAG(v, static);
+ if(GET_FLAG(d->base, static))
+ SET_FLAG(v, static);
+ else
+ set_vflag(v, vflag_member);
SET_ACCESS(d->base, v)
- }
+ }
d->base->func = v->d.func_ref = f;
return f->value_ref = v;
}
RET_NSPC(scan2_args(def))
}
} else
- SET_FLAG(fptr->type, func);
+ set_tflag(fptr->type, tflag_ftmpl);
return GW_OK;
}
ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
- if(!tdef->type->e->def) return GW_OK;
- return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->def) : GW_OK;
+ if(!tdef->type->e->cdef) return GW_OK;
+ return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->cdef) : GW_OK;
}
ANN static inline Value prim_value(const Env env, const Symbol s) {
if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
prim->prim_type == ae_prim_interp)
CHECK_BB(scan2_exp(env, prim->d.exp))
- else if(prim->prim_type == ae_prim_id) {
+/* else if(prim->prim_type == ae_prim_id) {
const Value v = prim_value(env, prim->d.var);
if(v)
- SET_FLAG(v, used);
- } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
+ v->vflag |= used;
+ } */else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
return scan2_exp(env, prim->d.array->exp);
else if(prim->prim_type == ae_prim_range)
return scan2_range(env, prim->d.range);
if(e->exp_type == ae_exp_decl) {
if(e->d.exp_decl.list->next)
ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."), s_name(op))
- SET_FLAG(e->d.exp_decl.list->self->value, used);
+// set_vflag(e->d.exp_decl.list->self->value, vflag_used);
}
return GW_OK;
}
const m_uint scope = union_push(env, udef);
const m_bool ret = scan2_union_decl(env, udef->l);
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_scan2);
+ union_flag(udef, tflag_scan2);
return ret;
}
}
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
- const m_bool base = tmpl_base(f->base->tmpl);
- const m_bool tmpl = GET_FLAG(overload, template);
+ const m_bool fptr = is_fptr(env->gwion, overload->type);
if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
- if(!GET_FLAG(f->base, typedef))
+ if(!fbflag(f->base, fbflag_internal))
ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
}
- if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f->base, template)))
+ const Func obase = !fptr ? overload->d.func_ref : overload->type->e->d.base_type->e->d.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);
+ const m_bool tmpl = fflag(obase, fflag_tmpl);
+ if((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
ERR_B(f->pos, _("must overload template function with template"))
return GW_OK;
}
ANN static Func scan_new_func(const Env env, const Func_Def f, const m_str name) {
const Func func = new_func(env->gwion->mp, name, f);
if(env->class_def) {
- if(GET_FLAG(env->class_def, template))
- SET_FLAG(func, ref);
- if(!GET_FLAG(f->base, static))
- SET_FLAG(func, member);
+ if(tflag(env->class_def, tflag_tmpl))
+ set_fflag(func, fflag_ftmpl);
}
return func;
}
t->name = func->name;
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
- if(GET_FLAG(func, member))
- t->size += SZ_INT;
t->e->d.func = func;
return t;
}
f->next = overload->d.func_ref->next;
overload->d.func_ref->next = f;
}
+ if(env->class_def && !GET_FLAG(f->def->base, static)) {
+ t->size += SZ_INT;
+ set_vflag(v, vflag_member);
+ }
return v;
}
-ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
- SET_FLAG(func, builtin);
- SET_FLAG(func->value_ref, builtin);
- func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
- func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
- return GW_OK;
-}
-
ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
const m_str name = s_name(f->base->xid);
const Func func = scan_new_func(env, f, name);
const Value value = func_value(env, func, overload);
- SET_FLAG(value, valid | ae_flag_template);
- SET_FLAG(value->type, func); // the only types with func flag, name could be better
+ set_fflag(func, fflag_tmpl);
+ set_vflag(value, vflag_valid);
+ set_tflag(value->type, tflag_ftmpl); // the only types with func flag, name could be better
Type type = env->class_def;
Nspc nspc = env->curr;
uint i = 0;
nspc_add_func(env->curr, f->base->xid, func);
} else
func->vt_index = ++overload->from->offset;
- if(GET_FLAG(f->base, builtin)) {
- CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
- SET_FLAG(func, builtin);
- SET_FLAG(value, builtin);
- }
return GW_OK;
}
}
ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
- if(!GET_FLAG(f->base, builtin))
- SET_FLAG(f->base->func, pure);
+ set_fflag(f->base->func, fflag_pure);
if(f->base->xid == insert_symbol("@dtor"))
- SET_FLAG(env->class_def, dtor);
+ set_tflag(env->class_def, tflag_dtor);
}
ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
nspc_add_func(env->curr, insert_symbol(func->name), func);
const Value v = func_value(env, func, overload);
scan2_func_def_flag(env, f);
- if(GET_FLAG(f->base, builtin))
- CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
nspc_add_value(env->curr, insert_symbol(func->name), v);
return v;
}
f->base->func = base;
if(f->base->args)
CHECK_BB(scan2_args(f))
- if(!GET_FLAG(f->base, builtin) && f->d.code)
+ if(f->d.code)
CHECK_BB(scan2_func_def_code(env, f))
if(!base) {
- if(GET_FLAG(f->base, op))
+ if(fbflag(f->base, fbflag_op))
CHECK_BB(scan2_func_def_op(env, f))
- SET_FLAG(f->base->func->value_ref, valid);
+ set_vflag(f->base->func->value_ref, vflag_valid);
}
return GW_OK;
}
fdef : scan2_cpy_fdef(env, fdef);
const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) && !GET_FLAG(f->base, global)) ? SZ_INT : 0;
- if(GET_FLAG(f->base, variadic))
+ if(fbflag(f->base, fbflag_variadic))
f->stack_depth += SZ_INT;
const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
if(GET_FLAG(f->base, global))
ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
- if(parent->e->def && !GET_FLAG(parent, scan2))
+ if(!tflag(parent, tflag_scan2))
CHECK_BB(ensure_scan2(env, parent))
if(cdef->base.ext->array)
CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, scan2))return GW_OK;
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
+ if(tflag(t, tflag_scan2))
+ return GW_OK;
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan2))
CHECK_BB(ensure_scan2(env, t->e->owner_class))
- SET_FLAG(t, scan2);
+ set_tflag(t, tflag_scan2);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
__attribute__((returns_nonnull))
ANN Type unflag_type(const Type t) {
- const Type type = !GET_FLAG(t, nonnull) ? t : t->e->parent;
- return !GET_FLAG(type, force) ? type : type->e->parent;
+ const Type type = !tflag(t, tflag_nonnull) ? t : t->e->parent;
+ return !tflag(type, tflag_force) ? type : type->e->parent;
}
__attribute__((returns_nonnull))
return unflag_type(type);
}
-ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
const _exp_func f_cdef, const _exp_func f_union) {
- const Type t = get_type(cdef->base.type);
+ const Type t = get_type(base);
if(t->e->parent != env->gwion->type[et_union])
- return f_cdef(opt, t->e->def);
- CHECK_BB(template_push_types(env, t->e->def->base.tmpl))
- const m_bool ret = f_union(opt, t->e->def->union_def);
- nspc_pop_type(env->gwion->mp, env->curr);
+ return f_cdef(opt, t->e->cdef);
+ const m_bool ret = f_union(opt, t->e->udef);
return ret;
}
env_pop(env, scope);
}
-ANN void union_flag(const Union_Def udef, const ae_flag flag) {
+ANN void union_flag(const Union_Def udef, const enum tflag flag) {
const Type type = udef->xid || !udef->type_xid ?
udef->value->type : udef->type;
- type->flag |= flag;
+ type->tflag |= flag;
}
ANN static m_bool _template_push(const Env env, const Type t) {
if(t->e->owner_class)
CHECK_BB(template_push(env, t->e->owner_class))
- if(GET_FLAG(t, template))
- return push_types(env, t->e->def->base.tmpl);
+ if(tflag(t, tflag_tmpl))
+ return push_types(env, t->e->cdef->base.tmpl); // incorrect
return GW_OK;
}
ADD_REF(ret->nspc)
ret->e->parent = t;
ret->name = s_name(sym);
- SET_FLAG(ret, func);
+ set_tflag(ret, tflag_ftmpl);
nspc_add_type_front(t->e->owner, sym, ret);
+ void* func_ptr = t->e->d.func->def->d.dl_func_ptr;
+ if(vflag(t->e->d.func->value_ref, vflag_builtin))
+ t->e->d.func->def->d.dl_func_ptr = NULL;
const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
const Value value = new_value(env->gwion->mp, ret, s_name(sym));
func->flag = def->base->flag;
+ if(vflag(t->e->d.func->value_ref, vflag_member))
+ set_vflag(value, vflag_member);
value->d.func_ref = func;
value->from->owner = t->e->owner;
value->from->owner_class = t->e->owner_class;
func->def->base->tmpl = mk_tmpl(env, t->e->d.func->def->base->tmpl, td->types);
def->base->func = func;
nspc_add_value_front(t->e->owner, sym, value);
+ if(vflag(t->e->d.func->value_ref, vflag_builtin)) {
+ builtin_func(env->gwion->mp, func, func_ptr);
+ t->e->d.func->def->d.dl_func_ptr = func_ptr;
+ }
return ret;
}
}
ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) {
- if(GET_FLAG(t, template) && isa(t, env->gwion->type[et_function]) < 0) {
- if(GET_FLAG(t, ref) || (GET_FLAG(t, unary) && !td->types))
+ if(tflag(t, tflag_tmpl) && isa(t, env->gwion->type[et_function]) < 0) {
+ if(tflag(t, tflag_ctmpl) || (tflag(t, tflag_ntmpl) && !td->types))
return t;
struct TemplateScan ts = { .t=t, .td=td };
struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td), .op_type=op_scan };
if(!owner->nspc)
ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
struct EnvSet es = { .env=env, .data=env,
- .scope=env->scope->depth, .flag=ae_flag_none };
+ .scope=env->scope->depth, .flag=tflag_none };
envset_push(&es, owner, owner->nspc);
(void)env_push(env, owner, owner->nspc);// TODO: is this needed?
const Type ret = scan_type(env, t, td->next);
ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
const Type t = def->base.type;
- if(!GET_FLAG(t, scan1))
+ if(!tflag(t, tflag_scan1))
CHECK_BB(scan1_class_def(env, def))
- if(!GET_FLAG(t, scan2))
+ if(!tflag(t, tflag_scan2))
CHECK_BB(scan2_class_def(env, def))
- if(!GET_FLAG(t, valid))
+ if(!tflag(t, tflag_check))
return check_class_def(env, def);
return GW_OK;
}
ANN void gack(const VM_Shred shred, const m_uint offset) {
const Type t = *(Type*)shred->reg;
const VM_Code code = get_gack(t)->e->gack;
- if(GET_FLAG(code, builtin)) {
+ if(code->builtin) {
const m_uint sz = *(m_uint*)(shred->reg + SZ_INT);
((f_gack)code->native_func)(t, (shred->reg - sz), shred);
POP_REG(shred, sz);
} else {
prepare_call(shred, offset);
- if(GET_FLAG(t, struct))
+ if(tflag(t, tflag_struct))
*(void**)(shred->mem) = (void*)(shred->reg - t->size);
else
*(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
PRAGMA_PUSH()
reg -= SZ_INT;
a.code = *(VM_Code*)reg;
- if(!GET_FLAG((VM_Code)a.code, builtin)) {
+ if(!a.code->builtin) {
register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
mem += push;
*(m_uint*) mem = push;mem += SZ_INT;
ANN static void free_vm_code(VM_Code a, Gwion gwion) {
if(a->memoize)
memoize_end(gwion->mp, a->memoize);
- if(!GET_FLAG(a, builtin)) {
+ if(!a->builtin) {
_mp_free(gwion->mp, vector_size(a->instr) * SZ_INT, a->bytecode);
_free_code_instr(a->instr, gwion);
}
VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
- const ae_flag flag, const m_str name) {
+ const int builtin, const m_str name) {
VM_Code code = mp_calloc(p, VM_Code);
if(instr) {
code->instr = vector_copy(p, instr);
}
code->name = mstrdup(p, name);
code->stack_depth = stack_depth;
- code->flag = flag;
+ code->builtin = builtin;
code->ref = new_refcount(p, free_vm_code);
return code;
}
--- /dev/null
+#! [contains] override final
+class C {
+ fun final void test() { <<< "final" >>>;}
+}
+
+class D extends C {
+ fun void test() { <<< "final" >>>;}
+}
+var D d;
--- /dev/null
+#! [contains] inherit from final parent
+class final C {}
+
+class D extends C {}
--- /dev/null
+class C {
+ fun abstract void test(int i);
+}
--- /dev/null
+#! [contains] must be declared 'abstract'
+class abstract C {
+ fun abstract void test(int i);
+}
+
+class D extends C {}
+++ /dev/null
-#! [contains] can't inherit
-class C extends TypedFork:[int] {
-
-}
-
-var C c;
-c.exit();
return 12;
}
-fork test() @=> ref TypedFork:[int] sh;
+fork test() @=> ref auto sh;
<<< typeof(sh) >>>;
sh.ev => now;
<<< sh.retval >>>;
GWI_OB(gwi_class_ini(gwi, ":[A,B]ClassTemplate", NULL))
gwi_class_xtor(gwi, class_template_ctor, NULL);
GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
- GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+ GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
- GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+ GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_func_ini(gwi, "int", ":[C,D]test"))
GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
GWION_IMPORT(class_template) {
GWI_OB(gwi_class_ini(gwi, "ClassTemplate:[A,B]", NULL))
GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
- GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+ GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
- GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+ GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_func_ini(gwi, "int", "test:[C,D]"))
GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
GWI_OB(gwi_class_ini(gwi, "Variadic", NULL))
GWI_BB(gwi_func_ini(gwi, "void", "member"))
GWI_BB(gwi_func_arg(gwi, "string", "format"))
- GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_variadic))
+ GWI_BB(gwi_func_arg(gwi, "does not matter", "..."))
+ GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_none))
GWI_BB(gwi_func_ini(gwi, "void", "test"))
GWI_BB(gwi_func_end(gwi, m_test, ae_flag_none))
GWI_BB(gwi_class_end(gwi))