tflag_contract = 1 << 19,
tflag_float = 1 << 20,
tflag_union = 1 << 21,
+ tflag_error = 1 << 22,
} __attribute__((packed));
struct Type_ {
-Subproject commit f88125defdcc1ea298fae47b02c5c4b87b28ea5d
+Subproject commit ca54364364765ea11af9d121cbdf6aab700aeb19
ANN static void clean_var_decl(Clean *a, Var_Decl b) {
if (b->array) clean_array_sub(a, b->array);
- if (a->scope && b->value) value_remref(b->value, a->gwion);
+ if (a->scope && b->value && !tflag(b->value->type, tflag_error)) value_remref(b->value, a->gwion);
}
ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) {
ANN static Instr emit_struct_decl(const Emitter emit, const Value v,
const bool emit_addr) {
+printf("emit %s\n", v->name);
emit_add_instr(emit, RegPushMem);
const Instr instr = emit_structmember(emit, v->type->size, emit_addr);
if (!emit_addr) {
ANN void unset_local(const Emitter emit, Local *const l) {
l->instr->opcode = eNoOp;
-// l->is_compound = false;
-// l-> = false;
for(m_uint i = m_vector_size(&emit->code->live_values) + 1; --i;) {
VMValue vmval = *(VMValue*)(ARRAY_PTR((&emit->code->live_values)) + (i-1) * sizeof(VMValue));
if(vmval.offset != l->offset) continue;
f_instr *exec = (f_instr *)allocmember;
if (!emit->env->scope->depth) emit_debug(emit, v);
if (!vflag(v, vflag_member)) {
-// v->from->offset = exp_self(decl)->data ? ((Local*)exp_self(decl)->data)->offset : emit_local(emit, type);
v->from->offset = decl_non_static_offset(emit, decl, type);
exec = (f_instr *)(allocword);
if (GET_FLAG(v, late)) { // ref or emit_var ?
return isa(actual_type(gwion, t), gwion->type[et_fptr]) > 0;
}
ANN inline bool is_class(const struct Gwion_ *gwion, const Type t) {
- return isa(t, gwion->type[et_class]) > 0;
+// return isa(t, gwion->type[et_class]) > 0;
+ return t->info->parent == gwion->type[et_class];
}
ANN Type actual_type(const struct Gwion_ *gwion, const Type t) {
#define MAX(a, b) (a >= b ? a : b)
ANN void free_value(Value a, Gwion gwion) {
const Type t = a->type;
-// if(t) {
-
if (t->size > SZ_INT && !vflag(a, vflag_func) && a->d.ptr)
_mp_free(gwion->mp, t->size, a->d.ptr);
else if (is_class(gwion, t))
type_remref(t, gwion);
else if (vflag(a, vflag_inner))
type_remref(t, gwion);
-// }
mp_free(gwion->mp, ValueFrom, a->from);
mp_free(gwion->mp, Value, a);
#define deep_any(_name, _data, action, ACTION, _test, _t, _op) \
static OP_##ACTION(op##action##_deep_##_t##_any) { \
Exp_Binary *bin = data; \
- _test(_name##_exp(_data, bin->lhs)); \
- _test(_name##_exp(_data, bin->rhs)); \
struct Op_Import opi = { \
.lhs = bin->lhs->type, \
.rhs = bin->rhs->type, \
}; \
return op_##_name(_data, &opi); \
}
+static OP_CHECK(opck_deep_eq_any) {
+ Exp_Binary *bin = data;
+ bin->op = insert_symbol(env->gwion->st, "==");
+ DECL_ON(const Type, t, = check_exp(env, exp_self(bin)));
+ return t;
+}
+static OP_CHECK(opck_deep_ne_any) {
+ Exp_Binary *bin = data;
+ bin->op = insert_symbol(env->gwion->st, "!=");
+ const Type t = check_exp(env, exp_self(bin));
+ return !t ? env->gwion->type[et_error] : env->gwion->type[et_bool];
+}
-deep_any(check, env, ck, CHECK, CHECK_ON, eq, ==);
deep_any(emit, emit, em, EMIT, CHECK_BB, eq, ==);
-deep_any(check, env, ck, CHECK, CHECK_ON, ne, !=);
deep_any(emit, emit, em, EMIT, CHECK_BB, ne, !=);
// get members of a specific type
const bool ret = deep_check(env, bin, &l, &r);
vector_release(&l);
vector_release(&r);
- if(ret > 0) return env->gwion->type[et_bool];
+ if(ret) return env->gwion->type[et_bool];
ERR_N(exp_self(bin)->pos, "no deep operation for: {G+/}%s{0} {+}%s{0} {G+/}%s{0}",
bin->lhs->type->name, s_name(bin->op), bin->rhs->type->name);
}
};
static void deep_emits_init(const Emitter emit, struct DeepEmits *ds) {
- emit_add_instr(emit, RegMove)->m_val = -SZ_INT*2;
- deep_emit_init(emit, ds->lhs, 0);
- deep_emit_init(emit, ds->rhs, SZ_INT);
+ emit_add_instr(emit, RegMove)->m_val = -SZ_INT;
+ deep_emit_init(emit, ds->lhs, -SZ_INT);
+ deep_emit_init(emit, ds->rhs, 0);
vector_init(&ds->acc);
}
const Instr branch = (Instr)vector_at(v, i);
branch->m_val = sz;
}
- emit_add_instr(emit, RegMove)->m_val = -SZ_INT;
emit_add_instr(emit, RegSetImm)->m_val2 = -SZ_INT;
}
struct Exp_ rexp = MK_DOT(emit, ds->rhs->tmp, rhs);
struct Exp_ temp = MK_BIN(lexp, rexp, ds->bin);
temp.type=emit->gwion->type[et_bool];
+ if(tflag(lexp.type, tflag_struct))
+ exp_setvar(&lexp, true);
+ if(tflag(rexp.type, tflag_struct))
+ exp_setvar(&rexp, true);
if(emit_exp(emit, &temp) < 0) return false;
vector_add(&ds->acc, (m_uint)emit_add_instr(emit, BranchEqInt));
- const Instr pop = emit_add_instr(emit, RegMove);
- pop->m_val = -SZ_INT;
}
const Instr jmp = emit_add_instr(emit, Goto);
emit_deep_fail(emit, &ds->acc);
static OP_EMIT(opem_uncond_object) {
const Vector v = &emit->code->instr;
- const Instr back = (Instr)vector_at(v, vector_size(v) -2);
- if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) {
- free_instr(emit->gwion, back);
- vector_rem(v, vector_size(v) - 2);
+ if(vector_size(v) >= 2) {
+ const Instr back = (Instr)vector_at(v, vector_size(v) -2);
+ if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) {
+ free_instr(emit->gwion, back);
+ vector_rem(v, vector_size(v) - 2);
+ }
}
emit_add_instr(emit, BranchNeqInt);
return GW_OK;
static OP_EMIT(opem_cond_object) {
const Vector v = &emit->code->instr;
- const Instr back = (Instr)vector_at(v, vector_size(v) -2);
- if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) {
- free_instr(emit->gwion, back);
- vector_rem(v, vector_size(v) - 2);
+ printf("size %lu\n", vector_size(v));
+ if(vector_size(v) >= 2) {
+ const Instr back = (Instr)vector_at(v, vector_size(v) -2);
+ if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) {
+ free_instr(emit->gwion, back);
+ vector_rem(v, vector_size(v) - 2);
+ }
}
emit_add_instr(emit, BranchEqInt);
return GW_OK;
ANN static Type check_exp_td(const Env env, Type_Decl **td) {
DECL_OO(const Type, t, = known_type(env, *td));
+ if(t == env->gwion->type[et_class])
+ ERR_O(exp_self(td)->pos, "can't use {G+}Class{0} in type decl expression");
if (!is_func(env->gwion, t) || is_fptr(env->gwion, t))
return type_class(env->gwion, t);
return t;
e->next = next;
CHECK_OB(t);
Exp_Binary bin = {.lhs = base, .rhs = e, .op = op};
- struct Exp_ ebin = {.d = {.exp_binary = bin}};
+ struct Exp_ ebin = {.d = {.exp_binary = bin}, .exp_type = ae_exp_binary};
struct Op_Import opi = {.op = op,
.lhs = base->type,
.rhs = e->type,
}
ANN static inline bool type_is_recurs(const Type t, const Type tgt) {
+// if(tflag(tgt, tflag_union)) return false;
return isa(tgt, t) > 0 || isa(t, tgt) > 0 || (tgt->info->tuple && vector_find(&tgt->info->tuple->contains, (m_uint)t) > -1);
}
type_remref(first, env->gwion);
if(second->ref > 2)
type_remref(second, env->gwion);
- if(tgt != t && v->type == tgt && strncmp(tgt->name, "Option:[", 8))
- recursive_type_base(env, tgt);
+ if(v->from->owner_class->ref > 2)
+ type_remref(v->from->owner_class, env->gwion);
+ if(t->ref > 2)
+ type_remref(t, env->gwion);
}
+ set_tflag(t, tflag_error);
set_tflag(t, tflag_infer);
set_tflag(tgt, tflag_infer);
unset_tflag(t, tflag_check);
unset_tflag(tgt, tflag_check);
return true;
}
- if(v->type->nspc && !GET_FLAG(v, late) &&
+
+ if(t != tgt && v->type->nspc && !GET_FLAG(v, late) && strncmp(tgt->name, "Option:[", 8) &&
isa(tgt, env->gwion->type[et_compound]) > 0)
return recursive_type(env, t, tgt);
+
return false;
}
struct scope_iter inner = {tgt->nspc->info->value, 0, 0};
bool error = false;
while (scope_iter(&inner, &v) > 0) {
- if(!GET_FLAG(v, late) && recursive_value(env, t, v)) {
+ if(!GET_FLAG(v, late) && v->type != tgt && recursive_value(env, t, v)) {
error = true;
}
}
while (scope_iter(&iter, &value) > 0) {
if (isa(value->type, env->gwion->type[et_compound]) < 0) continue;
if (value->type->nspc && !GET_FLAG(value, late)) {
- if(recursive_type(env, t, value->type)) {
+ if(/*value->type != t && */recursive_type(env, t, value->type)) {
env_err(env, value->from->loc, _("recursive type"));
gw_err("use {+G}late{0} on one (or more) of the variables?\n");
error = true;
const Context ctx = base->info->value->from->ctx;
if (ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name)
DECL_OO(const Type, type, = find1(env, base, td));
- const Type t = !td->ref ? type : ref(env, td);
- const Type ret = !td->option ? t : option(env, td);
+ DECL_OO(const Type, t, = !td->ref ? type : ref(env, td));
+ DECL_OO(const Type, ret, = !td->option ? t : option(env, td));
const Array_Sub array = last->array;
return !array ? ret : array_type(env, ret, array->depth);
}