-Subproject commit 4a237db7d547d5b132ffcdb4489ed67126e67e69
+Subproject commit bf2ac162a45d024461ed046fb4af500566a10f54
ANN static inline bool is_static_call(const Gwion gwion, Exp* e) {
if (e->exp_type != ae_exp_dot) return true;
const Exp_Dot *member = &e->d.exp_dot;
- if(unlikely(!strcmp(s_name(member->xid), "new"))) return true;
+ if(unlikely(!strcmp(s_name(member->tag.sym), "new"))) return true;
return GET_FLAG(e->type, final) ||
GET_FLAG(member->base->type, final) ||
is_class(gwion, member->base->type) ||
clean_type_decl(a, *b);
}
+ANN static void clean_exp_named(Clean *a, Exp_Named *b) {
+ clean_exp(a, b->exp);
+}
+
DECL_EXP_FUNC(clean, void, Clean *)
ANN static void clean_exp(Clean *a, Exp* b) {
clean_exp_func[b->exp_type](a, &b->d);
#include "match.h"
#include "specialid.h"
#include "looper.h"
-#include "shreduler_private.h"
#undef insert_symbol
#define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
return true;
}
+ANN static bool emit_exp_named(const Emitter emit, Exp_Named *exp) {
+// gw_out("these should be changed in verify pass");
+ return emit_exp(emit, exp->exp);
+}
DECL_EXP_FUNC(emit, bool, Emitter)
-ANN2(1) /*static */ bool emit_exp(const Emitter emit, /* const */ Exp* e) {
+ANN2(1) bool emit_exp(const Emitter emit, /* const */ Exp* e) {
Exp* exp = e;
do {
if (emit->info->debug){
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);
+ base = new_exp_dot(mp, base, next->tag, td->tag.loc);
next = next->next;
}
return base;
ANEW ANN m_str tl2str(const Gwion gwion, const TmplArg_List tl,
const loc_t loc NUSED) {
- struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa};
+ struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa, .color=false};
gwfmt_state_init(&ls);
text_init(&ls.text, gwion->mp);
Gwfmt gwfmter = {.mp = gwion->mp, .st = gwion->st, .ls = &ls, .line = 1, .last = cht_nl };
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
#include "gwion_util.h"
#include "gwion_ast.h"
#include "gwion_env.h"
#include "operator.h"
#include "import.h"
#include "gwi.h"
-#include "mpool.h"
-#include "specialid.h"
ANN static Type _get_type(const Gwi gwi, const m_str s) {
if (s == (m_str)OP_ANY_TYPE) return OP_ANY_TYPE;
const Type lhs = gwi_get_type(gwi, op->lhs), rhs = gwi_get_type(gwi, op->rhs),
ret = gwi_get_type(gwi, op->ret);
const struct Op_Func opfunc = {
- .ck = op->ck, .em = op->em, .effect = {.ptr = op->effect.ptr}};
+ .ck = op->ck, .em = op->em,
+ .effect = {.ptr = op->effect.ptr}};
const struct Op_Import opi = {.lhs = lhs,
.rhs = rhs,
.ret = ret,
return true;
}
-ANN bool gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void *)) {
+ANN bool gwi_oper_add(const Gwi gwi, const opck ck) {
gwi->oper->ck = ck;
return true;
}
exp_setvar(e, true);
}
-#define MK_DOT(_data, _exp, _value) \
- { \
- .d = { \
- .exp_dot = { \
- .base = _exp, \
- .xid = insert_symbol(_data->gwion->st, _value->name) \
- } \
- }, \
- .type = _value->type, \
- .exp_type = ae_exp_dot, \
- .loc = _exp->loc \
+#define MK_DOT(_data, _exp, _value) \
+ { \
+ .d = { \
+ .exp_dot = { \
+ .base = _exp, \
+ .tag = { \
+ .sym = insert_symbol(_data->gwion->st, _value->name), \
+ .loc = _exp->loc \
+ } \
+ } \
+ }, \
+ .type = _value->type, \
+ .exp_type = ae_exp_dot, \
+ .loc = _exp->loc \
}
#define MK_BIN(_lhs, _rhs, _bin) \
ANN static inline Value get_value(const Env env, const Exp_Dot *member,
const Type t) {
- const Value value = find_value(t, member->xid);
+ const Value value = find_value(t, member->tag.sym);
if (value)
return value;
if (env->func && env->func->def->base->values)
- return upvalues_lookup(env->func->def->base->values, member->xid);
+ return upvalues_lookup(env->func->def->base->values, member->tag.sym);
if(t->info->values)
- return (Value)scope_lookup1(t->info->values, (m_uint)member->xid);
+ return (Value)scope_lookup1(t->info->values, (m_uint)member->tag.sym);
return NULL;
}
OP_CHECK(opck_object_dot) {
Exp_Dot *const member = (Exp_Dot *)data;
Exp* self = exp_self(member);
- const m_str str = s_name(member->xid);
+ const m_str str = s_name(member->tag.sym);
const bool base_static = is_class(env->gwion, member->base->type);
const Type the_base =
base_static ? _class_base(member->base->type) : member->base->type;
const Value value = get_value(env, member, the_base);
if (!value) {
- const Value v = nspc_lookup_value1(env->curr, member->xid);
+ const Value v = nspc_lookup_value1(env->curr, member->tag.sym);
if(v) {
if (self->is_call) {
if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class))) // is_callable needs type
return v->type;
}
}
- env_err(env, self->loc, _("class '%s' has no member '%s'"),
+ env_err(env, member->tag.loc, _("class '%s' has no member '%s'"),
the_base->name, str);
if (member->base->type->nspc) did_you_mean_type(the_base, str);
return env->gwion->type[et_error];
OP_EMIT(opem_object_dot) {
const Exp_Dot *member = (Exp_Dot *)data;
const Type t_base = member_type(emit->gwion, member->base->type);
- const Value value = find_value(t_base, member->xid);
+ const Value value = find_value(t_base, member->tag.sym);
if (is_class(emit->gwion, value->type)) {
emit_pushimm(emit, (m_uint)value->type);
return true;
const Exp_Binary *bin = (Exp_Binary *)data;
if (opck_const_rhs(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
- exp_setvar(bin->rhs, 1);
+ exp_setvar(bin->rhs, true);
return bin->rhs->type;
}
Exp* args = cpy_exp(env->gwion->mp, unary->ctor.exp);
Exp* base = new_exp_unary2(env->gwion->mp, unary->op, unary->ctor.td, unary->ctor.exp, self->loc);
base->type = t;
- Exp* func = new_exp_dot(env->gwion->mp, base, insert_symbol("new"), self->loc);
+ Exp* func = new_exp_dot(env->gwion->mp, base, MK_TAG(insert_symbol("new"), self->loc), self->loc);
self->d.exp_call.func = func;
self->d.exp_call.args = args;
self->d.exp_call.tmpl = NULL;
static OP_CHECK(opck_now) {
const Exp_Binary *bin = (Exp_Binary *)data;
if (!is_now(env, bin->rhs)) CHECK_NN(opck_const_rhs(env, data));
- exp_setvar(bin->rhs, 1);
+ exp_setvar(bin->rhs, true);
return bin->rhs->type;
}
Exp* exp = exp_self(data);
Exp* func = cpy_exp(mp, exp);
- Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, insert_symbol(env->gwion->st, "last"), func->loc);
+ Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, MK_TAG(insert_symbol(env->gwion->st, "last"), func->loc), func->loc);
Exp* call = new_exp_call(mp, dot, NULL, func->loc);
func->d.exp_binary.lhs = call;
func->d.exp_binary.op = chuck;
// probs exosts already
*(m_uint*)REG(-SZ_INT) = **(m_uint**)REG(-SZ_INT);
}
+
+static bool needs_reset(const Env env, const Exp *base) {
+ return base->cast_to
+// && isa(base->cast_t
+ && strcmp(*(m_str*)base->cast_to->nspc->class_data, env->curr->name);
+}
+
+// TODO: put in header, check other uses
+OP_CHECK(opck_object_dot);
+
+OP_EMIT(opem_setunion_implicit) { exit(19);}
+
+OP_CHECK(opck_setunion_class) {
+ struct TemplateScan *ts = (struct TemplateScan *)data;
+ const Type base = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td);
+ const m_str name = mp_vector_at(ts->td->types, TmplArg, 1)->d.exp->d.prim.d.string.data;
+ char buf[256];
+ snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]",
+ base->name, name, env->curr->name); // vector_at 1
+ const Type t = type_copy(env->gwion->mp, base);
+ t->name = s_name(insert_symbol(env->gwion->st, buf));
+ t->info->parent = ts->t; // check if not set by copy
+ t->info->base_type = base;
+ t->nspc = new_nspc(env->gwion->mp, t->name);
+ t->nspc->class_data_size = 16;
+ nspc_allocdata(env->gwion->mp, t->nspc);
+ *(m_str*)t->nspc->class_data = s_name(insert_symbol(env->gwion->st, name));
+ *(m_str*)(t->nspc->class_data+SZ_INT) = s_name(insert_symbol(env->gwion->st, env->name));
+ return t;
+}
+
+OP_CHECK(opck_setunion_implicit) {
+ exit(87);
+}
+
+static Value find_dot_value(const Env env, const Exp *exp) {
+// if(exp->exp_type == ae_exp_dot)
+// return find_dot_value(
+ if(exp->exp_type == ae_exp_primary && exp->d.prim.prim_type == ae_prim_id)
+ return nspc_lookup_value1(env->curr, exp->d.prim.d.var);
+ return NULL;
+}
+
+static OP_CHECK(opck_setunion_dot) {
+ const Exp_Dot *member = (Exp_Dot *)data;
+ const Type set_t = member->base->type;
+ const Type t = member->base->type->info->base_type;
+ member->base->type = t;
+ const Type ret = opck_object_dot(env, data);
+ member->base->type = set_t;
+ return ret;
+}
+
+static OP_CHECK(opck_setunion_dot2) {
+ puts(__func__);
+ const Exp_Dot *member = (Exp_Dot *)data;
+ puts(member->base->type->name);
+ const m_str name = *(m_str*)member->base->type->nspc->class_data;
+ if(!exp_getvar(exp_self(member)) && strcmp(s_name(member->tag.sym), name)) {
+ // change member->base->loc to member->tag.loc
+ char buf[256];
+ sprintf(buf, "expected {G}%s{0}", name);
+ gwlog_error("invalid union access", buf, env->name, member->base->loc, 0);
+ return env->gwion->type[et_error];
+ }
+ member->base->type = member->base->type->info->base_type;
+ return exp_self(member)->type;
+}
+
+static OP_CHECK(opck_union_dot) {
+ const Exp_Dot *member = (Exp_Dot *)data;
+ find_dot_value(env, member->base);
+ DECL_NN(const Type, ret, = opck_object_dot(env, data));
+/*
+ char buf[256];
+ snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]",
+ member->base->type->name, s_name(member->xid), env->curr->name);
+ const Value v = find_dot_value(env, member->base);
+ if(v)
+ v->type = str2type(env->gwion, buf, member->base->loc);
+*/
+ return ret;
+}
+
static OP_EMIT(opem_union_dot) {
const Exp_Dot *member = (Exp_Dot *)data;
- const Map map = &member->base->type->nspc->info->value->map;
exp_setvar(member->base, true);
CHECK_B(emit_exp(emit, member->base));
if (is_func(emit->gwion, exp_self(member)->type)) { // is_callable? can only be a func
emit_pushimm(emit, (m_uint)exp_self(member)->type->info->func->code);
return true;
}
- if (!strcmp(s_name(member->xid), "index")) {
- //emit_add_instr(emit, DotMember);
+ if (!strcmp(s_name(member->tag.sym), "index")) {
emit_add_instr(emit, UnionIndex);
return true;
}
+ const Map map = &member->base->type->nspc->info->value->map;
for (m_uint i = 0; i < map_size(map); ++i) {
- if (VKEY(map, i) == (m_uint)member->xid) {
+ if (VKEY(map, i) == (m_uint)member->tag.sym) {
const Value v = (Value)VVAL(map, i);
const uint emit_addr = exp_getvar(exp_self(member));
emit_unionmember(emit, i, v->type->size, emit_addr);
Exp* exp_args = call->args;
e->exp_type = ae_exp_binary;
e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func);
- e->d.exp_binary.lhs->d.exp_dot.xid =
+ e->d.exp_binary.lhs->d.exp_dot.tag.sym =
insert_symbol(env->gwion->st, "index");
// e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, e->loc);
e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i, e->loc);
exp->d.exp_dot.base = base;
base->d.prim.value = v->from->owner_class->info->value;
// base->type = v->from->owner_class;
- exp->d.exp_dot.xid = *data;
+ exp->d.exp_dot.tag.sym = *data;
return check_exp(env, exp);
}
exp->exp_type = ae_exp_dot;
Type_Decl *td = cpy_type_decl(env->gwion->mp, using->d.td);
exp->d.exp_dot.base = new_exp_td(env->gwion->mp, td, exp->loc);
- exp->d.exp_dot.xid = insert_symbol(value->name);
+ exp->d.exp_dot.tag.sym = insert_symbol(value->name);
return check_exp(env, exp);
}
} else if(sym == using->tag.sym) {
call->args = this;
call->func->type = v->type;
call->func->d.prim.value = v;
- call->func->d.prim.d.var = call->func->d.exp_dot.xid;
+ call->func->d.prim.d.var = call->func->d.exp_dot.tag.sym;
call->func->exp_type = ae_exp_primary;
call->func->d.prim.prim_type = ae_prim_id;
CHECK_O(check_exp_call(env, call));
return NULL;
}
-ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
+static ANN Func find_func_match_normal(const Env env, const Func up, Exp_Call *const call) {
Func func;
Exp* exp = call->args;
Exp* args =
: NULL;
}
+ANN bool call_has_named_args(Exp_Call *call, uint32_t *nargs) {
+ Exp *exp = call->args;
+ bool ret = false;
+ do {
+ if(exp->exp_type == ae_exp_named)
+ ret = true;
+ (*nargs)++;
+ } while ((exp = exp->next));
+ return ret;
+}
+
+struct NamedChecker {
+ MP_Vector *call_list;
+ MP_Vector *named;
+ MP_Vector *unnamed;
+ uint32_t nargs;
+};
+
+static ANN Func __find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) {
+ const MP_Vector *args = up->def->base->args;
+ if(!args || nc->nargs != args->len) {
+ return NULL;
+ }
+
+ uint32_t nnamed = 0;
+ uint32_t nunnamed = 0;
+ for(uint32_t i = 0; i < args->len; i++) {
+ bool found = false;
+ Arg *arg = mp_vector_at(args, Arg, i);
+ for(uint32_t j = 0; j < nc->named->len; j++) {
+ Exp *exp = *mp_vector_at(nc->named, Exp*, j);
+ if(arg->var.vd.tag.sym == exp->d.exp_named.tag.sym) {
+ mp_vector_set(nc->call_list, Exp*, i, exp);
+ nnamed++;
+ found = true;
+ break;
+ }
+ }
+ if(!found && nunnamed < nc->unnamed->len)
+ mp_vector_set(nc->call_list, Exp*, i, *mp_vector_at(nc->unnamed, Exp*,nunnamed++));
+ }
+ if((nunnamed + nnamed) != nc->nargs) return NULL;
+ for(uint32_t i = 1; i < nc->call_list->len; i++) {
+ (*mp_vector_at(nc->call_list, Exp*, i-1))->next =
+ *mp_vector_at(nc->call_list, Exp*, i);
+ }
+ (*mp_vector_at(nc->call_list, Exp*, nc->call_list->len-1))->next = NULL;
+ call->args = *mp_vector_at(nc->call_list, Exp*, 0);
+ return find_func_match_normal(env, up, call);
+}
+
+static ANN Func _find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) {
+ Func ret = __find_func_match_named(env, up, call, nc);
+ if(ret) return ret;
+ if(!up->next) return NULL;
+ return _find_func_match_named(env, up->next, call, nc);
+}
+
+static ANN Func find_func_match_named(const Env env, const Func up, Exp_Call *const call, const uint32_t nargs) {
+ struct NamedChecker nc = {
+ .call_list = new_mp_vector(env->gwion->mp, Exp*, nargs),
+ .named = new_mp_vector(env->gwion->mp, Exp*, 0),
+ .unnamed = new_mp_vector(env->gwion->mp, Exp*, 0),
+ .nargs = nargs,
+ };
+ MP_Vector *arg_list = new_mp_vector(env->gwion->mp, Exp*, nargs);
+ Exp *exp = call->args;
+ uint32_t i = 0;
+ do {
+ mp_vector_set(arg_list, Exp*, i, exp);
+ if(exp->exp_type == ae_exp_named) {
+ exp->d.exp_named.is_arg = true;
+ mp_vector_add(env->gwion->mp, &nc.named, Exp*, exp);
+ } else
+ mp_vector_add(env->gwion->mp, &nc.unnamed, Exp*, exp);
+ i++;
+ } while((exp = exp->next));
+
+ const Func ret = _find_func_match_named(env, up, call, &nc);
+
+ if(!ret) {
+ for(uint32_t i = 1; i < arg_list->len; i++) {
+ (*mp_vector_at(arg_list, Exp*, i-1))->next =
+ *mp_vector_at(arg_list, Exp*, i);
+ }
+ (*mp_vector_at(arg_list, Exp*, arg_list->len-1))->next = NULL;
+ call->args = (*mp_vector_at(arg_list, Exp*, 0));
+ }
+
+ free_mp_vector(env->gwion->mp, Exp*, arg_list);
+ free_mp_vector(env->gwion->mp, Exp*, nc.call_list);
+ free_mp_vector(env->gwion->mp, Exp*, nc.named);
+ free_mp_vector(env->gwion->mp, Exp*, nc.unnamed);
+
+ return ret;
+}
+
+ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
+ uint32_t nargs = 0;
+ if(!call->args || !call_has_named_args(call, &nargs))
+ return find_func_match_normal(env, up, call);
+ return find_func_match_named(env, up, call, nargs);
+}
+
ANN bool check_traverse_fdef(const Env env, const Func_Def fdef) {
struct Vector_ v = {};
const m_uint scope = env->scope->depth;
}
ANN static void print_current_args(Exp* e) {
- do gw_err(" {G}%s{0}", e->type ? e->type->name : "<Unknown>");
- while ((e = next_arg_exp(e)));
+ do {
+ if (e->exp_type == ae_exp_named)
+ gw_err(" {B}%s{0} =", s_name(e->d.exp_named.tag.sym));
+ gw_err(" {G}%s{0}", e->type ? e->type->name : "<Unknown>");
+ } while ((e = next_arg_exp(e)));
gw_err("\n");
}
return NULL;
}
-ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
+static ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
DECL_O(const Type, t, = call_type(env, exp));
if (t == env->gwion->type[et_op]) return check_op_call(env, exp);
if (!t->info->func) // TODO: effects?
bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
// allow foo => new C to mean new C(foo)
+ // do we actually still need that?
if(bin->op == insert_symbol("=>") &&
bin->rhs->exp_type == ae_exp_unary && bin->rhs->d.exp_unary.unary_type == unary_td &&
!bin->rhs->d.exp_unary.ctor.td->array &&
return t;
}
+ANN static Type check_exp_named(const Env env, Exp_Named *exp_named) {
+ return check_exp(env, exp_named->exp);
+}
DECL_EXP_FUNC(check, Type, Env)
ANN Type check_exp(const Env env, Exp* exp) {
CHECK_B(op_exist(&ock, n));
}
} while ((n = n->parent));
- // Nspc nspc = gwion->env->context
- // ? gwion->env->context->nspc
- // : gwion->env->curr;
const Nspc nspc = get_nspc(gwion->env);
if (!nspc->operators)
nspc->operators = mp_calloc(gwion->mp, NspcOp);
ock->opi->lhs, r)
: operator_find((Vector)&VVAL(ock->map, idx),
ock->opi->lhs, r))) {
- if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) {
+ if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) {
ock->effect.ptr = mo->effect.ptr;
return t;
} else
return NULL;
}
+// TODO: maybe should return M_Operator*?
ANN void* op_get(const Env env, struct Op_Import *opi) {
for (int i = 0; i < 2; ++i) {
Nspc nspc = env->curr;
}
ANN bool operator_set_func(const Env env, const struct Op_Import *opi) {
- //const Nspc nspc = ((Func)opi->data)->value_ref->from->owner;
- //const Nspc nspc = ((Func)opi->data)->value_ref->from->ctx->nspc;
const Nspc nspc = get_nspc(env);
const m_int idx = map_index(&nspc->operators->map, (vtype)opi->op);
const Vector v = (Vector)&VVAL(&nspc->operators->map, idx);
ANN bool scan0_union_def(const Env env, const Union_Def udef) {
bool global = false;
+ bool ok = true;
CHECK_B(scan0_global(env, udef->flag, udef->tag.loc, &global));
CHECK_B(scan0_defined(env, udef->tag));
udef->type = union_type(env, udef->tag.sym, udef->tag.loc);
if (udef->tmpl) union_tmpl(env, udef);
if (global) env_pop(env, 0);
set_tflag(udef->type, tflag_scan0);
- return true;
+ return ok;
}
ANN static inline void cdef_flag(const Class_Def cdef, const Type t) {
SET_FLAG(v, global);
else if(env->context)
set_vflag(v, vflag_fglobal); // file global
- } else if (GET_FLAG(decl->var.td, global))
+ } else if (GET_FLAG(decl->var.td, global)) // wait we can have globals in a scope ?
SET_FLAG(v, global);
nspc_add_value(env->curr, vd->tag.sym, v);
((Exp_Decl *)decl)->type = decl->var.vd.value->type;
#define scan1_exp_lambda dummy_func
#define scan1_exp_td dummy_func
+
+ANN static bool scan1_exp_named(const Env env, Exp_Named *named) {
+ return scan1_exp(env, named->exp);
+}
+
HANDLE_EXP_FUNC(scan1, bool, Env)
ANN static inline bool _scan1_stmt_match_case(const restrict Env env,
return stmt->val ? scan1_exp(env, stmt->val) : 1;
}
+ANN static void enum_value(const Env env, const Enum_Def edef,
+ const Tag tag, const m_int value, m_int *last) {
+ const Value v = new_value(env, edef->type, tag);
+ v->d.num = value;
+ *last = v->d.num + 1;
+ valuefrom(env, v->from);
+ nspc_add_value(env->curr, tag.sym, v);
+ SET_FLAG(v, static | ae_flag_const);
+ SET_ACCESS(edef, v)
+ SET_ACCESS(edef, edef->type)
+ set_vflag(v, vflag_builtin);
+}
+
ANN bool scan1_enum_def(const Env env, const Enum_Def edef) {
const Type t = edef->type;
t->nspc = new_nspc(env->gwion->mp, t->name);
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, ev.tag);
- v->d.num = (ev.set ? ev.gwint.num : last);
- last = v->d.num + 1;
- valuefrom(env, v->from);
- nspc_add_value(env->curr, ev.tag.sym, v);
- SET_FLAG(v, static | ae_flag_const);
- SET_ACCESS(edef, v)
- SET_ACCESS(edef, t)
- set_vflag(v, vflag_builtin);
+ CHECK_B(can_define(env, ev.tag.sym, ev.tag.loc));
+ const m_int value = !ev.set
+ ? last
+ : ev.gwint.num;
+ enum_value(env, edef, ev.tag, value, &last);
}
env_pop(env, scope);
return true;
ANN static inline bool scan1_union_def_inner_loop(const Env env,
Union_Def udef) {
- nspc_allocdata(env->gwion->mp, udef->type->nspc);
- Variable_List l = udef->l;
m_uint sz = 0;
- const Symbol sym = insert_symbol("@index");
- const Value v = new_value(env, env->gwion->type[et_int], MK_TAG(sym, udef->tag.loc));
- nspc_add_value_front(env->curr, sym, v);
- valuefrom(env, v->from);
bool ok = true;
+ Variable_List l = udef->l;
for(uint32_t i = 0; i < l->len; i++) {
Variable *um = mp_vector_at(l, Variable, i);
if (nspc_lookup_value0(env->curr, um->vd.tag.sym)) {
+ // TODO: use already_declared
ERR_OK(ok, um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym));
continue;
}
}
// return
// check for previous errors?
-cdef->base.type->error = !env_body(env, cdef, scan1_section);
-return true;
+ cdef->base.type->error = !env_body(env, cdef, scan1_section);
+ return true;
}
ANN static bool scan1_class_tmpl(const Env env, const Class_Def c) {
RET_NSPC(_scan2_stmt_match(env, stmt))
}
+ANN static bool scan2_exp_named(const Env env, Exp_Named *named) {
+ return scan2_exp(env, named->exp);
+}
+
#define scan2_exp_lambda dummy_func
#define scan2_exp_td dummy_func
HANDLE_EXP_FUNC(scan2, bool, Env)
if(t) {
targ->type = tmplarg_exp;
Exp* e = new_exp_td(env->gwion->mp, base, base->tag.loc);
- targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc);
+ targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag, base->tag.loc);
free_type_decl(env->gwion->mp, last);
i--;
continue;
return validate_type_decl(a, b);
}
+ANN static bool validate_exp_named(Validate *a, Exp_Named *b) {
+ if(!b->is_arg) {
+ env_err(a->env, exp_self(b)->loc, "named expression not in a function call");
+ return false;
+ }
+ return validate_exp(a, b->exp);
+}
+
DECL_EXP_FUNC(validate, bool, Validate*)
ANN static bool validate_exp(Validate *a, Exp* b) {
bool ret = true;
SymTable *st = sema->st;
Exp* dbase = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc);
const Symbol sym = insert_symbol(st, "new");
- Exp* func = new_exp_dot(p, dbase, sym, base->tag.loc);
+ Exp* func = new_exp_dot(p, dbase, MK_TAG(sym, base->tag.loc), base->tag.loc);
return code(p, func, base->args, max, ae_stmt_exp);
}
return type_decl_array_empty(a, b, "in `type declaration` expression");
}
+ANN static bool sema_exp_named(Sema *a, Exp_Named *b) {
+ return sema_exp(a, b->exp);
+}
+
DECL_EXP_FUNC(sema, bool, Sema*)
ANN static bool sema_exp(Sema *a, Exp* b) {
bool ok = sema_exp_func[b->exp_type](a, &b->d);
MP_Vector *result = new_mp_vector(a->mp, Stmt, base->len + stmt_list->len - 1);
// store the first part of the list in it
// TODO: use memcpy
- // or berrer, use the above function to just start at part two
+ // or better, use the above function to just start at part two
for(uint32_t i = 0; i < index; i++) {
Stmt stmt = *mp_vector_at(base, Stmt, i);
mp_vector_set(result, Stmt, i, stmt);
// TODO: rename l
ANN static bool sema_union_def(Sema *a, Union_Def b) {
+ if(!b->l->len) {
+ gwlog_error(_("unions can't be empty"), NULL,
+ a->filename, b->tag.loc, 0);
+ return false;
+ }
bool ok = true;
for(uint32_t i = 0; i < b->l->len; i++) {
Variable *c = mp_vector_at(b->l, Variable, i);