-Subproject commit 7c1340d71a2c83dfad0c1d933732e7d223beab59
+Subproject commit 6477df1118c1c7b011583f14cae9e7d185f2cbeb
--- /dev/null
+#!enum Enum {
+#! bar,
+#! foo
+#!}
+#!class C:[const int N] {
+#!class C:[const Enum N] {
+#! N :=> var auto n;
+#! <<< "N:${N} n:${n}" >>>;
+#!}
+
+fun void foo:[T, const float N]() {
+#! <<< __func__ >>>;
+ <<< N >>>;
+#! <<< "heyo">>>;
+}
+#!const int i;
+#!new C:[Enum.foo];
+#!new C:[2];
+#!r
+#!foo:[int, Enum.foo]();
+foo:[int, .2]();
+#!foo:[int, 2]();
adc ~> var Gain g ~> dac;
g.chan(0);
+
spork { while(true) { (g.gain() == .2 ? .2 : .1) => g.gain; .15::second => now; }};
+
for(var int i; i < 5; i++) {
<<< g.op() >>>;
i => g.op;
<<< g.op() >>>;
2::second => now;
}
+
1 => adc.op;
}
ANN static inline bool is_ctor(const Func_Def fdef) {
- return !strcmp(s_name(fdef->base->xid), "@ctor");
+ return !strcmp(s_name(fdef->base->tag.sym), "@ctor");
}
#endif
ANEW ANN Type type_copy(MemPool, const Type type);
ANN Value find_value(const Type, const Symbol);
ANN m_bool isa(const Type, const Type) __attribute__((pure));
-ANN m_bool isres(const Env, const Symbol, const loc_t pos);
+ANN m_bool isres(const Env, const Tag);
ANN Type array_type(const Env, const Type, const m_uint);
ANN Type find_common_anc(const Type, const Type) __attribute__((pure));
ANN Type array_base(Type) __attribute__((pure));
#ifndef __GWION
#define __GWION
-// typedef struct Gwion_* Gwion;
#include "arg.h"
#include "plug.h"
#include "driver.h"
threadpool_add(shred->info->vm->gwion->data->tpool, fun, arg);
}
+typedef struct {
+ VM_Shred shred;
+ m_bit *mem;
+ m_bit *RETURN;
+ MemPool mp;
+} TpShredInfo;
#endif
f_xfun addr;
};
union {
- Union_List list; // union
+ Variable_List list; // union
struct Vector_ v;
MP_Vector *mpv;
// ID_List curr;// enum
ANN static inline void set_decl_ref(const Exp e) {
if (e->exp_type == ae_exp_decl)
- SET_FLAG(e->d.exp_decl.vd.value, late);
+ SET_FLAG(e->d.exp_decl.var.vd.value, late);
}
ANN void func_operator(const Func_Def fdef, struct Op_Import *opi);
member->base->exp_type == ae_exp_cast;
}
-#define is_new(a) !strcmp(s_name((a)->base->xid), "new")
+#define is_new(a) !strcmp(s_name((a)->base->tag.sym), "new")
#endif
ANN static inline bool is_spread_tmpl(const Tmpl *tmpl) {
const Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1);
- return !strcmp(s_name(spec->xid), "...");
+ return !strcmp(s_name(spec->tag.sym), "...");
}
ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl);
ANN m_bool template_push_types(const Env, const Tmpl *);
ANN m_bool template_push(const Env env, const Type t);
ANN Tmpl *mk_tmpl(const Env, const Tmpl *, const Type_List);
+/*
+//! returns the Tmpl of a class or enum def
+ANN static inline Tmpl* get_tmpl(const Type t) {
+ return tflag(t, tflag_cdef)
+ ? t->info->cdef->base.tmpl
+// : tflag(t, tflag_udef)
+ : t->info->udef->tmpl;
+// : NULL;
+}
+*/
+ANN static inline Tmpl* get_tmpl(const Type t) {
+ return tflag(t, tflag_udef)
+ ? t->info->udef->tmpl
+ : t->info->cdef->base.tmpl;
+// : tflag(t, tflag_udef)
+// : NULL;
+}
+
#define POP_RET(a) \
{ \
nspc_pop_type(env->gwion->mp, env->curr); \
ANN Func find_template_match(const Env env, const Value value,
Exp_Call *const exp);
ANN Func find_func_match(const Env env, const Func up, Exp_Call *const exp);
+ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread);
#endif
if (a->scope && b->value) value_remref(b->value, a->gwion);
}
-ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
+ANN static void clean_variable(Clean *a, Variable *b) {
if (b->td) clean_type_decl(a, b->td);
clean_var_decl(a, &b->vd);
}
+ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
+ clean_variable(a, &b->var);
+}
+
ANN static void clean_exp_binary(Clean *a, Exp_Binary *b) {
clean_exp(a, b->lhs);
clean_exp(a, b->rhs);
ANN static void clean_arg_list(Clean *a, Arg_List b) {
for(uint32_t i = 0; i < b->len; i++) {
Arg *arg = mp_vector_at(b, Arg, i);
- if (arg->td) clean_type_decl(a, arg->td);
- clean_var_decl(a, &arg->var_decl);
+ clean_variable(a, &arg->var);
}
}
}
#define clean_enum_def clean_dummy
-ANN static void clean_union_list(Clean *a, Union_List b) {
+ANN static void clean_variable_list(Clean *a, Variable_List b) {
for(uint32_t i = 0; i < b->len; i++) {
- Union_Member *tgt = mp_vector_at(b, Union_Member, i);
+ Variable *tgt = mp_vector_at(b, Variable, i);
clean_type_decl(a, tgt->td);
clean_var_decl(a, &tgt->vd);
}
}
ANN static void clean_union_def(Clean *a, Union_Def b) {
- clean_union_list(a, b->l);
+ clean_variable_list(a, b->l);
if (b->tmpl) clean_tmpl(a, b->tmpl);
}
ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) {
CHECK_BB(emit_interp(emit, *exp));
if (!(emit->env->func &&
- emit->env->func->def->base->xid == insert_symbol("@gack")))
+ emit->env->func->def->base->tag.sym == insert_symbol("@gack")))
emit_add_instr(emit, GackEnd);
else emit_regtomem(emit, SZ_INT, -SZ_INT);
return GW_OK;
ANN static m_bool _decl_static(const Emitter emit, const Exp_Decl *decl,
const Var_Decl *var_decl, const uint is_ref) {
const Value v = var_decl->value;
- if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, is_ref));
+ if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->var.td, is_ref));
else CHECK_BB(emit_exp(emit, decl->args));
CHECK_BB(emit_dot_static_data(emit, v, 1));
emit_add_instr(emit, Assign);
ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) {
const Type t = decl->type;
const bool emit_addr = exp_getvar(exp_self(decl));
- if(GET_FLAG(decl->vd.value, late) || GET_FLAG(decl->td, late)) {
+ if(GET_FLAG(decl->var.vd.value, late) || GET_FLAG(decl->var.td, late)) {
if(!emit_addr)
decl_expand(emit, t);
return GW_OK;
const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
if (is_obj && !is_ref && !exp_self(decl)->ref) {
- if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
+ if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref));
else CHECK_BB(emit_exp(emit, decl->args));
}
f_instr *exec = (f_instr *)allocmember;
const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
if (is_obj && !is_ref) {
- if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
+ if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref));
else CHECK_BB(emit_exp(emit, decl->args));
}
if (type->size > SZ_INT)
ANN static void set_late(const Exp_Decl *decl, const Var_Decl *var) {
const Value v = var->value;
if (!exp_getvar(exp_self(decl)) &&
- (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->td, late)))
+ (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->var.td, late)))
SET_FLAG(v, late);
else UNSET_FLAG(v, late);
}
}
ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) {
- const m_bool global = GET_FLAG(decl->td, global);
+ const m_bool global = GET_FLAG(decl->var.td, global);
const uint var = exp_getvar(exp_self(decl));
- const uint ref = GET_FLAG(decl->td, late) || type_ref(decl->type);
- Var_Decl *vd = &decl->vd;
+ const uint ref = GET_FLAG(decl->var.td, late) || type_ref(decl->type);
+ Var_Decl *vd = &decl->var.vd;
const Value v = vd->value;
const uint r = ref || GET_FLAG(v, late);
- if (GET_FLAG(decl->td, static))
+ if (GET_FLAG(decl->var.td, static))
CHECK_BB(emit_exp_decl_static(emit, decl, vd, r, var));
else if (!global)
CHECK_BB(emit_exp_decl_non_static(emit, decl, vd, r, var));
CHECK_BB(op_emit(emit, &opi));
}
set_late(decl, vd);
- if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) &&
- GET_FLAG(v, late) && late_array(decl->td)
+ if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->var.td, late) &&
+ GET_FLAG(v, late) && late_array(decl->var.td)
&& GET_FLAG(v->type, abstract)) {
- env_err(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"),
- v->type->name, !GET_FLAG(decl->td, const) ? "var" : "const");
+ env_err(emit->env, decl->var.td->tag.loc, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"),
+ v->type->name, !GET_FLAG(decl->var.td, const) ? "var" : "const");
if(v->type->nspc->vtable.ptr) {
const Vector vec = &v->type->nspc->vtable;
for(m_uint i = 0; i < vector_size(vec); i++) {
if(decl->args && !strncmp(decl->args->type->name, "partial:", 8))
ERR_B(decl->args->pos, "unresolved partial");
CHECK_BB(ensure_emit(emit, t));
- const m_bool global = GET_FLAG(decl->td, global);
+ const m_bool global = GET_FLAG(decl->var.td, global);
const m_uint scope =
!global ? emit->env->scope->depth : emit_push_global(emit);
const m_bool ret = emit_decl(emit, decl);
if (global) emit_pop(emit, scope);
- if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
+ if(emit->status.in_return && GET_FLAG(decl->var.vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
emit_add_instr(emit, GWOP_EXCEPT);
return ret;
}
ANN static void tmpl_prelude(const Emitter emit, const Func f) {
const Instr gtmpl = emit_add_instr(emit, GTmpl);
gtmpl->m_val = (m_uint)f->def;
- gtmpl->m_val2 = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
+ gtmpl->m_val2 = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc);
}
ANN static Instr get_prelude(const Emitter emit, const Func f,
struct Exp_ lhs = {
.exp_type = ae_exp_primary,
.type = arg->type,
- .pos = arg->td->pos,
+ .pos = arg->var.td->tag.loc,
.d = {
.prim = { .prim_type = ae_prim_id }
}
struct Exp_ rhs = {
.exp_type = ae_exp_primary,
.type = me->emit->gwion->type[et_bool],
- .pos = arg->td->pos,
+ .pos = arg->var.td->tag.loc,
.d = {
.prim = { .prim_type = ae_prim_id }
}
struct Exp_ bin = {
.exp_type = ae_exp_binary,
.type = arg->type,
- .pos = arg->td->pos,
+ .pos = arg->var.td->tag.loc,
.d = {
.exp_binary = {
.lhs = &lhs,
struct Op_Import opi = {.op = sym,
.lhs = arg->type,
.rhs = arg->type,
- .pos = me->fdef->base->pos,
+ .pos = me->fdef->base->tag.loc,
.data = (uintptr_t)&bin.d};
CHECK_BB(op_emit(emit, &opi));
const Instr instr = emit_add_instr(emit, BranchEqInt);
const Value v = cap->orig;
struct Exp_ exp = {
.d = { .prim = {
- .d = { .var = cap->xid },
+ .d = { .var = cap->tag.sym },
.value = v,
.prim_type = ae_prim_id
}},
if (exp->cast_to) CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to));
if (isa(e->type, emit->gwion->type[et_object]) > 0 &&
(e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
- e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) &&
+ e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.var.td, late) &&
exp_getuse(e) && !exp_getvar(e) &&
- GET_FLAG(e->d.exp_decl.vd.value, late))
- emit_fast_except(emit, e->d.exp_decl.vd.value->from, e->pos);
+ GET_FLAG(e->d.exp_decl.var.vd.value, late))
+ emit_fast_except(emit, e->d.exp_decl.var.vd.value->from, e->pos);
} while ((exp = exp->next));
return GW_OK;
}
emit_memsetimm(emit, key_offset, -1);
stmt->v->from->offset = val_offset;
//value_addref(stmt->v);
-_nspc_add_value(emit->env->curr, stmt->sym, stmt->v);
+_nspc_add_value(emit->env->curr, stmt->tag.sym, stmt->v);
emit_debug(emit, stmt->v);
if (stmt->idx) {
stmt->idx->v->from->offset = key_offset;
-_nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v);
+_nspc_add_value(emit->env->curr, stmt->idx->tag.sym, stmt->idx->v);
//value_addref(stmt->idx->v);
emit_debug(emit, stmt->idx->v);
}
Handler *handler = mp_vector_at(handlers, Handler, i);
const Instr instr = emit_add_instr(emit, HandleEffect);
instr->m_val = emit->status.effect = offset;
- instr->m_val2 = (m_uint)handler->xid;
+ instr->m_val2 = (m_uint)handler->tag.sym;
CHECK_BB(scoped_stmt(emit, handler->stmt));
emit_try_goto(emit, v);
instr->m_val = emit_code_size(emit);
ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- const Type type = arg->var_decl.value->type;
+ const Type type = arg->var.vd.value->type;
emit->code->stack_depth += type->size;
- arg->var_decl.value->from->offset = emit_localn(emit, type);
- emit_debug(emit, arg->var_decl.value);
- _nspc_add_value(emit->env->curr, insert_symbol(arg->var_decl.value->name), arg->var_decl.value);
+ arg->var.vd.value->from->offset = emit_localn(emit, type);
+ emit_debug(emit, arg->var.vd.value);
+ _nspc_add_value(emit->env->curr, insert_symbol(arg->var.vd.value->name), arg->var.vd.value);
}
}
}
ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
- if (f->def->base->xid == insert_symbol("@dtor"))
+ if (f->def->base->tag.sym == insert_symbol("@dtor"))
return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC);
- else if (f->def->base->xid == insert_symbol("@gack")) {
+ else if (f->def->base->tag.sym == insert_symbol("@gack")) {
emit_regmove(emit, -SZ_INT - f->value_ref->from->owner_class->size);
const Instr instr = emit_add_instr(emit, RegPushMem);
instr->m_val = SZ_INT;
}
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
- if (fdef->base->xid == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]);
+ if (fdef->base->tag.sym == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]);
if (fdef->base->args) emit_func_def_args(emit, fdef->base->args);
if (fdef->d.code) {
if(!fdef->builtin) {
emit_regtomem4(emit, fdef->stack_depth, offset);
}
+static INSTR(ConstGenericEOC) {
+ shred->reg -= instr->m_val;
+ memcpy((void*)instr->m_val2, shred->reg, instr->m_val);
+//a exit(12);
+}
ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK;
const Func func = f->base->func;
if ((vflag(func->value_ref, vflag_builtin) &&
safe_tflag(emit->env->class_def, tflag_tmpl)) || (fdef->base->tmpl && is_new(f))) {
const Func base =
- nspc_lookup_func1(func->value_ref->from->owner, f->base->xid);
+ nspc_lookup_func1(func->value_ref->from->owner, f->base->tag.sym);
builtin_func(emit->gwion, func, (f_xfun)base->code->native_func);
return GW_OK;
}
const uint global = GET_FLAG(f->base, global);
const m_uint scope =
!global ? emit->env->scope->depth : env_push_global(emit->env);
+ if(fdef->base->tmpl) { // check is call?
+ if(tmplarg_ntypes(fdef->base->tmpl->call) != fdef->base->tmpl->call->len) {
+emit_push_code(emit, "const-generic"); // better name?
+uint32_t size = 0;
+// create new code here
+ for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) {
+ TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i);
+ if(targ->type == tmplarg_td)continue;
+ // spec could be null cause of spread ops
+ Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i);
+ if(!spec) break;
+CHECK_BB(emit_exp(emit, targ->d.exp));
+//oemit_regmove(emit, -targ->d.exp->type->size);
+//emit_regmove(emit, -SZ_INT);
+//pop_exp(emit, targ->d.exp);
+size += targ->d.exp->type->size;
+ }
+// set variables values
+// and remove code
+//emit_regmove(emit, -size);
+fdef->base->func->value_ref->type->nspc->class_data_size = size;
+fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size);
+const Instr instr = emit_add_instr(emit, ConstGenericEOC);
+instr->m_val = size;
+instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data;
+const VM_Code code = finalyze(emit, EOC);
+//const VM_Code code = finalyze(emit, ConstGenericEOC);
+const VM_Shred shred = new_vm_shred(emit->gwion->mp, code);
+vm_add_shred(emit->gwion->vm, shred);
+//shred->info->me->ref++;
+//vm_run(emit->gwion->vm);
+//emit->gwion->vm->
+const bool loop = emit->gwion->vm->shreduler->loop;
+vm_run(emit->gwion->vm);
+// alloc space
+//fdef->base->func->value_ref->type->nspc->class_data_size = size;
+//fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size);
+//memcpy(fdef->base->func->value_ref->type->nspc->class_data, shred->reg, size);
+// => copy data
+emit->gwion->vm->bbq->is_running = true;
+emit->gwion->vm->shreduler->loop = loop;
+//release(shred->info->me, emit->gwion->vm->cleaner_shred);
+//}
+ }
+ }
emit_func_def_init(emit, func);
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")) {
+ if (!strcmp(s_name(fdef->base->tag.sym), "@gack")) {
emit_local(emit, emit->gwion->type[et_int]);
emit_memsetimm(emit, SZ_INT, 0);
} else if(fdef->captures) emit_lambda_capture(emit, fdef);
ANN static m_bool emit_class_tmpl(const Emitter emit, const Tmpl *tmpl, const Nspc nspc) {
if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
- emit_push_code(emit, "tmpl");
+ emit_push_code(emit, "tmpl"); // make better name
for(uint32_t i = 0; i < tmpl->list->len; i++) {
const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
if(likely(targ.type == tmplarg_td)) continue;
CHECK_BB(emit_exp(emit, targ.d.exp));
const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
- const Value v = nspc_lookup_value1(nspc, spec.xid);
+ const Value v = nspc_lookup_value1(nspc, spec.tag.sym);
emit_pushimm(emit, (m_uint)v);
const Instr instr = emit_add_instr(emit, set);
instr->m_val2 = targ.d.exp->type->size;
ANN void unload_context(const Context ctx, const Env env) {
const Nspc global = ctx->nspc->parent;
- if(global != env->global_nspc) exit(53);
+ assert(global == env->global_nspc);
context_remref(ctx, env->gwion);
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
const Nspc user = (Nspc)vector_at(&env->scope->nspc_stack, 1);
}
#undef RETURN_TYPE
-ANN Type find_type(const Env env, Type_Decl *path) {
- DECL_OO(Type, type, = find_initial(env, path->xid));
- while ((path = path->next) && type && type->nspc) {
+ANN Type find_type(const Env env, Type_Decl *td) {
+ DECL_OO(Type, type, = find_initial(env, td->tag.sym));
+ while ((td = td->next) && type && type->nspc) {
const Nspc nspc = type->nspc;
- if(!(type = find_in_parent(type, path->xid)))
- ERR_O(path->pos, _("...(cannot find class '%s' in nspc '%s')"),
- s_name(path->xid), nspc->name)
+ if(!(type = find_in_parent(type, td->tag.sym)))
+ ERR_O(td->tag.loc, _("...(cannot find class '%s' in nspc '%s')"),
+ s_name(td->tag.sym), nspc->name)
}
return type;
}
return value;
}
-ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) {
+ANN m_bool isres(const Env env, const Tag tag) {
const Map map = &env->gwion->data->id;
for (m_uint i = 0; i < map_size(map); i++) {
- if (xid == (Symbol)VKEY(map, i))
- ERR_B(pos, _("%s is reserved."), s_name(xid));
+ if (tag.sym == (Symbol)VKEY(map, i))
+ ERR_B(tag.loc, _("%s is reserved."), s_name(tag.sym));
}
return GW_OK;
}
t->info->value->from->ctx ? t->info->value->from->ctx->nspc
: es->env->curr);
env_push_type((void *)es->env, t); // do not push if is a function?
- if (tflag(t, tflag_tmpl))
- CHECK_BB(template_push_types(
- es->env, t->info->cdef->base.tmpl)); // incorrect templates?
+ if (tflag(t, tflag_tmpl)) {
+ const Tmpl *tmpl = get_tmpl(t);
+ CHECK_BB(template_push_types(es->env, tmpl));
+ }
return GW_OK;
}
const Type_List tl = f->def->base->tmpl->call;
if(!tl) return;
const Specialized *spec = mp_vector_at(f->def->base->tmpl->list, Specialized, f->def->base->tmpl->list->len - 1);
- if(!strcmp(s_name(spec->xid), "...")) {
+ if(!strcmp(s_name(spec->tag.sym), "...")) {
const uint32_t len = tmplarg_ntypes(tl);
f->code->types = new_mp_vector(gwion->mp, Type, len);
uint32_t n = 0;
bool ctor = false;
if (env->func && env->func->def) {
if(!is_ctor(env->func->def))
- gwerr_secondary("in function", env->name, env->func->def->base->pos);
+ gwerr_secondary("in function", env->name, env->func->def->base->tag.loc);
else {
- gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos);
+ gwerr_secondary("in class pre constructor", env->name,
+ env->class_def->info->cdef->base.tag.loc);
ctor = true;
}
}
if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef))
- gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos);
+ gwerr_secondary("in class", env->name, env->class_def->info->cdef->base.tag.loc);
}
ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt,
ANN2(1) void add_template(const Env env, const Type t) {
nspc_push_type(env->gwion->mp, env->curr); //
- Specialized_List sl = t->info->cdef->base.tmpl->list;
+ Specialized_List sl = get_tmpl(t)->list;
for(uint32_t i = 0; i < sl->len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
+ nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]);
}
}
tflag(t, tflag_compound);
gwi_add_type(gwi, t);
import_class_ini(gwi->gwion->env, t);
- if (t->info->cdef && t->info->cdef->base.tmpl) {
+ if (t->info->cdef && get_tmpl(t)) {
gwi->tmpls++;
add_template(gwi->gwion->env, t);
set_tflag(t, tflag_cdef);
DECL_OB(const Symbol, sym, = __str2sym(gwion, &tdc));
struct AC ac = {.str = tdc.str, .pos = pos};
CHECK_BB(ac_run(gwion, &ac));
- vd->xid = sym;
+ vd->tag = MK_TAG(sym, pos);
vd->value = NULL;
- vd->pos = pos;
return GW_OK;
}
struct td_checker *tdc, Specialized_List *sl) {
if(unlikely(!strncmp(tdc->str, "...", 3))) {
tdc->str += 3;
- Specialized spec = {
- .xid = insert_symbol(gwion->st, "..."),
- .pos = tdc->pos
- };
+ Specialized spec = { .tag = MK_TAG(insert_symbol(gwion->st, "..."), tdc->pos) };
mp_vector_add(gwion->mp, sl, Specialized, spec);
return true;
}
DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc));
// TODO: handle traits?
- Specialized spec = {
- .xid = sym,
- .pos = tdc->pos
- };
+ Specialized spec = { .tag = MK_TAG(sym, tdc->pos) };
mp_vector_add(gwion->mp, sl, Specialized, spec);
if (*tdc->str == ',') {
++tdc->str;
ANN static Type_Decl *_str2td(const Gwion gwion, struct td_checker *tdc);
ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) {
+ // we probably need smth better
if(isalpha(*tdc->str)) {
TmplArg targ = {
.type = tmplarg_td,
if (!str2tl(gwion, tdc, tl))
return false;
}
- } else exit(6);
+ } else GWION_ERR_B(tdc->pos, "invalid character in template list");
return true;
}
free_arg_list(gwion->mp, args);
return (Arg_List)GW_ERROR;
}
- mp_vector_add(gwion->mp, &args, Arg, (Arg){ .td = td });
+ mp_vector_add(gwion->mp, &args, Arg, (Arg){ .var = {.td = td }});
} while(*tdc->str == ',' && tdc->str++);
return args;
}
text_add(text, t->name);
}
+ANN Exp td2exp(const MemPool mp, const Type_Decl *td) {
+ Exp base = new_prim_id(mp, td->tag.sym, td->tag.loc);
+ Type_Decl *next = td->next;
+ while(next) {
+ base = new_exp_dot(mp, base, next->tag.sym, td->tag.loc);
+ next = next->next;
+ }
+ return base;
+}
+
ANN static m_bool td_info_run(const Env env, struct td_info *info) {
+ const Gwion gwion = env->gwion;
Type_List tl = info->tl;
for(uint32_t i = 0; i < tl->len; i++) {
if (i) text_add(&info->fmt->ls->text, ",");
- TmplArg targ = *mp_vector_at(tl, TmplArg, i);
- if(targ.type == tmplarg_td) {
- DECL_OB(const Type, t, = known_type(env, targ.d.td));
- td_fullname(env, &info->fmt->ls->text, t);
- } else gwfmt_exp(info->fmt, targ.d.exp);
+ TmplArg *targ = mp_vector_at(tl, TmplArg, i);
+ if(targ->type == tmplarg_td) {
+ // we may need to stop errors
+ if(env->context) env->context->error = true;
+ const Type t = known_type(env, targ->d.td);
+ if(env->context) env->context->error = false;
+ if(t)
+ td_fullname(env, &info->fmt->ls->text, t);
+ else {
+ const Exp exp = td2exp(gwion->mp, targ->d.td);
+ if(traverse_exp(env, exp) > 0) {
+ if(is_class(gwion, exp->type)) {
+ td_fullname(env, &info->fmt->ls->text, exp->type);
+ free_exp(gwion->mp, exp);
+ } else gwfmt_exp(info->fmt, exp);
+ } else GWION_ERR_B(targ->d.td->tag.loc, "invalid template argument");
+ }
+ } else {
+ Exp exp = targ->d.exp;
+ if(check_exp(env, targ->d.exp)) {
+ if(!is_class(gwion, exp->type))
+ gwfmt_exp(info->fmt, exp);
+ else
+ td_fullname(env, &info->fmt->ls->text, targ->d.exp->type);
+ }
+ }
}
return GW_OK;
}
ANEW ANN m_str type2str(const Gwion gwion, const Type t,
const loc_t pos NUSED) {
- GwText text;
+ GwText text;
text_init(&text, gwion->mp);
td_fullname(gwion->env, &text, t);
return text.str;
ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) {
CHECK_BB(ck_ok(gwi, ck_edef));
DECL_OB(const Symbol, xid, = gwi_str2sym(gwi, name));
- const EnumValue ev = { .xid = xid, .gwint = { .num = i }, .set = true};
+ const EnumValue ev = { .tag = MK_TAG(xid, gwi->loc), .gwint = { .num = i }, .set = true};
mp_vector_add(gwi->gwion->mp, &gwi->ck->tmpl, EnumValue, ev);
return GW_OK;
}
DECL_OB(Type_Decl *, td, = gwi_str2td(gwi, t));
struct Var_Decl_ var;
if(gwi_str2var(gwi, &var, n) > 0) {
- Arg arg = { .td = td, .var_decl = var };
+ Arg arg = { .var = MK_VAR(td, var) };
mp_vector_add(gwi->gwion->mp, &gwi->ck->mpv, Arg, arg);
return GW_OK;
}
m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) {
CHECK_BB(ck_ok(gwi, ck_item));
const Env env = gwi->gwion->env;
- gwi->ck->exp->d.exp_decl.td->flag = flag;
+ gwi->ck->exp->d.exp_decl.var.td->flag = flag;
if (gwi->gwion->data->cdoc) {
gwfmt_indent(gwi->gwfmt);
gwfmt_exp(gwi->gwfmt, gwi->ck->exp);
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.vd.value;
+ const Value value = gwi->ck->exp->d.exp_decl.var.vd.value;
value->d = addr;
set_vflag(value, vflag_builtin);
if (!env->class_def) SET_FLAG(value, global);
add_op(env->gwion, &opi);
}
+static OP_CHECK(opck_prim_cast) {
+ Exp_Cast *cast = data;
+ return known_type(env, cast->td);
+}
+
ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) {
m_uint sz = SZ_INT;
while(sz < size) sz += SZ_INT;
scan_prim_op2(env, t);
if(size < SZ_INT) {
prim_op(env, t, ":=>", opck_rassign, opem_bitset);
- prim_op(env, t, "$", NULL, opem_bitcast);
+// prim_op(env, t, "$", NULL, opem_bitcast);
+ prim_op(env, t, "$", opck_prim_cast, opem_bitcast);
prim_implicit(env, t);
} else if(size == SZ_INT) {
prim_op(env, t, ":=>", opck_rassign, (opem)dummy_func);
CHECK_BB(ck_ini(gwi, ck_udef));
gwi->ck->name = name;
CHECK_BB(check_typename_def(gwi, gwi->ck));
- gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Union_Member, 0);
+ gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Variable, 0);
return GW_OK;
}
CHECK_BB(ck_ok(gwi, ck_udef));
DECL_OB(Type_Decl *, td, = str2td(gwi->gwion, type, gwi->loc));
DECL_OB(const Symbol, xid, = str2sym(gwi->gwion, name, gwi->loc));
- Union_Member um = { .td = td, .vd = { .xid = xid, .pos = gwi->loc } };
- mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Union_Member, um);
-// const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc);
+ Variable um = { .td = td, .vd = { .tag = MK_TAG(xid, gwi->loc) } };
+ mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Variable, um);
+// const Variable_List l = new_variable_list(gwi->gwion->mp, td, xid, gwi->loc);
// l->next = gwi->ck->list;
// gwi->ck->list = l;
return GW_OK;
const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->mpv, gwi->loc);
gwi->ck->list = NULL;
udef->flag = flag;
- udef->xid = gwi->ck->sym;
+ udef->tag.sym = gwi->ck->sym;
if (gwi->ck->tmpl) {
udef->tmpl = gwi_tmpl(gwi);
gwi->ck->tmpl = NULL;
}
ANN void ck_clean_udef(MemPool mp, ImportCK *ck) {
- if (ck->mpv) free_mp_vector(mp, Union_Member, ck->mpv);
+ if (ck->mpv) free_mp_vector(mp, Variable, ck->mpv);
if (ck->tmpl) free_id_list(mp, ck->tmpl);
}
ERR_N(exp_self(bin)->pos, _("array depths do not match."));
}
if (bin->rhs->exp_type == ae_exp_decl) {
- Type_Decl *td = bin->rhs->d.exp_decl.td;
+ Type_Decl *td = bin->rhs->d.exp_decl.var.td;
if (td->array && td->array->exp)
ERR_N(exp_self(bin)->pos,
_("do not provide array for 'xxx => declaration'."));
- SET_FLAG(bin->rhs->d.exp_decl.vd.value, late);
+ SET_FLAG(bin->rhs->d.exp_decl.var.vd.value, late);
}
bin->rhs->ref = bin->lhs;
// bin->rhs->data = bin->lhs;
Type parent = t;
while(parent) {
if (tflag(parent, tflag_cdef) && parent->info->cdef->base.ext && parent->info->cdef->base.ext->array) {
- ERR_N(cast->td->pos, "can only cast to simple array types");
+ ERR_N(cast->td->tag.loc, "can only cast to simple array types");
}
parent = parent->info->parent;
}
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.ext = type2td(env->gwion, t_array, (loc_t) {});
- cdef->base.xid = sym;
+ cdef->base.ext = type2td(env->gwion, t_array, (loc_t){});
+ cdef->base.tag.sym = sym;
cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, TmplArg, 1);
- TmplArg arg = {.type = tmplarg_td, .d = {.td = type2td(env->gwion, base, (loc_t) {})} };
+ TmplArg arg = {.type = tmplarg_td, .d = {.td = type2td(env->gwion, base, (loc_t){})} };
mp_vector_set(cdef->base.tmpl->call, TmplArg, 0, arg);
const Context ctx = env->context;
env->context = base->info->value->from->ctx;
t->array_depth = base->array_depth + 1;
t->info->base_type = array_base(base);
set_tflag(t, tflag_cdef | tflag_tmpl);
-
- builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t));
+
+ builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t));
array_func(env, t, "insert", get_insert(t));
array_func(env, t, "size", vm_vector_size);
array_func(env, t, "depth", vm_vector_depth);
ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args) {
if (!last_is_zero(td->array->exp)) {
if (!args)
- ERR_B(td->pos, "declaration of abstract type arrays needs lambda");
+ ERR_B(td->tag.loc, "declaration of abstract type arrays needs lambda");
} else {
if(args)
gwerr_warn("array is empty", "no need to provide a lambda",
}
ANN Type upvalue_type(const Env env, Capture *cap) {
- const Value v = nspc_lookup_value1(env->curr, cap->xid);
- if(!v) ERR_O(cap->pos, _("non existing value")); // did_you_mean
+ const Value v = nspc_lookup_value1(env->curr, cap->tag.sym);
+ if(!v) ERR_O(cap->tag.loc, _("non existing value")); // did_you_mean
if(cap->is_ref && not_upvalue(env, v))
- ERR_O(cap->pos, _("can't take ref of a scoped value"));
+ ERR_O(cap->tag.loc, _("can't take ref of a scoped value"));
cap->orig = v;
const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains);
- return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->pos);
+ return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->tag.loc);
}
ANN void free_captures(const VM_Shred shred, m_bit *const caps) {
ANN static m_bool emit_fptr_assign(const Emitter emit, const Type lhs, const Type rhs) {
const Instr instr = emit_add_instr(emit, fptr_assign);
- if(rhs->info->cdef && rhs->info->cdef->base.tmpl)
+ if(rhs->info->cdef && get_tmpl(rhs))
instr->m_val = SZ_INT * 2;
if(!lhs->info->func) {
const Func_Def fdef = lhs->info->func->def;
const Capture_List captures = fdef->captures;
if(captures) {
uint32_t offset = 0;
- Exp e = new_prim_id(emit->gwion->mp, fdef->base->xid, fdef->base->pos); // free me
+ Exp e = new_prim_id(emit->gwion->mp, fdef->base->tag.sym, fdef->base->tag.loc); // free me
for(uint32_t i = 0; i < captures->len; i++) {
Capture *const cap = mp_vector_at(captures, Capture, i);
- e->d.prim.d.var = cap->xid;
+ e->d.prim.d.var = cap->tag.sym;
e->d.prim.value = cap->orig;
e->type = cap->orig->type;
exp_setvar(e, cap->is_ref);
if(spec->td) continue;
TmplArg arg = *mp_vector_at(tl, TmplArg, i);
const Type t = known_type(env, arg.d.td);
- nspc_add_type(env->curr, spec->xid, t);
+ nspc_add_type(env->curr, spec->tag.sym, t);
}
}
if (arg0->type && arg1->type)
CHECK_BB(isa(arg0->type, arg1->type));
else if(!tmpl_base(base[0]->tmpl) && !tmpl_base(base[1]->tmpl)){
- Type_Decl *td[2] = {arg0->td, arg1->td};
+ Type_Decl *td[2] = {arg0->var.td, arg1->var.td};
CHECK_BB(td_match(env, td));
}
}
ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
const Value v = info->lhs->value_ref;
const Nspc nspc = v->from->owner;
- const m_str c = s_name(info->lhs->def->base->xid),
+ const m_str c = s_name(info->lhs->def->base->tag.sym),
stmpl = !info->rhs->def->base->tmpl ? NULL : "template";
for (m_uint i = 0; i <= v->from->offset; ++i) {
const Symbol sym = (!info->lhs->def->base->tmpl || i != 0)
? func_symbol(env, nspc->name, c, stmpl, i)
- : info->lhs->def->base->xid;
+ : info->lhs->def->base->tag.sym;
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));
}
} else {
DECL_OO(const Type, t,
- = nspc_lookup_type1(nspc, info->lhs->def->base->xid));
+ = nspc_lookup_type1(nspc, info->lhs->def->base->tag.sym));
info->lhs = actual_type(env->gwion, t)->info->func;
}
Type type = NULL;
// here move to arguments
for(uint32_t i = 0; i < l->def->captures->len; i++) {
Capture *cap = mp_vector_at(l->def->captures, Capture, i);
- const Value v = nspc_lookup_value1(env->curr, cap->xid);
- if(!v) ERR_B(cap->pos, _("unknown value in capture"));
+ const Value v = nspc_lookup_value1(env->curr, cap->tag.sym);
+ if(!v) ERR_B(cap->tag.loc, _("unknown value in capture"));
DECL_OB(const Type, t, = upvalue_type(env, cap));
- cap->temp = new_value(env, t, s_name(cap->xid), cap->pos);
+ cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc);
cap->orig = v;
}
}
.flag = tflag_scan0};
CHECK_BB(envset_pushv(&es, owner->info->value));
while(owner) {
- if(owner->info->cdef->base.tmpl)
- template_push_types(env, owner->info->cdef->base.tmpl);
+ const Tmpl *tmpl = get_tmpl(owner);
+ if(tmpl)
+ template_push_types(env, tmpl);
owner = owner->info->value->from->owner_class;
}
if(bases) {
for(uint32_t i = 0; i < bases->len; i++) {
Arg *base = mp_vector_at(bases, Arg, i);
Arg *arg = mp_vector_at(args, Arg, i);
- DECL_OB(const Type, arg_type, = known_type(env, base->td));
- arg->td = type2td(env->gwion, arg_type, exp_self(l)->pos);
+ DECL_OB(const Type, arg_type, = known_type(env, base->var.td));
+ arg->var.td = type2td(env->gwion, arg_type, exp_self(l)->pos);
}
}
DECL_OB(const Type, ret_type, = known_type(env, fdef->base->td));
}
/*Type*/ owner = fdef->base->func->value_ref->from->owner_class->info->value->from->owner_class;
while(owner) {
- if(owner->info->cdef->base.tmpl)
+ if(get_tmpl(owner))
nspc_pop_type(env->gwion->mp, env->curr);
owner = owner->info->value->from->owner_class;
}
if(args) {
for(uint32_t i = 0; i < bases->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- free_value(arg->var_decl.value, env->gwion);
- arg->var_decl.value = NULL;
+ free_value(arg->var.vd.value, env->gwion);
+ arg->var.vd.value = NULL;
}
}
}
set_fbflag(fdef->base, fbflag_lambda);
const Type actual = fdef->base->func->value_ref->type;
set_fbflag(fdef->base, fbflag_lambda);
- Var_Decl vd = bin->rhs->d.exp_decl.vd;
+ Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
exp_setvar(bin->rhs, true);
return vd.value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = actual;
}
const Exp_Binary *bin = (Exp_Binary *)data;
// we'll only deal with auto fptr declaration
if (bin->rhs->exp_type != ae_exp_decl &&
- bin->rhs->d.exp_decl.td->xid != insert_symbol("auto"))
+ bin->rhs->d.exp_decl.var.td->tag.sym != insert_symbol("auto"))
ERR_N(bin->lhs->pos, "invalid {G+}function{0} {+}:=>{0} {+G}function{0} assignment");
if (bin->lhs->exp_type == ae_exp_td)
ERR_N(bin->lhs->pos, "can't use {/}type decl expressions{0} in auto function pointer declarations");
num_digit(bin->rhs->pos.first.column)];
sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos.first.line,
bin->rhs->pos.first.column);
- fptr_def->base->xid = insert_symbol(name);
+ fptr_def->base->tag.sym = insert_symbol(name);
const m_bool ret = traverse_fptr_def(env, fptr_def);
const Type t = fptr_def->cdef->base.type;
free_fptr_def(env->gwion->mp, fptr_def);
- Var_Decl vd = bin->rhs->d.exp_decl.vd;
+ Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
vd.value->type = bin->rhs->type =
bin->rhs->d.exp_decl.type = t;
return ret > 0 ? t : env->gwion->type[et_error];
static OP_EMIT(opem_fptr_impl) {
struct Implicit *impl = (struct Implicit *)data;
- if(!impl->e->type->info->func->def->base->tmpl && impl->t->info->cdef->base.tmpl) {
+ if(!impl->e->type->info->func->def->base->tmpl && get_tmpl(impl->t)) {
const Instr instr = (Instr)vector_back(&emit->code->instr);
instr->opcode = eRegPushImm;
instr->m_val = (m_uint)impl->e->type->info->func;
safe_tflag(func->value_ref->from->owner_class, tflag_tmpl);
if (owner_tmpl)
template_push_types(
- env, func->value_ref->from->owner_class->info->cdef->base.tmpl);
+ env, get_tmpl(func->value_ref->from->owner_class));
const bool func_tmpl = fflag(func, fflag_tmpl);
if (func_tmpl) template_push_types(env, func->def->base->tmpl);
Arg_List args = func->def->base->args;
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- if (!arg->type) arg->type = known_type(env, arg->td);
+ if (!arg->type) arg->type = known_type(env, arg->var.td);
}
if (!func->def->base->ret_type)
func->def->base->ret_type = known_type(env, func->def->base->td);
.d = {.prim = {.d = {.var = lhs_sym}, .prim_type = ae_prim_id}},
.exp_type = ae_exp_primary,
.type = arg0->type,
- .pos = arg0->td->pos};
+ .pos = arg0->var.td->tag.loc};
struct Exp_ _rhs = {
.d = {.prim = {.d = {.var = rhs_sym}, .prim_type = ae_prim_id}},
.exp_type = ae_exp_primary,
.type = arg1->type,
- .pos = arg1->td->pos};
+ .pos = arg1->var.td->tag.loc};
struct Exp_ self = {.pos = impl->e->pos};
self.d.exp_binary.lhs = &_lhs;
self.d.exp_binary.rhs = &_rhs;
}
}
const Arg_List args = cpy_arg_list(env->gwion->mp, func->def->base->args);
- Arg *larg0 = (Arg*)(args->ptr);
- Arg *larg1 = (Arg*)(args->ptr + sizeof(Arg));
- larg0->var_decl.xid = lhs_sym;
- larg1->var_decl.xid = rhs_sym;
+ Arg *larg0 = mp_vector_at(args, Arg, 0);
+ Arg *larg1 = mp_vector_at(args, Arg, 1);
+ larg0->var.vd.tag.sym = lhs_sym;
+ larg1->var.vd.tag.sym = rhs_sym;
Func_Base *base =
new_func_base(env->gwion->mp, type2td(env->gwion, t, impl->e->pos),
impl->e->d.prim.d.var, args, ae_flag_none, impl->e->pos);
free_mp_vector(env->gwion->mp, struct ScopeEffect, eff);
}
const Exp lhs =
- new_prim_id(env->gwion->mp, larg0->var_decl.xid, impl->e->pos);
+ new_prim_id(env->gwion->mp, larg0->var.vd.tag.sym, impl->e->pos);
const Exp rhs =
- new_prim_id(env->gwion->mp, larg1->var_decl.xid, impl->e->pos);
+ new_prim_id(env->gwion->mp, larg1->var.vd.tag.sym, impl->e->pos);
const Exp bin = new_exp_binary(env->gwion->mp, lhs, impl->e->d.prim.d.var,
rhs, impl->e->pos);
Stmt_List code = new_mp_vector(env->gwion->mp, struct Stmt_, 1);
.pos = impl->e->pos
}));
const Func_Def def = new_func_def(env->gwion->mp, base, code);
- def->base->xid = impl->e->d.prim.d.var;
+ def->base->tag.sym = impl->e->d.prim.d.var;
// use envset
// or better, some function with envset and traverse
const m_uint scope = env_push(env, NULL, opi.nspc);
static OP_CHECK(opck_closure_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
struct tmpl_info info = {
- .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+ .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list};
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
const Func_Base *base = closure_def(ts->t)->base;
const Arg_List args = base->args ? cpy_arg_list(env->gwion->mp, base->args) : NULL;
- Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->pos);
+ Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->tag.loc);
fbase->tmpl = cpy_tmpl(env->gwion->mp, base->tmpl);
if(!is_base(env, ts->td->types))
fbase->tmpl->call = cpy_type_list(env->gwion->mp, ts->td->types);
const Fptr_Def fdef = new_fptr_def(env->gwion->mp, cpy_func_base(env->gwion->mp, fbase));
- fdef->base->xid = info.name;
+ fdef->base->tag.sym = info.name;
struct EnvSet es = {.env = env,
.data = env,
.func = (_exp_func)traverse_cdef,
#include "array.h"
#include "looper.h"
#include "dict.h"
+#include "template.h"
#define HMAP_MIN_CAP 32
#define HMAP_MAX_LOAD 0.75
static OP_CHECK(opck_dict_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
- if(ts->t->info->cdef->base.tmpl->call) return ts->t;
+ const Tmpl *tmpl = get_tmpl(ts->t);
+ if(tmpl->call) return ts->t;
struct tmpl_info info = {
- .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+ .base = ts->t, .td = ts->td, .list = tmpl->list};
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
if(!ts->td->types || ts->td->types->len != 2) return env->gwion->type[et_error];
DECL_ON(const Type, key, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td));
DECL_ON(const Type, val, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 1)->d.td));
if(tflag(key, tflag_ref) || tflag(val, tflag_ref))
- ERR_N(ts->td->pos, "can't use Ref:[] in dicts");
+ ERR_N(ts->td->tag.loc, "can't use Ref:[] in dicts");
const Class_Def cdef = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef);
- cdef->base.ext = type2td(env->gwion, env->gwion->type[et_dict], (loc_t) {});
- cdef->base.xid = info.name;
+ cdef->base.ext = type2td(env->gwion, env->gwion->type[et_dict], (loc_t){});
+ cdef->base.tag.sym = info.name;
cdef->base.tmpl->call = cpy_type_list(env->gwion->mp, info.td->types);
const bool is_global = tmpl_global(env, ts->td->types);
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
GWI_BB(gwi_oper_end(gwi, ".", NULL))
+ // allow const generics in functions
+ GWI_BB(gwi_oper_ini(gwi, "function", (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+ GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
+ GWI_BB(gwi_oper_end(gwi, ".", NULL))
+
GWI_BB(gwimport_class(gwi))
gwidoc(gwi, "allow static access.");
ANN static Func_Def traverse_tmpl(const Emitter emit, Func_Def fdef, Func_Def fbase,
const Nspc nspc) {
const Env env = emit->env;
- const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
+ const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->tag.sym),
"template", fbase->vt_index);
DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym)
- ?: nspc_lookup_value0(nspc, fdef->base->xid));
+ ?: nspc_lookup_value0(nspc, fdef->base->tag.sym));
const f_xfun xfun = v->d.func_ref->def->d.dl_func_ptr;
if (vflag(v, vflag_builtin))
v->d.func_ref->def->d.dl_func_ptr = NULL; // why
ERR_O(exp_self(prim)->pos,
_("keyword 'this' cannot be used inside static functions..."))
if (!exp_getuse(exp_self(prim)) &&
- !strcmp(s_name(env->func->def->base->xid), "@gack"))
+ !strcmp(s_name(env->func->def->base->tag.sym), "@gack"))
return get_gack(env->class_def->info->parent); // get_gack ?
}
return env->class_def;
-
#include "gwion_util.h"
#include "gwion_ast.h"
#include "gwion_env.h"
if (opck_rassign(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
if (bin->rhs->exp_type == ae_exp_decl) {
- Var_Decl vd = bin->rhs->d.exp_decl.vd;
+ Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
SET_FLAG(vd.value, late);
}
exp_setvar(bin->rhs, 1);
Exp rhs = bin->rhs;
if (rhs->exp_type != ae_exp_decl)
return NULL;
- if (rhs->d.exp_decl.td->array)
+ if (rhs->d.exp_decl.var.td->array)
return NULL;
Exp lhs = bin->lhs;
Exp e = exp_self(bin);
Exp_Decl *const decl = &e->d.exp_decl;
e->exp_type = ae_exp_decl;
- decl->td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.td);
- decl->vd = rhs->d.exp_decl.vd;
+ decl->var.td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.var.td);
+ decl->var.vd = rhs->d.exp_decl.var.vd;
decl->type = rhs->type;
decl->args = lhs;
free_exp(env->gwion->mp, rhs);
static OP_CHECK(opck_struct_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
- if(ts->t->info->cdef->base.tmpl->call) return ts->t;
+ const Tmpl *tmpl = get_tmpl(ts->t);
+ if(tmpl->call) return ts->t;
return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error];
}
struct dottmpl_ *dt = mp_malloc(emit->gwion->mp, dottmpl);
dt->nspc = emit->env->curr;
dt->type = emit->env->class_def;
- dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
+ dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc);
instr->m_val2 = (m_uint)dt;
}
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,
- NULL, c->pos);
+ NULL, c->base.tag.loc);
if(c->body) cdef->body = cpy_ast(env->gwion->mp, c->body);
cdef->cflag = c->cflag;
cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types);
ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
const Union_Def u = info->base->info->udef;
const Union_Def udef = new_union_def(
- env->gwion->mp, cpy_union_list(env->gwion->mp, u->l), u->pos);
- udef->xid = info->name;
+ env->gwion->mp, cpy_variable_list(env->gwion->mp, u->l), u->tag.loc);
+ udef->tag.sym = info->name;
udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types);
// resolve the template here
if (GET_FLAG(info->base, global)) SET_FLAG(udef, global);
ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
struct tmpl_info info = {
- .base = t, .td = td, .list = t->info->cdef->base.tmpl->list};
+ .base = t, .td = td, .list = get_tmpl(t)->list};
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
struct EnvSet es = {.env = env,
}
CHECK_BN(ensure_traverse(env, t));
if (type_ref(t))
- ERR_N(unary->ctor.td->pos, _("can't use 'new' on ref type '%s'\n"), t->name);
+ ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on ref type '%s'\n"), t->name);
if (tflag(t, tflag_infer))
- ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"),
+ ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on '%s'\n"),
t->name);
if (array) {
CHECK_BN(check_subscripts(env, array, 1));
}
if (GET_FLAG(t, abstract) &&
(!array || (array->exp && exp_is_zero(array->exp))))
- ERR_N(unary->ctor.td->pos, _("can't use 'new' on abstract type '%s'\n"),
+ ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on abstract type '%s'\n"),
t->name);
if (isa(t, env->gwion->type[et_object]) < 0)
ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n"));
static OP_CHECK(opck_ref_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
struct tmpl_info info = {
- .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+ .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list};
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
const TmplArg arg = *mp_vector_at(ts->td->types, TmplArg, 0);
ANN static ssize_t template_size(const Env env, struct tmpl_info *info) {
DECL_OB(const m_str, str,
- = tl2str(env->gwion, info->td->types, info->td->pos));
+ = tl2str(env->gwion, info->td->types, info->td->tag.loc));
const size_t tmpl_sz = tmpl_set(info, str);
const m_str base = !is_func(env->gwion, info->base)
? mstrdup(env->gwion->mp, info->base->name)
- : type2str(env->gwion, info->base, info->td->pos);
+ : type2str(env->gwion, info->base, info->td->tag.loc);
return tmpl_sz + tmpl_set(info, base) + 4;
}
ANN Type tmpl_exists(const Env env, struct tmpl_info *const info) {
if (template_match(info->list, info->td->types) < 0) // invalid template
- ERR_N(info->td->pos, _("invalid template types number"));
+ ERR_N(info->td->tag.loc, _("invalid template types number"));
if (!info->name)
info->name = template_id(env, info);
return _tmpl_exists(env, info->name);
for(uint32_t i = 0; i < unary->captures->len; i++) {
Capture *const cap = mp_vector_at(unary->captures, Capture, i);
DECL_OO(const Type, t, = upvalue_type(env, cap));
- cap->temp = new_value(env, t, s_name(cap->xid), cap->pos);
+ cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc);
cap->temp->from->offset = offset;
offset += cap->temp->type->size;
}
if(unary->captures) {
for(uint32_t i = 0; i < unary->captures->len; i++) {
Capture *const cap = mp_vector_at(unary->captures, Capture, i);
- valid_value(env, cap->xid, cap->temp);
+ valid_value(env, cap->tag.sym, cap->temp);
}
}
const Func f = env->func;
struct Value_ value = { .type = env->gwion->type[et_function]};
if(env->class_def)
set_vflag(&value, vflag_member);
- struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &upvalues, .fbflag = fbflag_lambda, .pos = exp_self(unary)->pos};
+ struct Func_Base_ fbase = { .tag=MK_TAG(insert_symbol("in spork"), exp_self(unary)->pos), .values = &upvalues, .fbflag = fbflag_lambda};
struct Func_Def_ fdef = { .base = &fbase};
struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
env->func = &func;
ANN static inline m_bool check_exp_decl_parent(const Env env,
const Var_Decl *var) {
- const Value value = find_value(env->class_def->info->parent, var->xid);
+ const Value value = find_value(env->class_def->info->parent, var->tag.sym);
if (value) {
- env_err(env, var->pos, _("Value defined in parent class"));
+ env_err(env, var->tag.loc, _("Value defined in parent class"));
defined_here(value);
return GW_ERROR;
}
ANN static m_bool check_var(const Env env, const Var_Decl *var) {
if (env->class_def && !env->scope->depth && env->class_def->info->parent)
CHECK_BB(check_exp_decl_parent(env, var));
- var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos);
+ var_effects(env, var->value->type, insert_symbol("@ctor"), var->tag.loc);
return GW_OK;
}
}
ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
- const Var_Decl *vd = &decl->vd;
+ const Var_Decl *vd = &decl->var.vd;
CHECK_BB(check_var(env, vd));
- CHECK_BB(check_var_td(env, vd, decl->td));
- if (decl->td->array && decl->td->array->exp) {
- CHECK_BB(check_subscripts(env, decl->td->array, true));
+ CHECK_BB(check_var_td(env, vd, decl->var.td));
+ if (decl->var.td->array && decl->var.td->array->exp) {
+ CHECK_BB(check_subscripts(env, decl->var.td->array, true));
if (GET_FLAG(array_base(decl->type), abstract))
- CHECK_BB(check_array_instance(env, decl->td, decl->args));
+ CHECK_BB(check_array_instance(env, decl->var.td, decl->args));
}
- valid_value(env, vd->xid, vd->value);
+ valid_value(env, vd->tag.sym, vd->value);
// set_vflag(var->value, vflag_used));
return GW_OK;
}
}
ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) {
- if (decl->td->array && decl->td->array->exp)
- CHECK_OO(check_exp(env, decl->td->array->exp));
+ if (decl->var.td->array && decl->var.td->array->exp)
+ CHECK_OO(check_exp(env, decl->var.td->array->exp));
if (decl->args) {
- const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->td), decl->args, decl->td->pos);
+ const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->var.td), decl->args, decl->var.td->tag.loc);
CHECK_OO(check_exp(env, e));
decl->args = e;
e->ref = exp_self(decl);
}
- if (decl->td->xid == insert_symbol("auto")) { // should be better
+ if (decl->var.td->tag.sym == insert_symbol("auto")) { // should be better
CHECK_BO(scan1_exp(env, exp_self(decl)));
CHECK_BO(scan2_exp(env, exp_self(decl)));
}
- if (!decl->type) ERR_O(decl->td->pos, _("can't find type"));
+ if (!decl->type) ERR_O(decl->var.td->tag.loc, _("can't find type"));
{
CHECK_BO(ensure_check(env, decl->type));
- if(inferable(env, decl->type, decl->td->pos) < 0) {
+ if(inferable(env, decl->type, decl->var.td->tag.loc) < 0) {
if(!tflag(decl->type, tflag_check) && decl->type->ref > 1 && env->class_def && !env->scope->depth)
type_remref(decl->type, env->gwion);
return NULL;
}
}
- const m_bool global = GET_FLAG(decl->td, global);
+ const m_bool global = GET_FLAG(decl->var.td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const m_bool ret = check_decl(env, decl);
if (global) {
env_pop(env, scope);
- set_vflag(decl->vd.value, vflag_direct);
+ set_vflag(decl->var.vd.value, vflag_direct);
}
env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0);
- return ret > 0 ? decl->vd.value->type : NULL;
+ return ret > 0 ? decl->var.vd.value->type : NULL;
}
ANN static m_bool check_collection(const Env env, Type type, const Exp e,
ANN static inline Value get_value(const Env env, const Symbol sym) {
const Value value = nspc_lookup_value1(env->curr, sym);
if(value) {
+if(value->from->owner_class && is_func(env->gwion, value->from->owner_class)) {
+/*
+
+set_tflag(value->from->owner_class, tflag_check);
+set_tflag(value->from->owner_class, tflag_scan0);
+set_tflag(value->from->owner_class, tflag_scan1);
+set_tflag(value->from->owner_class, tflag_scan2);
+set_tflag(value->from->owner_class, tflag_check);
+*/
+return value;
+}
+
if (!value->from->owner_class || isa(env->class_def, value->from->owner_class) > 0)
return value;
if(env->class_def) {
const Value v = exp->d.prim.value;
if(is_class(env->gwion, v->type) && env->class_def == v->type->info->base_type) // write it better
return v->type->info->base_type;
+// if(v->from->owner_class && is_func(env->gwion, v->from->owner_class))
+// return v->type;
const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
const Exp base =
new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data));
// without the mangling
ANN static inline Type type_list_base_func(const Type type) {
const Nspc owner = type->info->value->from->owner;
- const Symbol xid = type->info->func->def->base->xid;
+ const Symbol xid = type->info->func->def->base->tag.sym;
return nspc_lookup_type0(owner, xid);
}
return type2td(env->gwion, t, pos);
}
-ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) {
+ANN static Type tmplarg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) {
if (xid == tgt) return t;
+// Tmpl *tmpl = get_tmpl(t);//tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl
Tmpl *tmpl = tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl
: tflag(t, tflag_udef) ? t->info->udef->tmpl
: NULL;
const uint32_t len = mp_vector_len(tmpl->list);
for(uint32_t i = 0; i < len; i++) {
Specialized *spec = mp_vector_at(tmpl->list, Specialized, i);
- const Type base = nspc_lookup_type1(t->nspc, spec->xid);
- const Type t = tmpl_arg_match(env, xid, spec->xid, base);
+ const Type base = nspc_lookup_type1(t->nspc, spec->tag.sym);
+ const Type t = tmplarg_match(env, xid, spec->tag.sym, base);
if(t) return t;
}
return NULL;
if (arg->type == env->gwion->type[et_auto]) {
const Type owner = func->value_ref->from->owner_class;
if (owner) CHECK_BO(template_push(env, owner));
- arg->type = known_type(env, arg->td);
+ arg->type = known_type(env, arg->var.td);
if (owner) nspc_pop_type(env->gwion->mp, env->curr);
CHECK_OO(arg->type);
}
}
ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) {
- const Value v = nspc_lookup_value1(env->curr, up->def->base->xid);
+ const Value v = nspc_lookup_value1(env->curr, up->def->base->tag.sym);
if (v && is_func(env->gwion, v->type) && !v->from->owner_class) // is_callable
return call2ufcs(env, call, v);
return NULL;
ANN static m_bool check_func_args(const Env env, Arg_List args) {
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- const Var_Decl *decl = &arg->var_decl;
+ const Var_Decl *decl = &arg->var.vd;
const Value v = decl->value;
- if(decl->xid) CHECK_BB(already_defined(env, decl->xid, decl->pos));
- valid_value(env, decl->xid, v);
+ if(decl->tag.sym) CHECK_BB(already_defined(env, decl->tag.sym, decl->tag.loc));
+ valid_value(env, decl->tag.sym, v);
}
return GW_OK;
}
const uint32_t len = sl->len - spread;
Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, len);
m_uint args_number = 0;
-
+// infer template types from args
+// should not work with const generic
if(exp->other) {
for(uint32_t i = 0; i < len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) {
+ if (tmplarg_match(env, spec->tag.sym, fdef->base->td->tag.sym, fdef->base->ret_type)) {
CHECK_OO(check_exp(env, exp->other));
if(!is_func(env->gwion, exp->other->type)) {
TmplArg targ = {
.type = tmplarg_td,
- .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->pos) }
+ .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->tag.loc) }
};
mp_vector_set(tl, TmplArg, 0, targ);
} else {
Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
TmplArg targ = {
.type = tmplarg_td,
- .d = { .td = cpy_type_decl(env->gwion->mp, arg->td) }
+ .d = { .td = cpy_type_decl(env->gwion->mp, arg->var.td) }
};
mp_vector_set(tl, TmplArg, 0, targ);
break;
uint32_t count = 0;
while (count < args_len && template_arg) {
Arg *arg = mp_vector_at(args, Arg, count);
- if (tmpl_arg_match(env, spec->xid, arg->td->xid, template_arg->type)) {
+ if (tmplarg_match(env, spec->tag.sym, arg->var.td->tag.sym, template_arg->type)) {
TmplArg targ = {
.type = tmplarg_td,
- .d = { .td = mk_td(env, arg->td, template_arg->type, fdef->base->pos) }
+ .d = { .td = mk_td(env, arg->var.td, template_arg->type, fdef->base->tag.loc) }
};
mp_vector_set(tl, TmplArg, args_number, targ);
++args_number;
if(args) free_exp(env->gwion->mp, args);
return NULL;
}
- Arg arg = {
- .td = type2td(env->gwion, t, cap->pos),
- .var_decl = { .xid = cap->xid }
- };
+ Arg arg = { .var = MK_VAR(
+ type2td(env->gwion, t, cap->tag.loc),
+ (Var_Decl){ .tag = MK_TAG(cap->tag.sym, cap->tag.loc) }
+ )};
mp_vector_add(env->gwion->mp, &fdef->base->args, Arg, arg);
- const Exp exp = new_prim_id(env->gwion->mp, cap->xid, cap->pos);
+ const Exp exp = new_prim_id(env->gwion->mp, cap->tag.sym, cap->tag.loc);
if(args) tmp = tmp->next = exp;
else args = tmp = exp;
}
CHECK_OO(check_exp(env, bin->rhs));
if (is_auto) {
assert(bin->rhs->type == bin->lhs->type);
- set_vflag(bin->rhs->d.exp_decl.vd.value, vflag_assigned);
+ set_vflag(bin->rhs->d.exp_decl.var.vd.value, vflag_assigned);
}
struct Op_Import opi = {.op = bin->op,
.lhs = bin->lhs->type,
exp_setuse(bin->rhs, 1);
const Type ret = op_check(env, &opi);
if (!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
- bin->rhs->d.exp_decl.vd.value->type = env->gwion->type[et_auto];
+ bin->rhs->d.exp_decl.var.vd.value->type = env->gwion->type[et_auto];
return ret;
}
free_mstr(env->gwion->mp, str);
if (tflag(t, tflag_typedef)) {
gwerr_secondary("from definition:", env->name,
- t->info->func->def->base->pos);
+ t->info->func->def->base->tag.loc);
}
return GW_ERROR;
}
ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
if (tdef->when) {
set_tflag(tdef->type, tflag_contract);
- struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos };
+ struct Var_Decl_ decl = { .tag = MK_TAG(insert_symbol("self"), tdef->when->pos) };
Type_Decl *td = cpy_type_decl(env->gwion->mp, tdef->ext);
Arg_List args = new_mp_vector(env->gwion->mp, Arg, 1);
- mp_vector_set(args, Arg, 0, ((Arg) { .td = td, .var_decl = decl }));
+ mp_vector_set(args, Arg, 0, ((Arg) { .var = MK_VAR(td, decl)}));
Func_Base *fb = new_func_base(
- env->gwion->mp, type2td(env->gwion, tdef->type, tdef->pos),
- insert_symbol("@implicit"), args, ae_flag_none, tdef->pos);
+ env->gwion->mp, type2td(env->gwion, tdef->type, tdef->tag.loc),
+ insert_symbol("@implicit"), args, ae_flag_none, tdef->tag.loc);
set_fbflag(fb, fbflag_op);
const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"),
tdef->when->pos);
"use `{/+}bool{0}`", env->name, when->pos, 0);
char from[strlen(tdef->type->name) + 39];
sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name);
- gwerr_secondary(from, env->name, tdef->pos);
+ gwerr_secondary(from, env->name, tdef->tag.loc);
env_set_error(env, true);
return GW_ERROR;
}
// we handle the return after, so that we don't get *cant' use implicit
// casting while defining it*
const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos);
- ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->pos);
+ ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->tag.loc);
struct Stmt_ ret = {
.stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ret_id }},
.pos = when->pos
ID_List list = edef->list;
for(uint32_t i = 0; i < list->len; i++) {
EnumValue ev= *mp_vector_at(list, EnumValue, i);
- decl_static(env, nspc_lookup_value0(env->curr, ev.xid));
+ decl_static(env, nspc_lookup_value0(env->curr, ev.tag.sym));
}
env_pop(env, scope);
return GW_OK;
}
ANN static void check_idx(const Env env, const Type base, struct EachIdx_ *const idx) {
- idx->v = new_value(env, base, s_name(idx->sym), idx->pos);
- valid_value(env, idx->sym, idx->v);
+ idx->v = new_value(env, base, s_name(idx->tag.sym), idx->tag.loc);
+ valid_value(env, idx->tag.sym, idx->v);
SET_FLAG(idx->v, const);
}
.lhs = exp->type,
.op = insert_symbol("@each_idx"),
.data = (m_uint)exp,
- .pos = idx->pos
+ .pos = idx->tag.loc
};
DECL_OB(const Type, t, = op_check(env, &opi));
check_idx(env, t, idx);
if (stmt->idx)
CHECK_BB(check_each_idx(env, stmt->exp, stmt->idx));
DECL_OB(const Type, ret, = check_each_val(env, stmt->exp));
- stmt->v = new_value(env, ret, s_name(stmt->sym), stmt->vpos);
- valid_value(env, stmt->sym, stmt->v);
+ stmt->v = new_value(env, ret, s_name(stmt->tag.sym), stmt->tag.loc);
+ valid_value(env, stmt->tag.sym, stmt->v);
return check_conts(env, stmt_self(stmt), stmt->body);
}
ret_type->name);
if (stmt->val) {
Arg *arg = mp_vector_at(env->func->def->base->args, Arg, 0);
- if (env->func->def->base->xid == insert_symbol("@implicit") &&
+ if (env->func->def->base->tag.sym == insert_symbol("@implicit") &&
ret_type == arg->type)
ERR_B(stmt_self(stmt)->pos,
_("can't use implicit casting while defining it"))
if(stmt->val) {
CHECK_OB(check_exp(env, stmt->val));
if(stmt->val->exp_type == ae_exp_lambda) {
- const loc_t loc = stmt->val->d.exp_lambda.def->base->pos;
+ const loc_t loc = stmt->val->d.exp_lambda.def->base->tag.loc;
env_warn(env, loc, _("Partial application not used"));
}
}
ANN static inline bool find_handler(const Handler_List handlers, const Symbol xid) {
for(uint32_t i = 0; i < handlers->len; i++) {
Handler *handler = mp_vector_at(handlers, Handler, i);
- if(xid == handler->xid) return true;
- if(!handler->xid) return true;
+ if(xid == handler->tag.sym) return true;
+ if(!handler->tag.sym) return true;
}
return false;
}
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(fdef->base->td->pos, _("can't override final function '%s'\n"),
+ ERR_B(fdef->base->td->tag.loc, _("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;
- const m_str f_name = s_name(fdef->base->xid);
- ERR_B(fdef->base->td->pos,
+ const m_str f_name = s_name(fdef->base->tag.sym);
+ ERR_B(fdef->base->td->tag.loc,
_("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
" ...(reason: '%s.%s' is declared as 'static')"),
c_name, f_name, p_name, c_name,
const Type parent = env->class_def->info->parent;
if (!env->curr->vtable.ptr) vector_init(&env->curr->vtable);
if (parent) {
- const Value v = find_value(parent, fdef->base->xid);
+ const Value v = find_value(parent, fdef->base->tag.sym);
if (v && is_func(env->gwion, v->type)) {
const m_bool match = parent_match_actual(env, fdef, v->d.func_ref);
if (match) return match;
ANN static inline Func get_overload(const Env env, const Func_Def fdef,
const m_uint i) {
const Symbol sym =
- func_symbol(env, env->curr->name, s_name(fdef->base->xid), NULL, i);
+ func_symbol(env, env->curr->name, s_name(fdef->base->tag.sym), NULL, i);
return nspc_lookup_func1(env->curr, sym);
}
fbflag(f2->def->base, fbflag_unary) &&
fbflag(f1->def->base, fbflag_postfix) ==
fbflag(f2->def->base, fbflag_postfix))
- ERR_B(f2->def->base->pos,
+ ERR_B(f2->def->base->tag.loc,
_("global function '%s' already defined"
" for those arguments"),
- s_name(fdef->base->xid))
+ s_name(fdef->base->tag.sym))
}
}
return GW_OK;
const Func func = fdef->base->func;
if (env->class_def && env->class_def->info->parent) {
const Value override =
- find_value(env->class_def->info->parent, fdef->base->xid);
+ find_value(env->class_def->info->parent, fdef->base->tag.sym);
if (override && override->from->owner_class &&
!is_func(env->gwion, override->type))
- ERR_B(fdef->base->pos,
+ ERR_B(fdef->base->tag.loc,
_("function name '%s' conflicts with previously defined value...\n"
" from super class '%s'..."),
- s_name(fdef->base->xid), override->from->owner_class->name)
+ s_name(fdef->base->tag.sym), override->from->owner_class->name)
*ov = override;
}
if (func->value_ref->from->offset &&
ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
if (v) {
- if (fdef->base->xid == insert_symbol("@dtor"))
- ERR_B(fdef->base->pos, _("can't use effects in destructors"));
+ if (fdef->base->tag.sym == insert_symbol("@dtor"))
+ ERR_B(fdef->base->tag.loc, _("can't use effects in destructors"));
const Vector base = &fdef->base->effects;
if (!base->ptr) vector_init(base);
for (uint32_t i = 0; i < v->len; i++) {
return GW_OK;
}
+ANN static void fdef_const_generic_value(const Env env, const Type owner, const Type t, const Tag tag) {
+ const Value v = new_value(env, t, s_name(tag.sym), tag.loc);
+ SET_FLAG(v, static|ae_flag_const);
+ valid_value(env, tag.sym, v);
+ nspc_add_value_front(owner->nspc, tag.sym, v);
+ v->from->owner = owner->nspc;
+ v->from->owner_class = owner;
+}
+
+ANN static m_bool fdef_const_generic_typecheck(const Env env, const Specialized *spec, const TmplArg *targ) {
+ CHECK_OB(check_exp(env, targ->d.exp));
+ // check implicits?
+ const Type target = known_type(env, spec->td);
+ if(isa(targ->d.exp->type, target) < 0) {
+ char msg[256];
+ tcol_snprintf(msg, 255, "expected {G+}%s{0}", target->name);
+ gwerr_basic("invalid type for const generic argument", msg, NULL, env->name, spec->tag.loc, 0);
+ tcol_snprintf(msg, 255, "got {G+}%s{0}", targ->d.exp->type->name);
+ gwerr_secondary(msg, env->name, targ->d.exp->pos);
+ return GW_ERROR;
+ }
+ return GW_OK;
+}
+
+ANN static m_bool check_fdef_const_generic(const Env env, const Func_Def fdef) {
+ const Tmpl *tmpl = fdef->base->tmpl;
+ if(tmplarg_ntypes(tmpl->call) == tmpl->call->len) return GW_OK;
+ const Type t = fdef->base->func->value_ref->type;
+ assert(!t->nspc);
+ t->nspc = new_nspc(env->gwion->mp, t->name);
+
+ for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) {
+ const TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i);
+ if(targ->type == tmplarg_td)continue;
+ // spec could be null cause of spread ops
+ const Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i);
+ if(!spec) break;
+ CHECK_BB(fdef_const_generic_typecheck(env, spec, targ));
+ fdef_const_generic_value(env, t, targ->d.exp->type, spec->tag);
+ }
+ return GW_OK;
+}
+
+ANN static m_bool check_fdef_code(const Env env, const Func_Def fdef) {
+ const bool ctor = is_ctor(fdef);
+ if(!ctor) {
+ nspc_push_value(env->gwion->mp, env->curr);
+ env->scope->depth++;
+ }
+ const m_bool ret = check_stmt_list(env, fdef->d.code);
+ if(!ctor) {
+ env->scope->depth--;
+ nspc_pop_value(env->gwion->mp, env->curr);
+ }
+ CHECK_BB(check_fdef_effects(env, fdef));
+ return ret;
+}
+
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(fdef->builtin) return GW_OK;
- if (fdef->d.code && fdef->d.code) {
- const bool ctor = is_ctor(fdef);
- if(!ctor) {
- env->scope->depth++;
- nspc_push_value(env->gwion->mp, env->curr);
- }
- const m_bool ret = check_stmt_list(env, fdef->d.code);
- if(!ctor) {
- nspc_pop_value(env->gwion->mp, env->curr);
- env->scope->depth--;
- }
- CHECK_BB(check_fdef_effects(env, fdef));
- return ret;
- }
+ if (fdef->base->tmpl) CHECK_BB(check_fdef_const_generic(env, fdef));
+ if (fdef->builtin) return GW_OK;
+ if (fdef->d.code) CHECK_BB(check_fdef_code(env, fdef));
return GW_OK;
}
const Type parent = env->class_def->info->parent;
const Value v = nspc_lookup_value0(parent->nspc, insert_symbol("new"));
if(v && !GET_FLAG(v->d.func_ref->def->base, abstract))
- ERR_B(func->def->base->pos, "missing call to parent constructor");
+ ERR_B(func->def->base->tag.loc, "missing call to parent constructor");
}
}
-
return GW_OK;
}
const Func former = env->func;
env->func = func;
nspc_push_value(env->gwion->mp, env->curr);
+// env->scope->depth++;
struct Op_Import opi = {};
if (fbflag(fdef->base, fbflag_op)) {
func_operator(f, &opi);
uint32_t offset = fdef->stack_depth;
for(uint32_t i = 0; i < fdef->captures->len; i++) {
Capture *cap = mp_vector_at(fdef->captures, Capture, i);
- valid_value(env, cap->xid, cap->temp);
+ valid_value(env, cap->tag.sym, cap->temp);
cap->temp->from->offset = offset;
offset += cap->temp->type->size;
}
vector_pop(&env->scope->effects);
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) {
if (env->class_def && fdef->base->effects.ptr &&
(override &&
!check_effect_overload(&fdef->base->effects, override->d.func_ref)))
- ERR_B(fdef->base->pos, _("too much effects in override."),
- s_name(fdef->base->xid))
+ ERR_B(fdef->base->tag.loc, _("too much effects in override."),
+ s_name(fdef->base->tag.sym))
if(is_new(f) && !tflag(env->class_def, tflag_struct))
CHECK_BB(check_ctor(env, func));
}
ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
const Type t = xdef->type;
- ValueFrom from = { .filename = env->name, .loc=xdef->td->pos, .ctx=env->context,
+ ValueFrom from = { .filename = env->name, .loc=xdef->td->tag.loc, .ctx=env->context,
.owner = env->curr, .owner_class = env->class_def
};
const bool ret = check_trait_requests(env, t, xdef->traits, &from);
}
ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
- const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid);
+ const Trait trait = nspc_lookup_trait1(env->curr, pdef->tag.sym);
Ast ast = pdef->body;
if(!ast) return GW_OK;
for(m_uint i = 0; i < ast->len; i++) {
const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
if (stmt->stmt_type == ae_stmt_exp) {
CHECK_BB(traverse_exp(env, stmt->d.stmt_exp.val));
- Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.vd;
+ Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.var.vd;
const Value value = vd.value;
valuefrom(env, value->from);
if (!trait->var)
gwerr_basic(_("missing function definition"),
_("must be declared 'abstract'"),
_("provide an implementation for the following:"),
- env->name, cdef->pos, 0);
+ env->name, cdef->base.tag.loc, 0);
}
ValueFrom *from = f->value_ref->from;
gwerr_secondary_from("implementation missing", from);
const Section *section = mp_vector_at(ast, Section, 0);
if(section->section_type != ae_section_func) return false;
Func_Def f = section->d.func_def;
- if(strcmp(s_name(f->base->xid), "@ctor"))return false;
+ if(strcmp(s_name(f->base->tag.sym), "@ctor"))return false;
Stmt_List l = f->d.code;
for(m_uint i = 0; i < l->len; i++) {
const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
const Exp exp = stmt->d.stmt_exp.val;
if (!exp) continue;
if (exp->exp_type != ae_exp_decl) return true;
- if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
- Var_Decl vd = exp->d.exp_decl.vd;
+ if (GET_FLAG(exp->d.exp_decl.var.td, late)) continue;
+ Var_Decl vd = exp->d.exp_decl.var.vd;
if (GET_FLAG(vd.value, late)) continue;
if (tflag(vd.value->type, tflag_compound))
return true;
if(type_is_recurs(t, tgt)) {
env_err(env, v->from->loc, _("recursive type"));
env_set_error(env, false);
- gwerr_secondary("in class", t->name, t->info->cdef->base.pos);
+ gwerr_secondary("in class", t->name, t->info->cdef->base.tag.loc);
const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ?
v->type : t;
const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
if(likely(targ.type == tmplarg_td)) continue;
CHECK_OB(check_exp(env, targ.d.exp));
-// if(isa(targ.d.exp->type, known_type(env, spec)
const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
- const Value v = new_value(env, targ.d.exp->type, s_name(spec.xid), targ.d.exp->pos);
+ const Value v = new_value(env, targ.d.exp->type, s_name(spec.tag.sym), targ.d.exp->pos);
valuefrom(env, v->from);
set_vflag(v, vflag_valid);
- nspc_add_value(nspc, spec.xid, v);
-// valid_value(env, spec.xid, v);
+ nspc_add_value(nspc, spec.tag.sym, v);
SET_FLAG(v, const| ae_flag_static);
set_vflag(v, vflag_builtin);
-
- // set value type
}
}
return GW_OK;
}
ANN static bool trait_inherit(const Env env, const Type t, const Func_Def req) {
- const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->xid);
+ const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->tag.sym);
nspc_push_type(env->gwion->mp, env->curr);
nspc_add_type(env->curr, insert_symbol("Self"), t);
const Func_Def cpy = cpy_func_def(env->gwion->mp, req);
if (mp_vector_len(f->def->base->args) + m != mp_vector_len(req->args)) return false;
if(m) {
const Arg *r = mp_vector_at(req->args, Arg, 0);
- if(strcmp(s_name(r->td->xid), "Self"))
+ if(strcmp(s_name(r->var.td->tag.sym), "Self"))
return false;
}
for(m_uint i = m; i < req->args->len; i++) {
const Arg *r = mp_vector_at(req->args, Arg, i + m);
- const Type t = known_type(env, r->td);
+ const Type t = known_type(env, r->var.td);
const Arg *arg = mp_vector_at(f->def->base->args, Arg, i);
if(arg->type != t) return false;
}
ANN static bool request_found(const Env env, const Type t,
const Func_Def request) {
- const Value v = nspc_lookup_value0(t->nspc, request->base->xid);
+ const Value v = nspc_lookup_value0(t->nspc, request->base->tag.sym);
if (!v) return false;
if (!is_func(env->gwion, v->type)) {
gwerr_basic_from("is not a function", NULL, NULL, v->from, 0);
ANN static bool trait_ufcs(const Env env, const Type t,
const Func_Def request) {
- const Value v = nspc_lookup_value1(env->curr, request->base->xid);
+ const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym);
if(v) {
const bool global = type_global(env, t) || from_global_nspc(env, v->from->owner);
nspc_push_type(env->gwion->mp, env->curr);
if (trait_ufcs(env, t, request)) return true;
if (!GET_FLAG(request->base, abstract))
return trait_inherit(env, t, request);
- const Value parent = nspc_lookup_value1(env->global_nspc, request->base->xid);
+ const Value parent = nspc_lookup_value1(env->global_nspc, request->base->tag.sym);
if(parent) {
- const Value v = nspc_lookup_value1(env->curr, request->base->xid);
+ const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym);
if(!env->context->error) {
gwerr_basic_from("is missing {+G}global{0}", NULL, NULL, v->from, 0);
- gwerr_secondary("from requested func", env->name, request->base->pos);
+ gwerr_secondary("from requested func", env->name, request->base->tag.loc);
env_set_error(env, true);
}
} else gwerr_basic("missing requested function", NULL, NULL, env->name,
- request->base->pos, 0);
+ request->base->tag.loc, 0);
return false;
}
ANN2(1,2) static Exp base_args(const MemPool p, const Arg_List args, Exp next, const uint32_t min) {
for(uint32_t i = min; i--;) {
Arg *arg = mp_vector_at(args, Arg, i);
- const Exp exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
+ const Exp exp = new_prim_id(p, arg->var.vd.tag.sym, arg->var.vd.tag.loc);
exp->next = next;
next = exp;
}
ANN static Stmt_List std_code(const Env env, Func_Base *base, const uint32_t max) {
const MemPool p = env->gwion->mp;
- const Exp func = new_prim_id(p, base->xid, base->pos);
+ const Exp func = new_prim_id(p, base->tag.sym, base->tag.loc);
return code(p, func, base->args, max, ae_stmt_return);
}
ANN static Stmt_List new_code(const Env env, Func_Base *base, const uint32_t max) {
const MemPool p = env->gwion->mp;
SymTable *st = env->gwion->st;
- const Exp dbase = new_prim_id(p, insert_symbol(st, "this"), base->pos);
+ const Exp dbase = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc);
const Symbol sym = insert_symbol(st, "new");
- const Exp func = new_exp_dot(p, dbase, sym, base->pos);
+ const Exp func = new_exp_dot(p, dbase, sym, base->tag.loc);
return code(p, func, base->args, max, ae_stmt_exp);
}
ANN Func_Def default_args(const Env env, Func_Base *fb, Ast *acc, uint32_t max) {
Func_Base *const base = cpy_func_base(env->gwion->mp, fb);
- Stmt_List code = strcmp(s_name(base->xid), "new")
+ Stmt_List code = strcmp(s_name(base->tag.sym), "new")
? std_code(env, fb, max)
: new_code(env, fb, max);
const Func_Def fdef = new_func_def(env->gwion->mp, base, code);
#include "operator.h"
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);
+ opi->op = fdef->base->tag.sym;
+ const m_str str = s_name(fdef->base->tag.sym);
const uint is_unary =
fbflag(fdef->base, fbflag_unary) +
(!strcmp(str, "@conditional") || !strcmp(str, "@unconditional"));
const Arg_List args = fdef->base->args;
Arg *arg0 = args ? mp_vector_at(args, Arg, 0) : NULL;
Arg *arg1 = (args && args->len >= 2) ? mp_vector_at(args, Arg, 1) : NULL;
- opi->lhs = is_unary ? NULL : args ? arg0->var_decl.value->type : NULL;
+ opi->lhs = is_unary ? NULL : args ? arg0->var.vd.value->type : NULL;
if (strcmp(str, "@implicit"))
// opi->rhs = args ? is_unary ? arg0->var_decl->value->type
- opi->rhs = args ? is_unary ? (arg0 ? arg0->var_decl.value->type : NULL)
- : (arg1 ? arg1->var_decl.value->type : NULL)
+ opi->rhs = args ? is_unary ? (arg0 ? arg0->var.vd.value->type : NULL)
+ : (arg1 ? arg1->var.vd.value->type : NULL)
: NULL;
else
opi->rhs = fdef->base->ret_type;
const Tmpl tmpl = {.list = base->base->tmpl->list, .call = ra->types};
CHECK_BO(template_push_types(env, &tmpl));
Func_Base *const fbase = cpy_func_base(env->gwion->mp, base->base);
- fbase->xid = sym;
+ fbase->tag.sym = sym;
fbase->tmpl->call = cpy_type_list(env->gwion->mp, ra->types);
const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase);
const Func m_func = ensure_fptr(env, ra, fptr);
char c[256];
sprintf(c, "arg%u", idx);
TmplArg targ = *mp_vector_at(ra->types, TmplArg, idx);
- Arg arg = { .td = cpy_type_decl(env->gwion->mp, targ.d.td), .var_decl = {.xid = insert_symbol(c), /*.value = v*/ }};
+ Arg arg = { .var = MK_VAR(cpy_type_decl(env->gwion->mp, targ.d.td), (Var_Decl){ .tag = MK_TAG(insert_symbol(c), fdef->base->tag.loc)})};
mp_vector_add(env->gwion->mp, &args, Arg, arg);
}
fdef->base->args = args;
}
-
const Func func = ensure_tmpl(env, fdef, ra->e, ra->v->from->filename);
if (func && func->def->builtin) {
builtin_func(env->gwion, func, (void*)ra->v->d.func_ref->code->native_func);
.v = v, .e = exp, .tmpl_name = tmpl_name, .types = types};
CHECK_BO(envset_pushv(&es, v));
(void)env_push(env, v->from->owner_class, v->from->owner);
- const bool in_tmpl = v->from->owner_class && v->from->owner_class->info->cdef &&
- v->from->owner_class->info->cdef->base.tmpl;
- if(in_tmpl)
- (void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl);
+ const Tmpl *tmpl = v->from->owner_class && v->from->owner_class->info->cdef ?
+ get_tmpl(v->from->owner_class) : NULL;
+ if(tmpl)
+ (void)template_push_types(env, tmpl);
const bool is_clos = isa(exp->func->type, env->gwion->type[et_closure]) > 0;
const Func m_func = !is_clos ? func_match(env, &ra)
: fptr_match(env, &ra);
- if(in_tmpl)
+ if(tmpl)
nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
envset_pop(&es, v->from->owner_class);
Specialized * spec = mp_vector_at(sl, Specialized, i);
TmplArg arg = *mp_vector_at(tl, TmplArg, i);
if(unlikely(spec->td)) {
-// check argument in call exp
+ if(unlikely(arg.type == tmplarg_td))
+ ERR_O(exp_self(exp)->pos, "expected contant, not type");
+ // check argument in call exp
continue;
+ } else {
+ if(unlikely(arg.type == tmplarg_exp)) {
+ ERR_O(exp_self(exp)->pos, "expected type, not constant");
+ // check argument in call exp?
+ continue;
+ }
+ DECL_OO(const Type, t, = known_type(env, arg.d.td));
+ if(t->info->traits && miss_traits(t, spec))
+ return NULL;
}
- DECL_OO(const Type, t, = known_type(env, arg.d.td));
- if(t->info->traits && miss_traits(t, spec))
- return NULL;
}
return f;
}
while (t && t->nspc) {
const Func_Def fdef = value->d.func_ref ? value->d.func_ref->def
: value->type->info->func->def;
- const Value v = nspc_lookup_value0(t->nspc, fdef->base->xid);
+ const Value v = nspc_lookup_value0(t->nspc, fdef->base->tag.sym);
if (v) {
const Func f = _find_template_match(env, v, exp);
if (f) return f;
ANN static bool op_template_type(const Symbol xid, const Specialized_List sl) {
for(uint32_t i = 0; i < sl->len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- if (xid == spec->xid) return true;
+ if (xid == spec->tag.sym) return true;
}
return false;
}
//! check if type matches for template operator
ANN2(1,2,3) bool _tmpl_match(const Env env, const Type t, Type_Decl *const td,
Specialized_List sl) {
- if (!td->next && !td->types && op_template_type(td->xid, sl))
+ if (!td->next && !td->types && op_template_type(td->tag.sym, sl))
return true;
const Type base = known_type(env, td);
return base ? isa(t, base) > 0 : false;
Arg *arg0 = mp_vector_at(args, Arg, 0);
Arg *arg1 = args->len > 1 ? mp_vector_at(args, Arg, 1) : NULL;
if (opi->lhs) {
- if (!_tmpl_match(env, opi->lhs, arg0->td, sl)) return false;
+ if (!_tmpl_match(env, opi->lhs, arg0->var.td, sl)) return false;
if (fbflag(base, fbflag_postfix)) return !!opi->rhs;
if (!fbflag(base, fbflag_unary)) {
if (!opi->rhs) return false;
- if (!_tmpl_match(env, opi->rhs, arg1->td, sl)) return false;
+ if (!_tmpl_match(env, opi->rhs, arg1->var.td, sl)) return false;
} else if (opi->rhs) return false;
} else if (!fbflag(base, fbflag_unary) ||
- !_tmpl_match(env, opi->rhs, arg0->td, sl))
+ !_tmpl_match(env, opi->rhs, arg0->var.td, sl))
return false;
return true;
}
const Vector v = &nspc->operators->tmpl;
for (m_uint i = vector_size(v) + 1; --i;) {
const Func_Def fdef = (Func_Def)vector_at(v, i - 1);
- if (opi->op != fdef->base->xid) continue;
+ if (opi->op != fdef->base->tag.sym) continue;
if (!tmpl_match(env, opi, fdef->base)) continue;
return op_def(env, opi, fdef);
}
emit_pushfunc(emit, mo->func);
CHECK_BB(emit_exp_call1(emit, mo->func,
mo->func->def->base->ret_type->size, true));
- if (mo->func->def->base->xid ==
+ if (mo->func->def->base->tag.sym ==
insert_symbol(emit->gwion->st, "@conditional"))
emit_add_instr(emit, BranchEqInt);
- else if (mo->func->def->base->xid ==
+ else if (mo->func->def->base->tag.sym ==
insert_symbol(emit->gwion->st, "@unconditional"))
emit_add_instr(emit, BranchNeqInt);
return GW_OK;
char c[256];
sprintf(c, "@%u", args->len);
const Arg *src = mp_vector_at(base, Arg, i);
- Type_Decl *td = src->td ? cpy_type_decl(env->gwion->mp, src->td) : NULL;
- Arg arg = { .td = td, .var_decl = { .xid = insert_symbol(c) }};
+ Type_Decl *td = src->var.td ? cpy_type_decl(env->gwion->mp, src->var.td) : NULL;
+ Arg arg = { .var = MK_VAR(td, (Var_Decl){ .tag = MK_TAG(insert_symbol(c), src->var.vd.tag.loc)})};
mp_vector_add(env->gwion->mp, &args, Arg, arg);
}
i++;
char c[256];
sprintf(c, "@%u", i);
const Exp exp = new_prim_id(env->gwion->mp, insert_symbol(c), e->pos);
- exp->type = known_type(env, mp_vector_at(args, Arg, i)->td);
+ exp->type = known_type(env, mp_vector_at(args, Arg, i)->var.td);
exp->d.prim.value = new_value(env, exp->type, c, e->pos);
valid_value(env, insert_symbol(c), exp->d.prim.value);
return exp;
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
gw_err("{G}%s{0} {/}%s{0}", arg->type ? arg->type->name : NULL,
- arg->var_decl.xid ? s_name(arg->var_decl.xid) : "");
+ arg->var.vd.tag.sym ? s_name(arg->var.vd.tag.sym) : "");
if(i < args->len - 1) gw_err(", ");
}
}
nspc_add_type_front(nspc, insert_symbol(t->name), t);
}
-ANN static inline m_bool scan0_defined(const Env env, const Symbol s,
- const loc_t pos) {
- if (nspc_lookup_type1(env->curr, s))
- ERR_B(pos, _("type '%s' already defined"), s_name(s));
- return already_defined(env, s, pos);
+ANN static inline m_bool scan0_defined(const Env env, const Tag tag) {
+ if (nspc_lookup_type1(env->curr, tag.sym))
+ ERR_B(tag.loc, _("type '%s' already defined"), s_name(tag.sym));
+ return already_defined(env, tag.sym, tag.loc);
}
ANN static Arg_List fptr_arg_list(const Env env, const Fptr_Def fptr) {
if(env->class_def && !GET_FLAG(fptr->base, static)) {
- Arg arg = { .td = type2td(env->gwion, env->class_def, fptr->base->td->pos) };
+ Arg arg = { .var = {.td = type2td(env->gwion, env->class_def, fptr->base->td->tag.loc)}};
const uint32_t len = mp_vector_len(fptr->base->args);
Arg_List args = new_mp_vector(env->gwion->mp, Arg, len + 1);
mp_vector_set(args, Arg, 0, arg);
for(uint32_t i = 0; i < len; i++) {
Arg *base = mp_vector_at(fptr->base->args, Arg, i);
- Arg arg = { .td = cpy_type_decl(env->gwion->mp, base->td) };
+ Arg arg = { .var = {.td = cpy_type_decl(env->gwion->mp, base->var.td)}};
mp_vector_set(args, Arg, i+1, arg);
}
return args;
}
ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
- const loc_t loc = fptr->base->td->pos;
+ const loc_t loc = fptr->base->td->tag.loc;
CHECK_BB(env_access(env, fptr->base->flag, loc));
- CHECK_BB(scan0_defined(env, fptr->base->xid, loc));
+ CHECK_BB(scan0_defined(env, fptr->base->tag));
const Arg_List args = fptr_arg_list(env, fptr);
Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, fptr->base->td),
insert_symbol("func"), args, ae_flag_static | ae_flag_private, loc);
Ast body = new_mp_vector(env->gwion->mp, Section, 1);
mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
Type_Decl* td = new_type_decl(env->gwion->mp, insert_symbol(env->gwion->type[et_closure]->name), loc);
- const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->xid, td, body, loc);
+ const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->tag.sym, td, body, loc);
if(GET_FLAG(fptr->base, global)) {
SET_FLAG(cdef, global);
UNSET_FLAG(fptr->base, global);
ANN static void typedef_simple(const Env env, const Type_Def tdef,
const Type base) {
- const Type t = new_type(env->gwion->mp, s_name(tdef->xid), base);
+ const Type t = new_type(env->gwion->mp, s_name(tdef->tag.sym), base);
t->size = base->size;
const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global))
? env->global_nspc
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef,
const Type base) {
const ae_flag flag = base->info->cdef ? base->info->cdef->flag : 0;
- const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
+ const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->tag.sym,
cpy_type_decl(env->gwion->mp, tdef->ext),
- NULL, tdef->ext->pos);
+ NULL, tdef->ext->tag.loc);
const bool final = GET_FLAG(base, final);
if(final) UNSET_FLAG(base, final);
CHECK_BB(scan0_class_def(env, cdef));
}
ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
- CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos));
+ CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->tag.loc));
DECL_OB(const Type, base, = known_type(env, tdef->ext));
- CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos));
- DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->pos));
+ CHECK_BB(scan0_defined(env, tdef->tag));
+ DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->tag.loc));
if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
typedef_simple(env, tdef, base);
else CHECK_BB(typedef_complex(env, tdef, base));
- mk_class(env, tdef->type, tdef->pos);
+ mk_class(env, tdef->type, tdef->tag.loc);
if (tdef->when) set_tflag(tdef->type, tflag_contract);
if (tdef->type != base && !tdef->distinct && !tdef->when)
scan0_implicit_similar(env, base, tdef->type);
ANN static Type enum_type(const Env env, const Enum_Def edef) {
const Type t = type_copy(env->gwion->mp, env->gwion->type[et_enum]);
- t->name = s_name(edef->xid);
+ t->name = s_name(edef->tag.sym);
t->info->parent = env->gwion->type[et_enum];
add_type(env, env->curr, t);
- mk_class(env, t, edef->pos);
+ mk_class(env, t, edef->tag.loc);
return t;
}
ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
- CHECK_BB(scan0_defined(env, edef->xid, edef->pos));
- DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->pos));
+ CHECK_BB(scan0_defined(env, edef->tag));
+ DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->tag.loc));
edef->type = enum_type(env, edef);
if (global) env_pop(env, 0);
return GW_OK;
}
ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
- DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->pos));
- CHECK_BB(scan0_defined(env, udef->xid, udef->pos));
- udef->type = union_type(env, udef->xid, udef->pos);
+ DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->tag.loc));
+ CHECK_BB(scan0_defined(env, udef->tag));
+ udef->type = union_type(env, udef->tag.sym, udef->tag.loc);
SET_ACCESS(udef, udef->type);
if (udef->tmpl) union_tmpl(env, udef);
if (global) env_pop(env, 0);
Type owner = env->class_def;
while (owner) {
if (t == owner)
- ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name);
+ ERR_O(td->tag.loc, _("'%s' as parent inside itself\n."), owner->name);
owner = owner->info->value->from->owner_class;
}
return t;
ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
const Type t = known_type(env, td);
- if(!t) ERR_O(td->pos, _("can't find parent class %s\n."), s_name(td->xid));
+ if(!t) ERR_O(td->tag.loc, _("can't find parent class %s\n."), s_name(td->tag.sym));
return t;
}
}
ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
- CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos));
+ CHECK_BO(scan0_defined(env, cdef->base.tag));
DECL_OO(const Type, parent, = cdef_parent(env, cdef));
if(GET_FLAG(cdef, global) && isa(parent, env->gwion->type[et_closure]) < 0 && !type_global(env, parent)) {
- gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->pos : cdef->base.pos, 0);
+ gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->tag.loc : cdef->base.tag.loc, 0);
declared_here(parent->info->value);
env_set_error(env, true);
return NULL;
}
- if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos));
- const Type t = new_type(env->gwion->mp, s_name(cdef->base.xid), parent);
+ if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->base.tag.loc));
+ const Type t = new_type(env->gwion->mp, s_name(cdef->base.tag.sym), parent);
if (cflag(cdef, cflag_struct)) {
t->size = 0;
set_tflag(t, tflag_struct);
ANN static m_bool _spread_tmpl(const Env env, const Type t, const Spread_Def spread) {
if(t->info->value->from->owner_class)
CHECK_BB(_spread_tmpl(env, t->info->value->from->owner_class, spread));
- const Tmpl *tmpl = t->info->cdef->base.tmpl;
+ const Tmpl *tmpl = get_tmpl(t);
if(!tmpl || !tmpl->call) return GW_OK;
if(is_spread_tmpl(tmpl))
CHECK_BB(spread_ast(env, spread, tmpl));
return true;
Type t = env->class_def;
while(t) {
- const Tmpl *tmpl = t->info->cdef->base.tmpl;
+ const Tmpl *tmpl = get_tmpl(t);
if(tmpl && is_spread_tmpl(tmpl))
return true;
t = t->info->value->from->owner_class;
if(!fdef->base->tmpl || !fdef->base->tmpl->call) return GW_OK;
if(env->context) {
if(fdef->base->tmpl && fdef->base->tmpl->call && is_spread_tmpl(fdef->base->tmpl)) {
- struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former =
+ struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former =
env->func;
env->func = &fake;
if(!fdef->builtin && fdef->d.code)
if(!global) {
const Trait trait = nspc_lookup_trait1(env->curr, xid);
gwerr_basic("trait should be declared global", NULL, NULL, trait->filename, trait->loc, 0);
- gwerr_secondary("from the request ", env->name, xdef->td->pos);
+ gwerr_secondary("from the request ", env->name, xdef->td->tag.loc);
env_set_error(env, true);
}
}
}
ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
- CHECK_BB(scan0_defined(env, pdef->xid, pdef->pos));
- DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->pos));
- const Trait trait = new_trait(env->gwion->mp, pdef->pos);
- trait->loc = pdef->pos;
- trait->name = s_name(pdef->xid);
+ CHECK_BB(scan0_defined(env, pdef->tag));
+ DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->tag.loc));
+ const Trait trait = new_trait(env->gwion->mp, pdef->tag.loc);
+ trait->loc = pdef->tag.loc;
+ trait->name = s_name(pdef->tag.sym);
trait->filename = env->name;
- nspc_add_trait(env->curr, pdef->xid, trait);
+ nspc_add_trait(env->curr, pdef->tag.sym, trait);
if(global) env_pop(env, 0);
Ast ast = pdef->body;
if(!ast) return GW_OK; // ???
const Func_Def fdef = section->d.func_def;
if (fdef->base->flag != ae_flag_none &&
fdef->base->flag != (ae_flag_none | ae_flag_abstract))
- ERR_B(fdef->base->pos, "Trait function must be declared without qualifiers");
+ ERR_B(fdef->base->tag.loc, "Trait function must be declared without qualifiers");
if (!trait->fun) trait->fun = new_mp_vector(env->gwion->mp, Func_Def, 0);
mp_vector_add(env->gwion->mp, &trait->fun, Func_Def, fdef);
} else if (section->section_type == ae_section_stmt) {
ERR_B(stmt->pos, "trait can only contains variable requests and functions");
}
} else
- ERR_B(pdef->pos, "invalid section for trait definition");
+ ERR_B(pdef->tag.loc, "invalid section for trait definition");
}
return GW_OK;
}
ANN static m_bool scan0_trait_def(const Env env, const Trait_Def pdef) {
- const Symbol s = pdef->xid;
+ const Symbol s = pdef->tag.sym;
const Trait exists = nspc_lookup_trait1(env->curr, s);
if (exists) {
- gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->pos, 0);
+ gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->tag.loc, 0);
gwerr_secondary("defined here", env->name, exists->loc);
env_set_error(env, true);
- return already_defined(env, s, pdef->pos);
+ return already_defined(env, s, pdef->tag.loc);
}
- if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->pos));
+ if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->tag.loc));
_scan0_trait_def(env, pdef);
return GW_OK;
}
ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) {
- const loc_t loc = pdef->loc;
+ const loc_t loc = pdef->tag.loc;
CHECK_BB(env_access(env, pdef->flag, loc));
- CHECK_BB(scan0_defined(env, pdef->name, loc));
+ CHECK_BB(scan0_defined(env, pdef->tag));
DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, loc));
- const Type t = mk_primitive(env, s_name(pdef->name), pdef->size);
+ const Type t = mk_primitive(env, s_name(pdef->tag.sym), pdef->size);
add_type(env, env->curr, t);
- mk_class(env, t, pdef->loc);
+ mk_class(env, t, pdef->tag.loc);
t->flag = pdef->flag;
if(global) env_pop(env, 0);
return GW_OK;
HANDLE_SECTION_FUNC(scan0, m_bool, Env)
ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
- CHECK_BB(isres(env, cdef->base.xid, cdef->pos));
+ CHECK_BB(isres(env, cdef->base.tag));
CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)));
cdef->base.type->info->traits = cdef->traits; // should we copy the traits?
set_tflag(cdef->base.type, tflag_scan0);
- (void)mk_class(env, cdef->base.type, cdef->pos);
+ (void)mk_class(env, cdef->base.type, cdef->base.tag.loc);
add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK;
return ret;
ANN Ast spread_class(const Env env, const Ast body);
ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
- DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->pos));
+ DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->base.tag.loc));
const Ast old_extend = env->context ? env->context->extend : NULL;
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);
Type parent = t;
do {
if (parent == owner)
- ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
+ ERR_B(td->tag.loc, _("%s declared inside %s"), t->name, owner->name);
} while ((parent = parent->info->parent));
} while ((owner = owner->info->value->from->owner_class));
return GW_OK;
}
ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
- if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
+// if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
+ if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_union)))
return GW_OK;
struct EnvSet es = {.env = env,
.data = env,
ANN static Type void_type(const Env env, Type_Decl *td) {
DECL_OO(const Type, type, = scan1_type(env, td));
if (type->size) return type;
- ERR_O(td->pos, _("cannot declare variables of size '0' (i.e. 'void')..."))
+ ERR_O(td->tag.loc, _("cannot declare variables of size '0' (i.e. 'void')..."))
}
ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) {
if (decl->type) return decl->type;
- DECL_OO(const Type, t, = void_type(env, decl->td));
- if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->td->pos))
+ DECL_OO(const Type, t, = void_type(env, decl->var.td));
+ if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->var.td->tag.loc))
return NULL;
- if (decl->td->xid == insert_symbol("auto") && decl->type) return decl->type;
+ if (decl->var.td->tag.sym == insert_symbol("auto") && decl->type) return decl->type;
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))
const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
env->scope->depth)
? nspc_lookup_value1
- : nspc_lookup_value2)(env->curr, var->xid);
+ : nspc_lookup_value2)(env->curr, var->tag.sym);
if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0))
- ERR_B(var->pos,
+ ERR_B(var->tag.loc,
_("variable %s has already been defined in the same scope..."),
- s_name(var->xid))
+ s_name(var->tag.sym))
return GW_OK;
}
}
ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
- const bool decl_ref = decl->td->array && !decl->td->array->exp;
- Var_Decl *const vd = &decl->vd;
- CHECK_BB(isres(env, vd->xid, exp_self(decl)->pos));
+ const bool decl_ref = decl->var.td->array && !decl->var.td->array->exp;
+ Var_Decl *const vd = &decl->var.vd;
+ CHECK_BB(isres(env, vd->tag));
Type t = decl->type;
CHECK_BB(scan1_defined(env, vd));
const Type base = array_base_simple(t);
- if(decl->td->array) {
- if (!GET_FLAG(decl->td, late) && !decl->td->array->exp)
- ERR_B(decl->td->pos, _("arrays with no expressions should be declared `late`"));
- if (GET_FLAG(decl->td, late) && decl->td->array->exp)
- ERR_B(decl->td->array->exp->pos, _("late array should have no size"));
- if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->td->array));
+ if(decl->var.td->array) {
+ if (!GET_FLAG(decl->var.td, late) && !decl->var.td->array->exp)
+ ERR_B(decl->var.td->tag.loc, _("arrays with no expressions should be declared `late`"));
+ if (GET_FLAG(decl->var.td, late) && decl->var.td->array->exp)
+ ERR_B(decl->var.td->array->exp->pos, _("late array should have no size"));
+ if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->var.td->array));
}
const Value v = vd->value =
- vd->value ?: new_value(env, t, s_name(vd->xid), vd->pos);
- if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->td, late)) SET_FLAG(v, late);
+ vd->value ?: new_value(env, t, s_name(vd->tag.sym), vd->tag.loc);
+ if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->var.td, late)) SET_FLAG(v, late);
v->type = t;
if (decl_ref) SET_FLAG(v, late);
- v->flag |= decl->td->flag;
+ v->flag |= decl->var.td->flag;
if (!env->scope->depth) {
valuefrom(env, v->from);
if (env->class_def) {
if (env->class_def->info->tuple) tuple_contains(env, v);
- if (!GET_FLAG(decl->td, static)) {
+ if (!GET_FLAG(decl->var.td, static)) {
set_vflag(v, vflag_member);
if(tflag(t, tflag_release))
set_tflag(env->class_def, tflag_release);
env->class_def->size += t->size;
}
}
- } else if (GET_FLAG(decl->td, global))
+ } else if (GET_FLAG(decl->var.td, global))
SET_FLAG(v, global);
else if(env->context)
set_vflag(v, vflag_fglobal); // file global
- } else if (GET_FLAG(decl->td, global))
+ } else if (GET_FLAG(decl->var.td, global))
SET_FLAG(v, global);
- nspc_add_value(env->curr, vd->xid, v);
- ((Exp_Decl *)decl)->type = decl->vd.value->type;
+ nspc_add_value(env->curr, vd->tag.sym, v);
+ ((Exp_Decl *)decl)->type = decl->var.vd.value->type;
return GW_OK;
}
ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
- CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos));
+ CHECK_BB(env_storage(env, decl->var.td->flag, exp_self(decl)->pos));
((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl);
CHECK_OB(decl->type);
if(decl->args) CHECK_BB(scan1_exp(env, decl->args));
- const bool global = GET_FLAG(decl->td, global);
+ const bool global = GET_FLAG(decl->var.td, global);
if (global) {
if (env->context) env->context->global = true;
if (!type_global(env, decl->type))
ANN static inline m_bool stmt_each_defined(const restrict Env env,
const Stmt_Each stmt) {
- if (nspc_lookup_value1(env->curr, stmt->sym))
+ if (nspc_lookup_value1(env->curr, stmt->tag.sym))
ERR_B(stmt_self(stmt)->pos, _("foreach value '%s' is already defined"),
- s_name(stmt->sym))
- if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->sym))
- ERR_B(stmt->idx->pos, _("foreach index '%s' is already defined"),
- s_name(stmt->idx->sym))
+ s_name(stmt->tag.sym))
+ if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->tag.sym))
+ ERR_B(stmt->idx->tag.loc, _("foreach index '%s' is already defined"),
+ s_name(stmt->idx->tag.sym))
return GW_OK;
}
return GW_ERROR;
}
-ANN static inline m_bool shadow_arg(const Env env, const Symbol sym,
- const loc_t loc) {
+ANN static inline m_bool shadow_arg(const Env env, const Tag tag) {
Nspc nspc = env->curr;
do {
- const Value v = nspc_lookup_value0(nspc, sym);
+ const Value v = nspc_lookup_value0(nspc, tag.sym);
if (v && !env->func->def->builtin) {
const Type owner = v->from->owner_class;
if (owner && env->class_def && isa(env->class_def, owner) < 0)
continue;
- return shadow_err(env, v, loc);
+ return shadow_err(env, v, tag.loc);
}
} while ((nspc = nspc->parent));
return GW_OK;
}
-ANN static inline m_bool shadow_var(const Env env, const Symbol sym,
- const loc_t loc) {
- const Value v = nspc_lookup_value1(env->curr, sym);
- return !v ? GW_OK : shadow_err(env, v, loc);
+ANN static inline m_bool shadow_var(const Env env, const Tag tag){
+ const Value v = nspc_lookup_value1(env->curr, tag.sym);
+ return !v ? GW_OK : shadow_err(env, v, tag.loc);
}
#define describe_ret_nspc(name, type, prolog, exp) \
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->sym, stmt->idx->pos)) < 0 ||
+describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->tag)) < 0 ||
scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
m_int last = 0;
for(uint32_t i = 0; i < list->len; i++) {
EnumValue ev = *mp_vector_at(list, EnumValue, i);
- const Value v = new_value(env, t, s_name(ev.xid), edef->pos);
+ const Value v = new_value(env, t, s_name(ev.tag.sym), ev.tag.loc);
v->d.num = (ev.set ? ev.gwint.num : last);
last = v->d.num + 1;
valuefrom(env, v->from);
- nspc_add_value(env->curr, ev.xid, v);
+ nspc_add_value(env->curr, ev.tag.sym, v);
SET_FLAG(v, static | ae_flag_const);
SET_ACCESS(edef, v)
SET_ACCESS(edef, t)
}
ANN static Value arg_value(const Env env, Arg *const arg) {
- const Var_Decl *vd = &arg->var_decl;
+ const Var_Decl *vd = &arg->var.vd;
const Value v = new_value(env, arg->type,
- vd->xid ? s_name(vd->xid) : (m_str) __func__, arg->var_decl.pos);
- if (arg->td)
- v->flag = arg->td->flag;
+ vd->tag.sym ? s_name(vd->tag.sym) : (m_str) __func__, arg->var.vd.tag.loc);
+ if (arg->var.td)
+ v->flag = arg->var.td->flag;
return v;
}
ANN static m_bool scan1_args(const Env env, Arg_List args) {
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- Var_Decl *const vd = &arg->var_decl;
- if (vd->xid) CHECK_BB(isres(env, vd->xid, vd->pos));
- if (arg->td) {
- SET_FLAG(arg->td, late);
- CHECK_OB((arg->type = void_type(env, arg->td)));
+ Var_Decl *const vd = &arg->var.vd;
+ if (vd->tag.sym) CHECK_BB(isres(env, vd->tag));
+ if (arg->var.td) {
+ SET_FLAG(arg->var.td, late);
+ CHECK_OB((arg->type = void_type(env, arg->var.td)));
if (GET_FLAG(env->func->def->base, global) && !type_global(env, arg->type))
- ERR_B(arg->td->pos, "is not global");
- UNSET_FLAG(arg->td, late);
+ ERR_B(arg->var.td->tag.loc, "is not global");
+ UNSET_FLAG(arg->var.td, late);
}
vd->value = arg_value(env, arg);
- if (vd->xid) nspc_add_value(env->curr, vd->xid, vd->value);
+ if (vd->tag.sym) nspc_add_value(env->curr, vd->tag.sym, vd->value);
}
return GW_OK;
}
assert(base->td);
DECL_OO(const Type, t, = known_type(env, base->td));
if (!tflag(t, tflag_noret)) return t;
- ERR_O(base->pos, _("Can't use type `{+G}%s{0}` for return"), t->name);
+ ERR_O(base->tag.loc, _("Can't use type `{+G}%s{0}` for return"), t->name);
}
ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
Specialized_List sl = base->tmpl->list;
for(uint32_t i = 0; i < sl->len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
+ nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]);
}
CHECK_OB((base->ret_type = scan1_noret(env, base)));
return GW_OK;
ANN static bool find_op_template_type(const MemPool mp, const Symbol xid, const Specialized_List sl, MP_Vector **acc) {
for(uint32_t i = 0; i < sl->len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- if (xid == spec->xid) {
+ if (xid == spec->tag.sym) {
spec_acc_has(mp, acc, xid);
return true;
}
MP_Vector *acc = new_mp_vector(env->gwion->mp, Symbol, 0);
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- if (!arg->td->next) {
- find_op_template_type(env->gwion->mp, arg->td->xid, sl, &acc);
+ if (!arg->var.td->next) {
+ find_op_template_type(env->gwion->mp, arg->var.td->tag.sym, sl, &acc);
}
}
const uint32_t len = acc->len;
free_mp_vector(env->gwion->mp, Symbol, acc);
- if (len < sl->len) ERR_B(base->pos, "too many template types for operator");
+ if (len < sl->len) ERR_B(base->tag.loc, "too many template types for operator");
if (!env->curr->operators)
env->curr->operators = mp_calloc(env->gwion->mp, NspcOp);
const Vector v = &env->curr->operators->tmpl;
ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
if(tflag(tdef->type->info->parent, tflag_ref))
- ERR_B(tdef->pos, "can't typedef a reference type");
+ ERR_B(tdef->tag.loc, "can't typedef a reference type");
if (tflag(tdef->type, tflag_cdef))
return scan1_class_def(env, tdef->type->info->cdef);
return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK;
ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
Union_Def udef) {
nspc_allocdata(env->gwion->mp, udef->type->nspc);
- Union_List l = udef->l;
+ Variable_List l = udef->l;
m_uint sz = 0;
- const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->pos);
+ const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->tag.loc);
nspc_add_value_front(env->curr, insert_symbol("@index"), v);
valuefrom(env, v->from);
for(uint32_t i = 0; i < l->len; i++) {
- Union_Member *um = mp_vector_at(l, Union_Member, i);
+ Variable *um = mp_vector_at(l, Variable, i);
DECL_OB(const Type, t, = known_type(env, um->td));
- if (nspc_lookup_value0(env->curr, um->vd.xid))
- ERR_B(um->vd.pos, _("'%s' already declared in union"), s_name(um->vd.xid))
+ if (nspc_lookup_value0(env->curr, um->vd.tag.sym))
+ ERR_B(um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym))
if(tflag(t, tflag_ref))
- ERR_B(um->vd.pos, _("can't declare ref type in union"));
- const Value v = new_value(env, t, s_name(um->vd.xid), um->vd.pos);
+ ERR_B(um->vd.tag.loc, _("can't declare ref type in union"));
+ const Value v = new_value(env, t, s_name(um->vd.tag.sym), um->vd.tag.loc);
tuple_contains(env, v);
valuefrom(env, v->from);
- nspc_add_value_front(env->curr, um->vd.xid, v);
+ nspc_add_value_front(env->curr, um->vd.tag.sym, v);
if (t->size > sz) sz = t->size;
}
udef->type->nspc->offset = SZ_INT + sz;
ANN static m_bool class_internal(const Env env, const Func_Base *base) {
assert(base->td);
if (!env->class_def)
- ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid))
+ ERR_B(base->td->tag.loc, _("'%s' must be in class def!!"), s_name(base->tag.sym))
if (base->args)
- ERR_B(base->td->pos, _("'%s' must not have args"), s_name(base->xid))
+ ERR_B(base->td->tag.loc, _("'%s' must not have args"), s_name(base->tag.sym))
if (base->ret_type != env->gwion->type[et_void])
- ERR_B(base->td->pos, _("'%s' must return 'void'"), s_name(base->xid))
+ ERR_B(base->td->tag.loc, _("'%s' must return 'void'"), s_name(base->tag.sym))
return GW_OK;
}
const Func_Base *base) {
if (mp_vector_len(base->args) == 1) return GW_OK;
assert(base->td);
- ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"),
- s_name(base->xid))
+ ERR_B(base->td->tag.loc, _("'%s' must have one (and only one) argument"),
+ s_name(base->tag.sym))
}
ANN static inline m_bool scan_internal_int(const Env env,
assert(base->td);
CHECK_BB(scan_internal_arg(env, base));
if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK;
- ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid))
+ ERR_B(base->td->tag.loc, _("'%s' must return 'int'"), s_name(base->tag.sym))
}
ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
- const Symbol op = base->xid;
+ const Symbol op = base->tag.sym;
if (op == insert_symbol("@dtor")) {
if(safe_tflag(env->class_def, tflag_struct))
- ERR_B(base->pos, "can't use '@dtor' for structures");
+ ERR_B(base->tag.loc, "can't use '@dtor' for structures");
return class_internal(env, base);
}
if (op == insert_symbol("@gack"))
op == insert_symbol("@each_init") ||
op == insert_symbol("@each_val") ||
op == insert_symbol("@partial"))
- ERR_B(base->pos, "operator '%s' not allowed", s_name(op));
+ ERR_B(base->tag.loc, "operator '%s' not allowed", s_name(op));
return GW_OK;
}
ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) {
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- CHECK_BB(shadow_arg(env, arg->var_decl.xid, arg->var_decl.pos));
+ CHECK_BB(shadow_arg(env, arg->var.vd.tag));
}
return GW_OK;
}
ANN static inline m_bool scan1_fdef_defined(const Env env,
const Func_Def fdef) {
- const Value v = nspc_lookup_value1(env->curr, fdef->base->xid);
+ const Value v = nspc_lookup_value1(env->curr, fdef->base->tag.sym);
if (!v) return GW_OK;
if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable
if(fdef->builtin) return GW_OK;
if ((!env->class_def || !GET_FLAG(env->class_def, final)) &&
- !nspc_lookup_value0(env->curr, fdef->base->xid))
- ERR_B(fdef->base->pos,
+ !nspc_lookup_value0(env->curr, fdef->base->tag.sym))
+ ERR_B(fdef->base->tag.loc,
_("function '%s' has already been defined in the same scope..."),
- s_name(fdef->base->xid))
+ s_name(fdef->base->tag.sym));
return GW_OK;
}
ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) {
if(GET_FLAG(fdef->base, abstract) && !env->class_def)
- ERR_B(fdef->base->pos, "file scope function can't be abstract");
- CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->pos));
+ ERR_B(fdef->base->tag.loc, "file scope function can't be abstract");
+ CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->tag.loc));
CHECK_BB(scan1_fdef_defined(env, fdef));
const bool global = GET_FLAG(fdef->base, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
if (tmpl_base(fdef->base->tmpl)) return scan1_fdef_base_tmpl(env, fdef);
- struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former =
+ struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former =
env->func;
env->func = &fake;
const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef);
env->func = former;
if (global) env_pop(env, scope);
- if ((strcmp(s_name(fdef->base->xid), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
+ if ((strcmp(s_name(fdef->base->tag.sym), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
fdef->base->ret_type != env->gwion->type[et_void] && fdef->d.code &&
!fake.memoize)
- ERR_B(fdef->base->td->pos,
+ ERR_B(fdef->base->td->tag.loc,
_("missing return statement in a non void function"));
- if (fdef->base->xid == insert_symbol("@gack") && !fake.weight) {
+ if (fdef->base->tag.sym == insert_symbol("@gack") && !fake.weight) {
gwerr_basic(_("`@gack` operator does not print anything"), NULL,
- _("use `<<<` `>>>` in the function"), env->name, fdef->base->pos, 0);
+ _("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc, 0);
env_set_error(env, true);
return GW_ERROR;
}
Type t = parent;
do
if (tdef->type == t)
- ERR_O(tdef->ext->pos, _("recursive (%s <= %s) class declaration."),
+ ERR_O(tdef->ext->tag.loc, _("recursive (%s <= %s) class declaration."),
tdef->type->name, t->name)
while ((t = t->info->parent));
return parent;
}
ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
- const loc_t pos = cdef->base.ext->pos;
+ const loc_t pos = cdef->base.ext->tag.loc;
if (cdef->base.ext->array && cdef->base.ext->array->exp)
CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp));
DECL_OB(const Type, parent, = scan1_get_parent(env, &cdef->base));
if (isa(parent, env->gwion->type[et_object]) < 0 &&
- !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
+// !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
+ !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_union)))
ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
if (type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend"))
return GW_OK;
ANN static inline Type scan1_final(const Env env, Type_Decl *td, const bool tdef) {
DECL_OO(const Type, t, = known_type(env, td));
if (!GET_FLAG(t, final) || tdef) return t;
- ERR_O(td->pos, _("can't inherit from final parent class '%s'\n."), t->name);
+ ERR_O(td->tag.loc, _("can't inherit from final parent class '%s'\n."), t->name);
}
ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
}
} else mp_vector_add(mp, &body, Section, section);
}
- Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos);
+ Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.tag.loc);
Symbol sym = insert_symbol("@ctor");
- Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos);
+ Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.tag.loc);
Func_Def fdef = new_func_def(mp, fb, ctor);
mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
free_mp_vector(mp, Section, base);
ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) {
const Type t = decl->type;
CHECK_BB(ensure_scan2(env, t));
- const Var_Decl vd = decl->vd;
- nspc_add_value(env->curr, vd.xid, vd.value);
+ const Var_Decl vd = decl->var.vd;
+ nspc_add_value(env->curr, vd.tag.sym, vd.value);
return GW_OK;
}
ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) {
if(decl->args) CHECK_BB(scan2_exp(env, decl->args));
- const bool global = GET_FLAG(decl->td, global);
+ const bool global = GET_FLAG(decl->var.td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const m_bool ret = scan2_decl(env, decl);
if (global) env_pop(env, scope);
Arg_List args = f->base->args;
for(uint32_t i = 0; i < args->len; i++) {
Arg *arg = mp_vector_at(args, Arg, i);
- const Value v = arg->var_decl.value;
+ const Value v = arg->var.vd.value;
v->from->offset = f->stack_depth;
f->stack_depth += v->type->size;
set_vflag(v, vflag_arg);
const Value overload) {
if (!is_func(env->gwion, overload->type)) {
if (!fbflag(f->base, fbflag_internal))
- ERR_B(f->base->pos,
+ ERR_B(f->base->tag.loc,
_("function name '%s' is already used by another value"),
overload->name)
}
const Func obase = overload->d.func_ref;
if (GET_FLAG(obase->def->base, final) && (!env->class_def || (obase->value_ref->from->owner_class != env->class_def))) {
- env_err(env, f->base->pos, _("can't overload final function `{G}%s{0}`"), s_name(f->base->xid));
+ env_err(env, f->base->tag.loc, _("can't overload final function `{G}%s{0}`"), s_name(f->base->tag.sym));
declared_here(obase->value_ref);
return GW_ERROR;
}
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->base->pos, _("must overload template function with template"))
+ ERR_B(f->base->tag.loc, _("must overload template function with template"))
if (GET_FLAG(f->base, global) != GET_FLAG(obase->def->base, global))
- ERR_B(f->base->pos, _("function is declared global")) // improve me
+ ERR_B(f->base->tag.loc, _("function is declared global")) // improve me
return GW_OK;
}
ANN static void func_no_overload(const Env env, const Func f, const Value v) {
const Type t = v->type;
value_addref(v);
- nspc_add_value_front(env->curr, f->def->base->xid, v);
+ nspc_add_value_front(env->curr, f->def->base->tag.sym, v);
const Type newt = type_copy(env->gwion->mp, t);
t->info->parent = newt;
- newt->name = s_name(f->def->base->xid);
+ newt->name = s_name(f->def->base->tag.sym);
newt->info->func = f;
- nspc_add_type_front(env->curr, f->def->base->xid, newt);
+ nspc_add_type_front(env->curr, f->def->base->tag.sym, newt);
newt->info->value = v;
}
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 = t->info->value = new_value(env, t, t->name, f->def->base->pos);
+ const Value v = t->info->value = new_value(env, t, t->name, f->def->base->tag.loc);
valuefrom(env, v->from);
CHECK_OO(scan2_func_assign(env, f->def, f, v));
if (!overload)
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 m_str name = s_name(f->base->tag.sym);
const Func func = scan_new_func(env, f, name);
const Value value = func_value(env, func, overload);
set_fflag(func, fflag_tmpl);
Nspc nspc = env->curr;
uint i = 0;
do {
- const Value v = nspc_lookup_value0(nspc, f->base->xid);
+ const Value v = nspc_lookup_value0(nspc, f->base->tag.sym);
if (v) {
Func ff = v->d.func_ref;
if (!ff) continue;
}
if (compat_func(ff->def, f) > 0) {
if (ff->value_ref->from->owner == env->curr)
- ERR_B(f->base->pos,
+ ERR_B(f->base->tag.loc,
"template function '%s' already defined with those arguments "
"in this namespace",
name)
const Symbol sym =
func_symbol(env, env->curr->name, name, "template", ff->def->vt_index);
nspc_add_value(env->curr, sym, value);
- if (!overload) nspc_add_value(env->curr, f->base->xid, value);
+ if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value);
nspc_add_func(env->curr, sym, func);
func->def->vt_index = ff->def->vt_index;
return GW_OK;
const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
nspc_add_value(env->curr, sym, value);
nspc_add_func(env->curr, sym, func);
- if (!overload) nspc_add_value(env->curr, f->base->xid, value);
+ if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value);
else func->def->vt_index = ++overload->from->offset;
return GW_OK;
}
ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
- const m_str str = s_name(f->base->xid);
+ const m_str str = s_name(f->base->tag.sym);
struct Op_Func opfunc = {.ck = strcmp(str, "@implicit") ? 0
: opck_usr_implicit};
struct Op_Import opi = {.ret = f->base->ret_type,
- .pos = f->base->pos,
+ .pos = f->base->tag.loc,
.data = (uintptr_t)f->base->func,
.func = &opfunc};
func_operator(f, &opi);
ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
set_fflag(f->base->func, fflag_pure);
- if (f->base->xid == insert_symbol("@dtor"))
+ if (f->base->tag.sym == insert_symbol("@dtor"))
set_tflag(env->class_def, tflag_dtor);
}
ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
- const m_str name = s_name(f->base->xid);
- m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->pos);
+ const m_str name = s_name(f->base->tag.sym);
+ m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->tag.loc);
const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name,
(m_uint)f->vt_index);
return s_name(sym);
ANN2(1, 2)
static m_str func_name(const Env env, const Func_Def f, const Value v) {
if (!f->base->tmpl) {
- const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->xid),
+ const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->tag.sym),
NULL, v ? ++v->from->offset : 0);
return s_name(sym);
}
//! use function from parent class as next.
ANN static void upfunction(const Env env, const Func_Base *fb) {
- const Value v = find_value(env->class_def->info->parent, fb->xid);
+ const Value v = find_value(env->class_def->info->parent, fb->tag.sym);
if (!v) return;
Func func = fb->func;
while (func->next && func->next->value_ref->from->owner == env->curr)
}
ANN m_bool scan2_fdef(const Env env, const Func_Def fdef) {
- const Value overload = nspc_lookup_value2(env->curr, fdef->base->xid);
+ const Value overload = nspc_lookup_value2(env->curr, fdef->base->tag.sym);
if (overload) CHECK_BB(scan2_func_def_overload(env, fdef, overload));
CHECK_BB((!tmpl_base(fdef->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(
env, fdef, overload));
return GW_OK;
if(is_new(fdef)) {
if(!env->class_def)
- ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}"));
+ ERR_B(fdef->base->tag.loc, _("{G+}new{0} operator must be set inside {C+}class{0}"));
SET_FLAG(env->class_def, abstract);
if(!fdef->base->ret_type)
// fdef->base->ret_type = env->class_def;
// or do smth else?
DECL_OB(const Type, t, = known_type(env, targ.d.td));
struct AstGetter_ arg = {env->name, f, env->gwion->st, .ppa = env->gwion->ppa};
- const m_str type = type2str(env->gwion, t, targ.d.td->pos);
- sprintf(c, "%s=%s", s_name(spread->xid), type);
+ const m_str type = type2str(env->gwion, t, targ.d.td->tag.loc);
+ sprintf(c, "%s=%s", s_name(spread->tag.sym), type);
free_mstr(env->gwion->mp, type);
pparg_add(env->gwion->ppa, c);
for(uint32_t j = 0; j < spread->list->len; j++) {
sprintf(c, "%s=%s%u", name, name, i);
pparg_add(env->gwion->ppa, c);
}
- Ast ast = parse_pos(&arg, spread->pos);
- pparg_rem(env->gwion->ppa, s_name(spread->xid));
+ Ast ast = parse_pos(&arg, spread->tag.loc.first);
+ pparg_rem(env->gwion->ppa, s_name(spread->tag.sym));
for(uint32_t j = 0; j < spread->list->len;j++) {
const Symbol sym = *mp_vector_at(spread->list, Symbol, j);
m_str name = s_name(sym);
#include "vm.h"
#include "traverse.h"
#include "template.h"
+#include "tmp_resolve.h"
#include "vm.h"
#include "parse.h"
#include "gwion.h"
Type_List tl = tmpl->call;
Specialized *spec = mp_vector_at(sl, Specialized, sl->len - 1);
- const uint32_t len = strcmp(s_name(spec->xid), "...") ? sl->len : sl->len-1;
+ const uint32_t len = strcmp(s_name(spec->tag.sym), "...") ? sl->len : sl->len-1;
if(!tl) return GW_OK;
for(uint32_t i = 0; i < len; i++) {
if (i >= tl->len) return GW_OK;
if(unlikely(arg.type == tmplarg_exp)) continue;
const Type t = known_type(env, arg.d.td);
Specialized *spec = mp_vector_at(sl, Specialized, i);
- nspc_add_type(nspc, spec->xid, t);
+ nspc_add_type(nspc, spec->tag.sym, t);
};
if(len != sl->len) return GW_OK;
return tl->len == sl->len ? GW_OK : GW_ERROR;
ANN static m_bool _template_push(const Env env, const Type t) {
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->nspc, t->info->cdef->base.tmpl); // incorrect
- return GW_OK;
+ return tflag(t, tflag_tmpl)
+ ? push_types(env, t->nspc, get_tmpl(t))
+ : GW_OK;
}
ANN m_bool template_push(const Env env, const Type t) {
}
#include <ctype.h>
+ANN Exp td2exp(const MemPool mp, const Type_Decl *td);
ANN void check_call(const Env env, const Tmpl *tmpl) {
for(uint32_t i = 0; i < tmpl->call->len; i++) {
Specialized *spec = i < tmpl->list->len
? mp_vector_at(tmpl->list, Specialized, i)
: NULL;
TmplArg *targ = mp_vector_at(tmpl->call, TmplArg, i);
- if(spec && strcmp(s_name(spec->xid), "...")) {
- //spec->is_const) exit(12);
- if(spec->xid == targ->d.td->xid) {
- if (!nspc_lookup_type1(env->curr, spec->xid))
- targ->d.td->xid = insert_symbol("auto");
+//if(targ->type != tmplarg_td) exit(16);
+if(targ->type == tmplarg_td) {
+ if(spec && strcmp(s_name(spec->tag.sym), "...")) {
+if(unlikely(spec->td)) {
+if(targ->type == tmplarg_td) {
+targ->type = tmplarg_exp;
+const Exp exp = td2exp(env->gwion->mp, targ->d.td);
+targ->d.exp = exp;
+
+}
+}
+else if(spec->tag.sym == targ->d.td->tag.sym) {
+ if (!nspc_lookup_type1(env->curr, spec->tag.sym))
+ targ->d.td->tag.sym = insert_symbol("auto");
else {
- const Type t = nspc_lookup_type1(env->curr, spec->xid);
- Type_Decl *td = type2td(env->gwion, t, targ->d.td->pos);
+ const Type t = nspc_lookup_type1(env->curr, spec->tag.sym);
+ Type_Decl *td = type2td(env->gwion, t, targ->d.td->tag.loc);
free_type_decl(env->gwion->mp, targ->d.td);
targ->d.td = td;
}
- }
+ } else { // normal case?r
+//exit(11 + !!spec->xid);
+ }
+}
} else {
//if(targ->type == tmplarg_td)
// targ->d.td->xid = insert_symbol("auto");
}
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));
+ DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->tag.loc));
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 Func_Def def = cpy_func_def(env->gwion->mp, t->info->func->def);
const Func func = ret->info->func =
new_func(env->gwion->mp, s_name(sym), def);
- const Value value = new_value(env, ret, s_name(sym), def->base->pos);
+ const Value value = new_value(env, ret, s_name(sym), def->base->tag.loc);
func->flag = def->base->flag;
if (vflag(t->info->func->value_ref, vflag_member))
set_vflag(value, vflag_member);
static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) {
if (is_func(env->gwion, t) && t->info->func->def->base->tmpl) // is_callable needs type
return scan_func(env, t, td);
- ERR_O(td->pos,
+ ERR_O(td->tag.loc,
_("type '%s' is not template. You should not provide template types"),
t->name)
}
static ANN bool is_single_variadic(const MP_Vector *v) {
if(v->len != 1) return false;
const Specialized *spec = mp_vector_at(v, Specialized, 0);
- return !strcmp(s_name(spec->xid), "...");
+ return !strcmp(s_name(spec->tag.sym), "...");
}
-ANN2(1,2) static m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) {
+ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) {
if (!sl || sl->len > tl->len || (tl->len != sl->len && !is_spread))
ERR_B(pos, "invalid template type number");
for (uint32_t i = 0; i < sl->len; i++) {
TmplArg *arg = mp_vector_at(tl, TmplArg, i);
Specialized *spec = mp_vector_at(sl, Specialized, i);
if(arg->type == tmplarg_td) {
-
- // could be an enum or smth
if(spec->td) {
-
-Type_Decl *base = arg->d.td;
-Type_Decl *next = base;
-Type_Decl *last = next->next;
-while(next && last) {
- if(!last->next) break;
- last = last->next;
- next = next->next;
-}
-
-if(last) {
- next->next = NULL;
-const Type t = known_type(env, base);
-// check no array?
-// no template?
-if(t) {
- arg->type = tmplarg_exp;
- Exp e = new_exp_td(env->gwion->mp, base, base->pos);
- arg->d.exp = new_exp_dot(env->gwion->mp, e, last->xid, base->pos);
-free_type_decl(env->gwion->mp, last);
-// arg->d
-
-//turn into an exp;
-i--;continue;
-}
- next->next = last;
-
-}
-
-//exit(3);
- ERR_B(pos, "template type argument mismatch. expected %s",
- spec->td ? "constant" : "type");
+ Type_Decl *base = arg->d.td;
+ Type_Decl *next = base;
+ Type_Decl *last = next->next;
+ while(next && last) {
+ if(!last->next) break;
+ last = last->next;
+ next = next->next;
+ }
+ if(last) {
+ next->next = NULL;
+ const Type t = known_type(env, base);
+ if(t) {
+ arg->type = tmplarg_exp;
+ Exp e = new_exp_td(env->gwion->mp, base, base->tag.loc);
+ arg->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc);
+ free_type_decl(env->gwion->mp, last);
+ i--;
+ continue;
+ }
+ next->next = last;
+ }
+ ERR_B(pos, "template type argument mismatch. expected %s",
+ spec->td ? "constant" : "type");
}
DECL_OB(const Type, t, = known_type(env, arg->d.td));
}
}
} else {
- if(!spec->td) {
- ERR_B(pos, "template const argument mismatch. expected %s",
- spec->td ? "constant" : "type");
+ if(!spec->td) {
+ ERR_B(pos, "template const argument mismatch. expected %s",
+ spec->td ? "constant" : "type");
}
-
DECL_OB(const Type, t, = known_type(env, spec->td));
-CHECK_OB(check_exp(env, arg->d.exp));
-// DECL_OB(const Type, t, = nspc_lookup_valueh);
-if(isa(arg->d.exp->type,t) < 0)
- ERR_B(pos, "invalid type %s for template argument. expected %s",
- arg->d.exp->type->name, t->name);
-
-// exit(13);
-//puts("we could check here");
+ CHECK_OB(check_exp(env, arg->d.exp));
+ if(isa(arg->d.exp->type, t) < 0)
+ ERR_B(pos, "invalid type %s for template argument. expected %s",
+ arg->d.exp->type->name, t->name);
}
}
return GW_OK;
ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) {
if (tflag(t, tflag_tmpl) && !is_func(env->gwion, t)) { // is_callable
if (tflag(t, tflag_ntmpl) && !td->types) return t;
- const bool single_variadic = is_single_variadic(t->info->cdef->base.tmpl->list);
+ Tmpl *tmpl = get_tmpl(t);
+ const bool single_variadic = is_single_variadic(tmpl->list);
if(!td->types) {
- const Type new_type = nspc_lookup_type1(env->curr, td->xid);
- Type_Decl *new_td = type2td(env->gwion, new_type, td->pos);
+ const Type new_type = nspc_lookup_type1(env->curr, td->tag.sym);
+ Type_Decl *new_td = type2td(env->gwion, new_type, td->tag.loc);
Type_Decl *d = new_td;
while(d->next) d = d->next;
if(!d->types) {
if(!single_variadic)
- ERR_O(td->pos, _("you must provide template types for type '%s'"), t->name);
+ ERR_O(td->tag.loc, _("you must provide template types for type '%s'"), t->name);
d->types = new_mp_vector(env->gwion->mp, TmplArg, 0);
}
const Type ret = _scan_type(env, t, d);
}
struct TemplateScan ts = {.t = t, .td = td};
Type_List tl = td->types;
- Specialized_List sl = t->info->cdef->base.tmpl
- ? t->info->cdef->base.tmpl->list : NULL;
- const bool is_spread = is_spread_tmpl(t->info->cdef->base.tmpl);
- if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->pos, is_spread));
+ Specialized_List sl = tmpl
+ ? tmpl->list : NULL;
+ const bool is_spread = is_spread_tmpl(tmpl);
+ if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->tag.loc, is_spread));
struct Op_Import opi = {.op = insert_symbol("class"),
.lhs = t,
.data = (uintptr_t)&ts,
- .pos = td->pos};
+ .pos = td->tag.loc};
return op_check(env, &opi);
} else if (td->types)
return maybe_func(env, t, td);
const Type owner = array_base_simple(maybe_array);
td->next = next;
CHECK_OO(owner);
- if (!owner->nspc) ERR_O(td->pos, "type '%s' has no namespace", owner->name)
+ if (!owner->nspc) ERR_O(td->tag.loc, "type '%s' has no namespace", owner->name)
struct EnvSet es = {.env = env,
.data = env,
.scope = env->scope->depth,
Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, 1);
TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
mp_vector_set(tl, TmplArg, 0, arg);
- Type_Decl tmp = {
- .xid = insert_symbol("Option"), .types = tl, .pos = td->pos};
+ Type_Decl tmp = { .tag = MK_TAG(insert_symbol("Option"), td->tag.loc), .types = tl };
const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
free_mp_vector(env->gwion->mp, TmplArg, tl);
td->array = array;
Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, 1);
TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
mp_vector_set(tl, TmplArg, 0, arg);
- Type_Decl tmp = {.xid = insert_symbol("Ref"), .types = tl, .pos = td->pos};
+ Type_Decl tmp = {.tag = MK_TAG(insert_symbol("Ref"), td->tag.loc), .types = tl};
const Type t = known_type(env, &tmp);
free_mp_vector(env->gwion->mp, TmplArg, tl);
return t;
text_init(&text, env->gwion->mp);
text_add(&text, "(");
DECL_OO(const Type, t, = known_type(env, base->td));
- DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->pos));
+ DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->tag.loc));
text_add(&text, name);
free_mstr(env->gwion->mp, name);
text_add(&text, "(");
for(uint32_t i = 0; i < base->args->len; i++) {
if(i) text_add(&text, ",");
Arg *arg = mp_vector_at(base->args, Arg, i);
- DECL_OO(const Type, t, = known_type(env, arg->td));
- DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->td->pos));
+ DECL_OO(const Type, t, = known_type(env, arg->var.td));
+ DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->var.td->tag.loc));
text_add(&text, name);
free_mstr(env->gwion->mp, name);
if(*global)
}
text_add(&text, ")");
text_add(&text, ")");
- base->xid = insert_symbol(text.str);
+ base->tag.sym = insert_symbol(text.str);
text_release(&text);
- return base->xid;
+ return base->tag.sym;
}
ANN static inline Type find(const Env env, Type_Decl *td) {
if (!td->fptr) return find_type(env, td);
bool global = false;
- CHECK_OO((td->xid = symname(env, td->fptr->base, &global)));
+ CHECK_OO((td->tag.sym = symname(env, td->fptr->base, &global)));
const Fptr_Def fptr = td->fptr;
td->fptr = NULL;
const Type exists = find_type(env, td);
while (last->next) last = last->next;
DECL_OO(const Type, base, = find(env, td));
const Context ctx = base->info->value->from->ctx;
- if (ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name)
+ if (ctx && ctx->error) ERR_O(td->tag.loc, _("type '%s' is invalid"), base->name)
DECL_OO(const Type, type, = find1(env, base, td));
DECL_OO(const Type, t, = !td->ref ? type : ref(env, td));
DECL_OO(const Type, ret, = !td->option ? t : option(env, td));
}
ANN static inline void *type_unknown(const Env env, const Type_Decl *td) {
- env_err(env, td->pos, _("unknown type '%s'"), s_name(td->xid));
+ env_err(env, td->tag.loc, _("unknown type '%s'"), s_name(td->tag.sym));
return NULL;
}
#include "gwion_ast.h"
#include "gwion_env.h"
#include "vm.h"
-#include "plug.h"
-#include "driver.h"
#include "gwion.h"
static DRVRUN(simple_driver_run) {
-#! [contains] unknown type
+#! [contains] Invalid variable unknown_type
fun void my_function:[A]() { <<< "test" >>>; }
my_function:[unknown_type]();
+#! [contains] can't declare ref type in union
union U {
&int i;
}
-operator int --- :[A,C] (A i, C j) { return i;}
+operator int --- :[A,C] (A i, C j) { var C c; return i;}
<<< 1 --- 2 >>>;
<<< 2 --- 2 >>>;