ANN2(1) void envset_pop(struct EnvSet*, const Type);
ANN static inline m_bool extend_push(const Env env, const Type t) {
- if(t->info->owner_class)
- CHECK_BB(extend_push(env, t->info->owner_class))
+ const Type owner = t->info->value->from->owner_class;
+ if(owner)
+ CHECK_BB(extend_push(env, owner))
return env_push_type(env, t);
}
ANN static inline void extend_pop(const Env env, const Type t) {
env_pop(env, 0);
- if(t->info->owner_class)
- extend_pop(env, t->info->owner_class);
+ const Type owner = t->info->value->from->owner_class;
+ if(owner)
+ extend_pop(env, owner);
}
#endif
struct TypeInfo_ {
Type parent;
- Nspc owner;
- Type owner_class;
+ Value value;
union {
Union_Def udef;
Class_Def cdef;
Type base_type;
struct TupleForm_* tuple;
struct VM_Code_ *gack;
- struct Context_ *ctx;
};
enum tflag {
ANN Nspc pop_global(const Gwion gwion);
__attribute__((returns_nonnull))
ANN static inline Value type_value(const Gwion gwion, const Type t) {
- return (Value)nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name));
+ return (Value)nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name));
}
__attribute__((returns_nonnull))
ANN static inline Type type_class(const Gwion gwion, const Type t) {
- const Value v = nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name));
+ const Value v = nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name));
return v->type;
}
#endif
m_uint native_func;
};
size_t stack_depth;
+ struct Vector_ tmpl_types;
void* memoize;
Closure *closure;
m_str name;
uint16_t ref;
ae_flag flag;
- int builtin;
- int callback;
+ bool builtin;
+ bool callback;
};
typedef struct Shreduler_* Shreduler;
ANN static int is_reg(const m_str path) {
struct stat s;
stat(path, &s);
- return S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode);
+ return !S_ISDIR(s.st_mode) &&
+ (S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode));
}
+
#else
ANN static m_bool is_reg(const m_str path) {
const DWORD dw = GetFileAttributes(path);
char name[strlen(c->name) + 1];
strcpy(name, c->name);
#ifndef __FUZZING__
- if(c->type == COMPILE_FILE && !is_reg(name)) {
+ if((c->type == COMPILE_FILE || c->type == COMPILE_NAME) && !is_reg(name)) {
gw_err(_("'%s': is a not a regular file\n"), name);
return GW_ERROR;
}
const Func former = emit->env->func;
if(func->code || tmpl_base(fdef->base->tmpl))
return GW_OK;
- if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
+ if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) {
+ const Func base = nspc_lookup_func1(func->value_ref->from->owner, f->base->xid);
+ builtin_func(emit->gwion->mp, func, (f_xfun)base->code->native_func);
+ vector_init(&func->code->tmpl_types);
+ vector_add(&func->code->tmpl_types, (m_uint)fdef->base->ret_type);
+ Arg_List args = fdef->base->args;
+ while(args) {
+ vector_add(&func->code->tmpl_types, (m_uint)args->type);
+ args = args->next;
+ }
return GW_OK;
+ }
if(fdef_is_file_global(emit, fdef))
func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
const uint global = GET_FLAG(f->base, global);
if(tflag(t, tflag_emit))
return GW_OK;
set_tflag(t, tflag_emit);
- if(t->info->owner_class)
- CHECK_BB(ensure_emit(emit, t->info->owner_class))
+ const Type owner = t->info->value->from->owner_class;
+ if(owner)
+ CHECK_BB(ensure_emit(emit, owner))
if(cdef->base.ext && t->info->parent->info->cdef && !tflag(t->info->parent, tflag_emit)) // ?????
CHECK_BB(cdef_parent(emit, cdef))
nspc_allocdata(emit->gwion->mp, t->nspc);
}
ANN void env_add_type(const Env env, const Type type, const loc_t loc) {
- type->info->owner = env->curr;
- type->info->owner_class = env->class_def; // t owner_class ?
const Symbol sym = insert_symbol(type->name);
nspc_add_type_front(env->curr, sym, type);
const Value v = mk_class(env, type, loc);
const Type t_class = env->gwion->type[et_class];
const Type t = type_copy(env->gwion->mp, t_class);
t->info->parent = t_class;
- t->info->ctx = base->info->ctx;
t->info->base_type = base;
set_tflag(t, tflag_infer);
return t;
valuefrom(env, v->from, loc);
SET_FLAG(v, const);
set_vflag(v, vflag_valid);
- nspc_add_value_front(base->info->owner, sym, v);
+ nspc_add_value_front(env->curr, sym, v);
+ t->info->value = base->info->value = v;
return v;
}
ANN static void check(struct EnvSet *es, const Type t) {
const Vector v = &es->env->scope->class_stack;
- Type owner = t->info->owner_class;
+ Type owner = t->info->value->from->owner_class;
for(vtype i = vector_size(v) + 1; owner && --i;) {
if(owner != (Type)vector_at(v, i - 1)) {
es->run = 1;
return;
}
- owner = owner->info->owner_class;
+ owner = owner->info->value->from->owner_class;
}
}
ANN static m_bool push(struct EnvSet *es, const Type t) {
es->env->scope->depth = 0;
- if(t->info->owner_class)
- CHECK_BB(push(es, t->info->owner_class))
+ const Type owner_class = t->info->value->from->owner_class;
+ if(owner_class)
+ CHECK_BB(push(es, owner_class))
else
- env_push(es->env, NULL, t->info->ctx ? t->info->ctx->nspc : es->env->curr);
+ env_push(es->env, NULL, t->info->value->from->ctx ? t->info->value->from->ctx->nspc : es->env->curr);
if(es->func && !(t->tflag & es->flag))
CHECK_BB(es->func((void*)es->data, t))
if(tflag(t, tflag_tmpl))
return;
if(tflag(t, tflag_tmpl))
nspc_pop_type(es->env->gwion->mp, es->env->curr);
- if(t->info->owner_class)
- envset_pop(es, t->info->owner_class);
+ const Type owner_class = t->info->value->from->owner_class;
+ if(owner_class)
+ envset_pop(es, owner_class);
else
env_pop(es->env, es->scope);
}
ANN m_bool envset_run(struct EnvSet *es, const Type t) {
check(es, t);
+ const Type owner_class = t->info->value->from->owner_class;
if(es->run)
- CHECK_BB(push(es, t->info->owner_class))
+ CHECK_BB(push(es, owner_class))
const m_bool ret = t->info->cdef &&
!(t->tflag & es->flag) ?
es->func(es->data, t) : GW_OK;
if(es->run)
- envset_pop(es, t->info->owner_class);
+ envset_pop(es, owner_class);
return ret;
}
ANN Type type_copy(MemPool p, const Type type) {
const Type a = new_type(p, type->name, type->info->parent);
- a->nspc = type->nspc;
- a->info->owner = type->info->owner;
- a->info->owner_class = type->info->owner_class;
a->size = type->size;
a->array_depth = type->array_depth;
a->info->gack = type->info->gack;
#include "import.h"
ANN Type array_type(const Env env, const Type src, const m_uint depth) {
const Symbol sym = array_sym(env, src, depth);
- const Type type = nspc_lookup_type1(src->info->owner, sym);
+ const Type type = nspc_lookup_type1(src->info->value->from->owner, sym);
if(type)
return type;
const size_t tdepth = depth + src->array_depth;
t->nspc->parent = env->curr;
if(isa(t, env->gwion->type[et_object]) > 0)
inherit(t);
- t->info->owner = env->curr;
- t->info->owner_class = env->class_def;
env_push_type(env, t);
}
return tl;
}
+ANN static inline uint get_n(struct td_checker *tdc, const char c) {
+ uint n = 0;
+ while(*tdc->str == c) {
+ n++;
+ ++tdc->str;
+ }
+ return n;
+}
+
ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) {
+ const uint ref = get_n(tdc, '&');
DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc))
struct AC ac = { .str = tdc->str, .pos=tdc->pos };
CHECK_BO(ac_run(gwion, &ac))
Type_List tl = td_tmpl(gwion, tdc);
if(tl == (Type_List)GW_ERROR)
return NULL;
+ const uint option = get_n(tdc, '?');
Type_Decl *next = NULL;
if(*tdc->str == '.') {
++tdc->str;
Type_Decl *td = new_type_decl(gwion->mp, sym, tdc->pos);
td->next = next;
td->types = tl;
+ td->option = option;
+ td->ref = ref;
if(ac.depth)
td->array = mk_array(gwion->mp, &ac);
return td;
};
ANN static void td_fullname(const Env env, GwText *text, const Type t) {
- const Type owner = t->info->owner_class;
+ const Type owner = t->info->value->from->owner_class;
if(owner) {
td_fullname(env, text, owner);
text_add(text, ".");
ANEW ANN m_str type2str(const Gwion gwion, const Type t, const loc_t pos NUSED) {
GwText text = { .mp=gwion->mp };
- if(t->info->owner_class) {
- td_fullname(gwion->env, &text, t->info->owner_class);
+ const Type owner = t->info->value->from->owner_class;
+ if(owner) {
+ td_fullname(gwion->env, &text, owner);
text_add(&text, ".");
}
text_add(&text, t->name);
return exp ? emit_array_access(emit, info) : GW_ERROR;
}
+static m_bit map_byte[BYTECODE_SZ*4];// = { eOP_MAX, test };
+static const struct VM_Code_ map_run_code = {
+ .name = "map_run_code",
+ .stack_depth = SZ_INT,
+ .bytecode = map_byte
+};
+
+#define MAP_CODE_OFFSET SZ_INT*10
+static INSTR(test) {
+ *(VM_Code*)(shred->reg) = (*(VM_Code*)MEM(SZ_INT));
+ *(VM_Code*)(shred->reg + SZ_INT) = 0;
+ PUSH_REG(shred, SZ_INT);
+ const M_Object self = *(M_Object*)MEM(0);
+ const M_Vector array = ARRAY(self);
+ const m_uint index = *(m_uint*)MEM(SZ_INT*5);
+ shred->pc++;
+ (*(m_uint*)MEM(SZ_INT*5))++; // increment the index
+ shred->mem += MAP_CODE_OFFSET; // work in a safe memory space
+ *(m_uint*)(shred->reg + SZ_INT) = 0;
+ *(m_uint*)(shred->mem-SZ_INT) = 0;
+ *(m_uint*)(shred->mem-SZ_INT*2) = 0;
+ *(VM_Code*)(shred->mem-SZ_INT*3) = (VM_Code)&map_run_code;
+ m_vector_get(array, index, &*(m_bit**)(shred->mem + SZ_INT*5));
+}
+
+static INSTR(test2) {
+ shred->mem -= MAP_CODE_OFFSET;
+ const M_Object ret_obj = *(M_Object*)MEM(SZ_INT*2);
+ const M_Vector array = ARRAY(ret_obj);
+ POP_REG(shred, ARRAY_SIZE(array));
+ POP_REG(shred, SZ_INT);
+ const m_uint index = *(m_uint*)MEM(SZ_INT*5);
+ const m_uint size = m_vector_size(array);
+ m_vector_set(array, index - 1, &*(m_bit**)(shred->reg + SZ_INT));
+ if(index == size) {
+ shred->pc = *(m_uint*)MEM(SZ_INT*3);
+ shred->code = *(VM_Code*)MEM(SZ_INT*4);
+ *(M_Object*)(shred->reg) = ret_obj;
+ shred->reg += SZ_INT;
+ } else
+ shred->pc = 0;
+ shredule(shred->tick->shreduler, shred, 0);
+}
+
+static MFUN(vm_vector_map) {
+ const VM_Code code = *(VM_Code*)REG(SZ_INT*2);
+ const M_Object ret = *(M_Object*)MEM(SZ_INT*2) = *(M_Object*)RETURN = new_array(shred->info->vm->gwion->mp, (Type)vector_front(&code->tmpl_types), ARRAY_LEN(ARRAY(o)));
+ vector_add(&shred->gc, (m_uint)ret);
+ *(m_uint*)MEM(SZ_INT*3) = shred->pc;
+ *(VM_Code*)MEM(SZ_INT*4) = shred->code;
+ shred->code = (VM_Code)&map_run_code;
+ shred->pc = 0;
+ shredule(shred->tick->shreduler, shred, 0);
+}
+
ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth);
#include "template.h"
static OP_CHECK(opck_array_scan) {
const Type base = ts->t != t_array ?
ts->t : known_type(env, ts->td->types->td);
const Symbol sym = array_sym(env, array_base(base), base->array_depth + 1);
- const Type type = nspc_lookup_type1(base->info->owner, sym);
+ const Type type = nspc_lookup_type1(base->info->value->from->owner, sym);
if(type)
return type;
const Class_Def cdef = cpy_class_def(env->gwion->mp, c);
cdef->base.tmpl->base = 1; // could store depth here?
cdef->base.tmpl->call = new_type_list(env->gwion->mp, type2td(env->gwion, base, (loc_t){}), NULL);
const Context ctx = env->context;
- env->context = base->info->ctx;
- const m_uint scope = env_push(env, base->info->owner_class, base->info->owner);
+ env->context = base->info->value->from->ctx;
+ const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
(void)scan0_class_def(env, cdef);
const Type t = cdef->base.type;
(void)traverse_cdef(env, t);
builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 3), vm_vector_depth);
builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 4), vm_vector_cap);
builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 5), vm_vector_random);
+ builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 6), vm_vector_map);
if(isa(base, env->gwion->type[et_compound]) > 0) {
t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "array component dtor");
set_tflag(t, tflag_dtor);
return imp->t;
}
+static void prepare_map_run(void) {
+ *(unsigned*)map_byte = eOP_MAX;
+ *(f_instr*)(map_byte + SZ_INT*2) = test;
+ *(unsigned*)(map_byte+ BYTECODE_SZ) = eSetCode;
+ *(m_uint*)(map_byte + BYTECODE_SZ + SZ_INT*2) = 3;
+ *(unsigned*)(map_byte+ BYTECODE_SZ*2) = eOverflow;
+ *(unsigned*)(map_byte+ BYTECODE_SZ*3) = eOP_MAX;
+ *(f_instr*)(map_byte + BYTECODE_SZ*3 + SZ_INT*2) = test2;
+}
+
GWION_IMPORT(array) {
+ prepare_map_run();
const Type t_array = gwi_class_ini(gwi, "Array:[T]", "Object");
gwi->gwion->type[et_array] = t_array;
gwi_class_xtor(gwi, NULL, array_dtor);
GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data"))
GWI_BB(gwi_item_end(gwi, 0, num, 0))
+ GWI_BB(gwi_fptr_ini(gwi, "A", "map_t:[A]"))
+ GWI_BB(gwi_func_arg(gwi, "T", "elem"))
+ GWI_BB(gwi_fptr_end(gwi, ae_flag_global))
+
// put functions using T first
GWI_BB(gwi_func_ini(gwi, "bool", "remove"))
GWI_BB(gwi_func_arg(gwi, "int", "index"))
GWI_BB(gwi_func_ini(gwi, "T", "random"))
GWI_BB(gwi_func_end(gwi, vm_vector_random, ae_flag_none))
+ GWI_BB(gwi_func_ini(gwi, "A[]", "map:[A]"))
+ GWI_BB(gwi_func_arg(gwi, "map_t:[A]", "data"))
+ GWI_BB(gwi_func_end(gwi, vm_vector_map, ae_flag_none))
+
GWI_BB(gwi_class_end(gwi))
GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
INSTR(GTmpl) {
struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
const Func f = *(Func*)REG(-SZ_INT);
+ if(!f)
+ Except(shred, _("EmptyFuncPointerException"));
+if(f->code) {
+ *(VM_Code*)(shred->reg -SZ_INT) = f->code;
+ return;
+}
const m_str name = f->name;
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
const loc_t pos;
};
+ANN static void _fptr_tmpl_push(const Env env, const Func f) {
+ ID_List il = f->def->base->tmpl ? f->def->base->tmpl->list : NULL;
+ if(il) {
+ Type_List tl = f->def->base->tmpl->call;
+ while(il) {
+ const Type t = tl ? known_type(env, tl->td) : env->gwion->type[et_auto];
+ nspc_add_type(env->curr, il->xid, t);
+ il = il->next;
+ if(tl)
+ tl = tl->next;
+ }
+ }
+}
+
ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) {
if(!info->rhs->def->base->tmpl)
return GW_OK;
- ID_List t0 = info->lhs->def->base->tmpl->list,
- t1 = info->rhs->def->base->tmpl->list;
nspc_push_type(env->gwion->mp, env->curr);
- while(t0) {
- nspc_add_type(env->curr, t0->xid, env->gwion->type[et_auto]);
- nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]);
- t0 = t0->next;
- t1 = t1->next;
- }
+// Type owner = info->rhs->value_ref->from->owner_class;
+// while(owner) {
+// owner = owner->info->value->from->owner_class;
+// }
+
+// _fptr_tmpl_push(env, info->lhs);
+ _fptr_tmpl_push(env, info->rhs);
return GW_OK;
}
static m_bool td_match(const Env env, Type_Decl *id[2]) {
DECL_OB(const Type, t0, = known_type(env, id[0]))
DECL_OB(const Type, t1, = known_type(env, id[1]))
- return isa(t0, t1);
+ if(isa(t0, t1) > 0)
+ return GW_OK;
+ return t1 == env->gwion->type[et_auto];
}
ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
}
ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) {
- if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl)
- return GW_ERROR;
+// if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl)
+// return GW_ERROR;
const Type l_type = info->lhs->value_ref->from->owner_class;
const Type r_type = info->rhs->value_ref->from->owner_class;
if(!r_type && l_type)
for(m_uint i = 0; i <= v->from->offset && !type; ++i) {
const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ?
func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid;
- if(!is_class(env->gwion, info->lhs->value_ref->type))
- CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym)))
- else {
+ if(!is_class(env->gwion, info->lhs->value_ref->type)) {
+ if(!(info->lhs = nspc_lookup_func1(nspc, sym))) {
+ const Value v = nspc_lookup_value1(nspc, insert_symbol(c));
+ if(isa(v->type, env->gwion->type[et_function]) < 0)
+ return NULL;
+ info->lhs = v->type->info->func;
+ }
+ } else {
DECL_OO(const Type, t, = nspc_lookup_type1(nspc, info->lhs->def->base->xid))
info->lhs = actual_type(env->gwion, t)->info->func;
}
Func_Base *base[2] = { info->lhs->def->base, info->rhs->def->base };
- if(fptr_tmpl_push(env, info) > 0) {
- if(fptr_rettype(env, info) > 0 &&
- fptr_arity(info) && fptr_args(env, base) > 0)
+ CHECK_BO(fptr_tmpl_push(env, info))
+ if(fptr_rettype(env, info) > 0 &&
+ fptr_arity(info) && fptr_args(env, base) > 0)
type = actual_type(env->gwion, info->lhs->value_ref->type) ?: info->lhs->value_ref->type;
- if(info->rhs->def->base->tmpl)
- nspc_pop_type(env->gwion->mp, env->curr);
- }
+ if(info->rhs->def->base->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
}
return type;
}
ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def) {
Arg_List base = def->base->args, arg = l->def->base->args;
while(base && arg) {
- arg->td = base->td;
+// arg->td = base->td;
+ arg->td = type2td(env->gwion, known_type(env, base->td), exp_self(l)->pos);
+// arg->type = known_type(env, base->td);
base = base->next;
arg = arg->next;
}
if(base || arg)
ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
l->def->base->flag = def->base->flag;
- if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class)
+// if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class)
UNSET_FLAG(l->def->base, global);
- l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
+ l->def->base->td = type2td(env->gwion, known_type(env, def->base->td), exp_self(l)->pos);
l->def->base->values = env->curr->info->value;
const m_bool ret = traverse_func_def(env, l->def);
if(l->def->base->func) {
env->curr->info->value = l->def->base->values;
}
}
- arg = l->def->base->args;
- while(arg) {
- arg->td = NULL;
- arg = arg->next;
- }
return ret;
}
ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
const Func_Def fdef = t->info->func->def;
if(!GET_FLAG(t->info->func->value_ref, global))
- l->owner = t->info->owner_class;
+ l->owner = t->info->value->from->owner_class;
CHECK_BB(_check_lambda(env, l, fdef))
exp_self(l)->type = l->def->base->func->value_ref->type;
return GW_OK;
if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) {
CHECK_BB(fptr_check(env, info))
if(!(info->exp->type = fptr_type(env, info)))
- ERR_B(info->lhs->def->base->pos, _("no match found"))
+ ERR_B(info->pos, _("no match found"))
return GW_OK;
}
Exp_Lambda *l = &info->exp->d.exp_lambda;
return exists != env->gwion->type[et_error] ? exists : NULL;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
.scope=env->scope->depth, .flag=tflag_scan0 };
- const Type _t = known_type(env, td->types->td);
- CHECK_BO(envset_push(&es, _t->info->owner_class, _t->info->owner))
+ const Type owner = t->info->value->from->owner_class;
+ CHECK_BO(envset_push(&es, owner, t->info->value->from->owner))
const Type ret = _scan_class(env, &info);
if(es.run)
- envset_pop(&es, _t->info->owner_class);
+ envset_pop(&es, owner);
return ret;
}
}
ANN static inline Type ptr_base(const Env env, const Type t) {
+ return (Type)vector_front(&t->info->tuple->types);
return known_type(env, t->info->cdef->base.tmpl->call->td);
}
if(access)
ERR_N(e->pos, _("can't cast %s value to Ptr"), access);
exp_setvar(e, 1);
- const Type t = imp->t;
- if(!tflag(t, tflag_check))
- CHECK_BN(traverse_class_def(env, t->info->cdef))
return imp->t;
}
return NULL;
static DTOR(ptr_struct_dtor) {
const Type base = *(Type*)(shred->mem + SZ_INT);
- const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->owner_class, base->info->owner);
+ const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->value->from->owner_class, base->info->value->from->owner);
const Type t = known_type(shred->info->vm->gwion->env, base->info->cdef->base.tmpl->call->td);
env_pop(shred->info->vm->gwion->env, scope);
struct_release(shred, t, *(m_bit**)o);
}
-
+#include "tmpl_info.h"
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->info->cdef->base.tmpl->call->td);
+ struct tmpl_info info = { .base=ts->t, .td=ts->td, .list=ts->t->info->cdef->base.tmpl->list };
+ const Type exists = tmpl_exists(env, &info);
+ if(exists)
+ return exists != env->gwion->type[et_error] ? exists : NULL;
+ const Type base = known_type(env, ts->td->types->td);
+ const Type t = new_type(env->gwion->mp, s_name(info.name), base);
t->info->parent = env->gwion->type[et_ptr];
+ SET_FLAG(t, abstract | ae_flag_final);
+ t->info->tuple = new_tupleform(env->gwion->mp, NULL);
+ t->nspc = new_nspc(env->gwion->mp, t->name);
+ vector_add(&t->info->tuple->types, (m_uint)base);
+ const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
+ mk_class(env, t, (loc_t){});
+ env_pop(env, scope);
+ nspc_add_type_front(t->info->value->from->owner, info.name, t);
if(isa(base, env->gwion->type[et_compound]) > 0) {
t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
if(!tflag(base, tflag_struct))
return exists != env->gwion->type[et_error] ? exists : NULL;
const Type base = known_type(env, ts->td->types->td);
const Type t = new_type(env->gwion->mp, s_name(info.name), base);
- t->info->owner = base->info->owner;
- t->info->owner_class = base->info->owner_class;
- t->info->ctx = base->info->ctx;
SET_FLAG(t, abstract | ae_flag_final);
set_tflag(t, tflag_infer);
- const m_uint scope = env_push(env, base->info->owner_class, base->info->owner);
-// mk_class(env, t, (loc_t){});
+ const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
+ mk_class(env, t, (loc_t){});
base2ref(env, base, t);
ref2base(env, t, base);
env_pop(env, scope);
- nspc_add_type_front(t->info->owner, info.name, t);
+ nspc_add_type_front(t->info->value->from->owner, info.name, t);
return t;
}
ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site"))
const Type t = actual_type(env->gwion, exp->func->type);
if(isa(t, env->gwion->type[et_function]) > 0 &&
- exp->func->exp_type == ae_exp_dot && !t->info->owner_class) {
+ exp->func->exp_type == ae_exp_dot && !t->info->value->from->owner_class) {
if(exp->args)
CHECK_OB(check_exp(env, exp->args))
return call2ufcs(env, exp, t->info->func->value_ref) ?
bool err = false;
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)) {
+ if(f && GET_FLAG(f->def->base, abstract)) {
if(!err) {
err = true;
gwerr_basic(
struct Op_Import opi = { .op=insert_symbol("@class_check"), .lhs=t,
.data=(uintptr_t)cdef, .pos=cdef->pos };
CHECK_OB(op_check(env, &opi))
- if(t->info->owner_class)
- CHECK_BB(ensure_check(env, t->info->owner_class))
+ if(t->info->value->from->owner_class)
+ CHECK_BB(ensure_check(env, t->info->value->from->owner_class))
if(tflag(t, tflag_check))
return GW_OK;
set_tflag(t, tflag_check);
ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, Exp_Call *const exp) {
if(!tmpl_valid(env, fdef))
return NULL;
+ if(exp->args && !exp->args->type)
+ return NULL;
const Func f = fdef->base->func;
const Func next = f->next;
f->next = NULL;
+ const Tmpl tmpl = { .list=fdef->base->tmpl->list, .call=exp->tmpl->call };
+ CHECK_BO(template_push_types(env, &tmpl));
const Func func = find_func_match(env, f, exp);
+ nspc_pop_type(env->gwion->mp, env->curr);
f->next = next;
if(func)
set_fflag(func, fflag_tmpl | fflag_valid);
const Value value = template_get_ready(env, ra->v, "template", i);
if(!value)
return NULL;
+ const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
if(vflag(ra->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);
fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, ra->types);
fdef->base->tmpl->base = i;
const Func func = ensure_tmpl(env, fdef, ra->e);
if(!func && !fdef->base->func)
free_func_def(env->gwion->mp, fdef);
+ if(func && vflag(ra->v, vflag_builtin))
+ set_vflag(func->value_ref, vflag_builtin);
return func;
}
struct ResolverArgs ra = {.v = v, .e = exp, .tmpl_name = tmpl_name, .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);
+if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl)
+(void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl);
+//const Tmpl tmpl = { .list=v->frombase->tmpl->list, .call=ra->types };
+//CHECK_BO(template_push_types(env, &tmpl));
const Func m_func = !is_fptr(env->gwion, v->type) ?
func_match(env, &ra) :fptr_match(env, &ra);
+if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl)
+nspc_pop_type(env->gwion->mp, env->curr);
+//nspc_pop_type(env->gwion->mp, env->curr);
+ env_pop(env, scope);
if(es.run)
envset_pop(&es, v->from->owner_class);
- env_pop(env, scope);
env->func = former;
return m_func;
}
}
static inline Type scan0_type(const Env env, const m_str name, const Type t) {
- const Type type = new_type(env->gwion->mp, name, t);
- type->info->ctx = env->context;
- return type;
+ return new_type(env->gwion->mp, name, t);
}
ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) {
CHECK_BB(scan0_defined(env, fptr->base->xid, fptr->base->td->pos));
const m_str name = s_name(fptr->base->xid);
const Type t = scan0_type(env, name, env->gwion->type[et_fptr]);
- t->info->owner = !(!env->class_def && GET_FLAG(fptr->base, global)) ?
- env->curr : env->global_nspc;
- t->info->owner_class = env->class_def;
- if(GET_FLAG(fptr->base, global))
- context_global(env);
+ const bool global = !env->class_def && GET_FLAG(fptr->base, global);
t->nspc = new_nspc(env->gwion->mp, name);
t->flag |= fptr->base->flag;
fptr->type = t;
+ if(global) {
+ context_global(env);
+ env_push_global(env);
+ }
fptr->value = mk_class(env, t, fptr->base->pos);
+ if(global)
+ env_pop(env, 0);
valuefrom(env, fptr->value->from, fptr->base->pos);
fptr_def(env, fptr);
if(env->class_def)
fptr_assign(env, fptr);
set_vflag(fptr->value, vflag_func);
- add_type(env, t->info->owner, t);
- mk_class(env, t, fptr->base->pos);
+ add_type(env, t->info->value->from->owner, t);
type_addref(t);
return GW_OK;
}
if(GET_FLAG(tdef->ext, global))
context_global(env);
add_type(env, nspc, t);
- t->info->owner = nspc;
- t->info->owner_class = env->class_def;
tdef->type = t;
if(base->nspc)
nspc_addref((t->nspc = base->nspc));
t->flag = tdef->ext->flag;
if(tdef->ext->array && !tdef->ext->array->exp)
set_tflag(t, tflag_empty);
+ mk_class(env, tdef->type, tdef->pos);
}
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
CHECK_BB(scan0_class_def(env, cdef))
tdef->type = cdef->base.type;
cdef->base.tmpl = tdef->tmpl;// check cpy
+ mk_class(env, tdef->type, tdef->pos);
return GW_OK;
}
ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) {
tdef->type = type_copy(env->gwion->mp, base);
tdef->type->info->func = base->info->func;
- nspc_addref(tdef->type->nspc);
tdef->type->name = s_name(tdef->xid);
tdef->type->info->parent = base;
add_type(env, env->curr, tdef->type);
CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos))
DECL_OB(const Type, base, = tdef->tmpl ? find_type(env, tdef->ext) : known_type(env, tdef->ext))
CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos))
+ const bool global = GET_FLAG(tdef->ext, global); // TODO: handle global in class
+ if(global) {
+ context_global(env);
+ env_push_global(env);
+ }
if(isa(base, env->gwion->type[et_function]) < 0) {
if(!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
typedef_simple(env, tdef, base);
typedef_fptr(env, tdef, base);
if(!tdef->distinct && !tdef->when)
scan0_implicit_similar(env, tdef->type, base);
+ if(global)
+ env_pop(env, 0);
set_tflag(tdef->type, tflag_typedef);
return GW_OK;
}
const Symbol sym = scan0_sym(env, "enum", edef->pos);
t->name = edef->xid ? s_name(edef->xid) : s_name(sym);
t->info->parent = env->gwion->type[et_int];
- const Nspc nspc = GET_FLAG(edef, global) ? env->global_nspc : env->curr;
- t->info->owner = nspc;
- t->info->owner_class = env->class_def;
- add_type(env, nspc, t);
+ const bool global = GET_FLAG(edef, global); // TODO: handle global in class
+ if(global) {
+ context_global(env);
+ env_push_global(env);
+ }
+ add_type(env, env->curr, t);
mk_class(env, t, edef->pos);
+ if(global)
+ env_pop(env, 0);
// scan0_implicit_similar(env, t, env->gwion->type[et_int]);
return t;
}
const m_str name = s_name(s);
const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]);
t->nspc = new_nspc(env->gwion->mp, name);
- t->info->owner = t->nspc->parent = env->curr;
- t->info->owner_class = env->class_def;
+ t->nspc->parent = env->curr;
t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
add_type(env, env->curr, t);
mk_class(env, t, loc);
ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
CHECK_BB(env_storage(env, udef->flag, udef->pos))
CHECK_BB(scan0_global(env, udef->flag, udef->pos))
- const m_uint scope = !GET_FLAG(udef, global) ? env->scope->depth :
- env_push_global(env);
+ const bool global = GET_FLAG(udef, global); // TODO: handle global in class
+ if(global) {
+ context_global(env);
+ env_push_global(env);
+ }
if(GET_FLAG(udef, global))
context_global(env);
CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
SET_ACCESS(udef, udef->type);
if(udef->tmpl)
union_tmpl(env, udef);
- if(GET_FLAG(udef, global))
- env_pop(env, scope);
+ if(global)
+ env_pop(env, 0);
set_tflag(udef->type, tflag_scan0);
return GW_OK;
}
while(owner) {
if(t == owner)
ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name);
- owner = owner->info->owner_class;
+ owner = owner->info->value->from->owner_class;
}
return t;
}
set_tflag(t, tflag_struct);
}
t->info->tuple = new_tupleform(env->gwion->mp, parent);
- t->info->owner = env->curr;
- t->info->owner_class = env->class_def;
t->nspc = new_nspc(env->gwion->mp, t->name);
t->nspc->parent = env->curr;
t->info->cdef = cdef;
t->flag |= cdef->flag;
- add_type(env, t->info->owner, t);
+// add_type(env, t->info->value->from->owner, t);
cdef_flag(cdef, t);
if(cdef->base.ext && cdef->base.ext->array)
set_tflag(t, tflag_typedef);
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_tflag(cdef->base.type, tflag_scan0);
+ (void)mk_class(env, cdef->base.type, cdef->pos);
+ add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
if(cdef->body)
CHECK_BB(env_body(env, cdef, scan0_section))
- (void)mk_class(env, cdef->base.type, cdef->pos);
return GW_OK;
}
ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
parent = parent->info->parent;
}
- } while((owner = owner->info->owner_class));
+ } while((owner = owner->info->value->from->owner_class));
return GW_OK;
}
DECL_OO(const Type ,t, = void_type(env, decl->td))
if(decl->td->xid == insert_symbol("auto") && decl->type)
return decl->type;
- if(GET_FLAG(t, private) && t->info->owner != env->curr)
+ if(GET_FLAG(t, private) && t->info->value->from->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))
ERR_O(exp_self(decl)->pos, _("can't use protected type %s"), t->name)
if(global) {
if(env->context)
env->context->global = 1;
- if(!is_global(decl->type->info->owner, env->global_nspc))
+ if(!is_global(decl->type->info->value->from->owner, env->global_nspc))
ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
}
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
set_vflag(v, vflag_builtin);
SET_FLAG(v, const);
set_vflag(v, vflag_valid);
- nspc_add_value(edef->t->info->owner, list->xid, v);
+ nspc_add_value(edef->t->info->value->from->owner, list->xid, v);
vector_add(&edef->values, (vtype)v);
} while((list = list->next));
return GW_OK;
if(tflag(t, tflag_scan1))
return GW_OK;
set_tflag(t, tflag_scan1);
- if(t->info->owner_class)
- CHECK_BB(ensure_scan1(env, t->info->owner_class))
+ if(t->info->value->from->owner_class)
+ CHECK_BB(ensure_scan1(env, t->info->value->from->owner_class))
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
const Type t = type_copy(env->gwion->mp, base);
t->info->parent = base;
t->name = func->name;
- t->info->owner = env->curr;
- t->info->owner_class = env->class_def;
t->info->func = func;
return t;
}
ANN2(1,2) static Value func_value(const Env env, const Func f,
const Value overload) {
const Type t = func_type(env, f);
- const Value v = new_value(env->gwion->mp, t, t->name);
+ const Value v = t->info->value = new_value(env->gwion->mp, t, t->name);
valuefrom(env, v->from, f->def->base->pos);
CHECK_OO(scan2_func_assign(env, f->def, f, v))
if(!overload) {
}
ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
- if(GET_FLAG(fdef->base, global))
+ if(GET_FLAG(fdef->base, global) && !env->class_def)
env->context->global = 1;
const Func_Def f = !is_cpy(fdef) ?
fdef : scan2_cpy_fdef(env, fdef);
const Type t = cdef->base.type;
if(tflag(t, tflag_scan2))
return GW_OK;
- if(t->info->owner_class)
- CHECK_BB(ensure_scan2(env, t->info->owner_class))
+ if(t->info->value->from->owner_class)
+ CHECK_BB(ensure_scan2(env, t->info->value->from->owner_class))
set_tflag(t, tflag_scan2);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
}
ANN static m_bool _template_push(const Env env, const Type t) {
- if(t->info->owner_class)
- CHECK_BB(template_push(env, t->info->owner_class))
+ if(t->info->value->from->owner_class)
+ CHECK_BB(template_push(env, t->info->value->from->owner_class))
if(tflag(t, tflag_tmpl))
return push_types(env, t->info->cdef->base.tmpl); // incorrect
return GW_OK;
static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->pos))
- const Symbol sym = func_symbol(env, t->info->owner->name, t->info->func->name, tl_name, 0);
+ const Symbol sym = func_symbol(env, t->info->value->from->owner->name, t->info->func->name, tl_name, 0);
free_mstr(env->gwion->mp, tl_name);
- const Type base_type = nspc_lookup_type1(t->info->owner, sym);
+ const Type base_type = nspc_lookup_type1(t->info->value->from->owner, sym);
if(base_type)
return base_type;
const Type ret = type_copy(env->gwion->mp, t);
ret->info->parent = t;
+ ret->info->value = t->info->func->value_ref;
ret->name = s_name(sym);
set_tflag(ret, tflag_ftmpl);
- nspc_add_type_front(t->info->owner, sym, ret);
+ nspc_add_type_front(t->info->value->from->owner, sym, ret);
void* func_ptr = t->info->func->def->d.dl_func_ptr;
if(vflag(t->info->func->value_ref, vflag_builtin))
t->info->func->def->d.dl_func_ptr = NULL;
if(vflag(t->info->func->value_ref, vflag_member))
set_vflag(value, vflag_member);
value->d.func_ref = func;
- value->from->owner = t->info->owner;
- value->from->owner_class = t->info->owner_class;
+ value->from->owner = t->info->value->from->owner;
+// value->from->owner_class = t->info->owner_class;
func->value_ref = value;
func->def->base->tmpl = mk_tmpl(env, t->info->func->def->base->tmpl, td->types);
def->base->func = func;
- nspc_add_value_front(t->info->owner, sym, value);
+ nspc_add_value_front(t->info->value->from->owner, sym, value);
if(vflag(t->info->func->value_ref, vflag_builtin)) {
builtin_func(env->gwion->mp, func, func_ptr);
t->info->func->def->d.dl_func_ptr = func_ptr;
last = last->next;
Array_Sub array = last->array;
DECL_OO(const Type, base, = find_type(env, td))
- if(base->info->ctx && base->info->ctx->error)
+ const Context ctx = base->info->value->from->ctx;
+ if(ctx && ctx->error)
ERR_O(td->pos, _("type '%s' is invalid"), base->name)
DECL_OO(const Type, type, = scan_type(env, base, td))
const Type t = !td->ref ? type : ref(env, td);
free_code_instr(a->instr, gwion);
}
free_vector(gwion->mp, a->instr);
- }
+ } else if(a->tmpl_types.ptr)
+ vector_release(&a->tmpl_types);
free_mstr(gwion->mp, a->name);
mp_free(gwion->mp , VM_Code, a);
}
var B b;
fun A test() {
<<< "lol" >>>;
+ return a;
}
fun void test2:[C](C o) {
<<< o >>>;