const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
instr->m_val = v->from->offset;
+ if(GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) && isa(v->type, emit->gwion->type[et_object]) > 0) {
+ const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
+ instr->m_val = -SZ_INT;
+ }
return GW_OK;
}
ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
const Value v = e->d.prim.value;
-printf("base->type %s\n", base->type->name);
v->from->offset = emit_local(emit, base->type);
const Instr instr = emit_add_instr(emit, Reg2Mem4);
instr->m_val = v->from->offset;
CHECK_BO(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(vec, (vtype)instr);
+ return CASE_PASS;
}
ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt,
- const Vector v, struct Match_ *const match) {
+ const Vector v) {
Exp e = stmt->cond;
const Map map = &emit->env->scope->match->map;
for(m_uint i = 0; i < map_size(map) && e; e = e->next, ++i) {
const Symbol op = case_op(emit, base, e, v, 0);
if(op != CASE_PASS)
CHECK_BB(emit_case_head(emit, base, e, op, v))
-else puts("pass");
}
CHECK_BB(emit_case_body(emit, stmt))
return GW_OK;
}
-ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt,
- struct Match_ *match) {
+ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt) {
emit_push_scope(emit);
struct Vector_ v;
vector_init(&v);
- const m_bool ret = _emit_stmt_match_case(emit, stmt, &v, match);
+ const m_bool ret = _emit_stmt_match_case(emit, stmt, &v);
emit_pop_scope(emit);
for(m_uint i = 0; i < vector_size(&v); ++i) {
const Instr instr = (Instr)vector_at(&v, i);
vector_release(vec);
}
-ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list, struct Match_ *match) {
- do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match, match))
+ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list) {
+ do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match))
while((list = list->next));
return GW_OK;
}
CHECK_BB(emit_stmt(emit, stmt->where, 1))
MATCH_INI(emit->env->scope)
vector_init(&m.vec);
- const m_bool ret = emit_stmt_cases(emit, stmt->list, &m);
+ const m_bool ret = emit_stmt_cases(emit, stmt->list);
match_unvec(&m, emit_code_size(emit));
MATCH_END(emit->env->scope)
return ret;
const Array_Sub array = (Array_Sub)data;
const Type t_int = env->gwion->type[et_int];
Exp e = array->exp;
- do CHECK_BO(check_implicit(env, e, t_int))
+ do CHECK_BN(check_implicit(env, e, t_int))
while((e = e->next));
const Type t = array->type->array_depth ? array->type : typedef_base(array->type);
if(t->array_depth >= array->depth)
GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt))
GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le))
GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt))
-/*
+
GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
-*/
+
GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) {
CHECK_BB(fptr_check(env, info))
- CHECK_OB((info->exp->type = fptr_type(env, info)))
+ if(!(info->exp->type = fptr_type(env, info)))
+ ERR_B(info->lhs->def->pos, _("no match found"))
return GW_OK;
}
Exp_Lambda *l = &info->exp->d.exp_lambda;
bin->rhs->type->info->func->def->base->tmpl->call) {
struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->parent->info->func,
bin->lhs, exp_self(bin)->pos };
- CHECK_BO(fptr_do(env, &info))
+ CHECK_BN(fptr_do(env, &info))
exp_setvar(bin->rhs, 1);
return bin->rhs->type;
}
struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->func,
bin->lhs, exp_self(bin)->pos };
- CHECK_BO(fptr_do(env, &info))
+ CHECK_BN(fptr_do(env, &info))
exp_setvar(bin->rhs, 1);
return bin->rhs->type;
}
const Type t = exp_self(cast)->type;
struct FptrInfo info = { cast->exp->type->info->func, t->info->func,
cast->exp, exp_self(cast)->pos };
- CHECK_BO(fptr_do(env, &info))
+ CHECK_BN(fptr_do(env, &info))
return t;
}
struct Implicit *impl = (struct Implicit*)data;
struct FptrInfo info = { impl->e->type->info->func, impl->t->info->func,
impl->e, impl->e->pos };
- CHECK_BO(fptr_do(env, &info))
+ CHECK_BN(fptr_do(env, &info))
return impl->t;
}
const m_bool ret = check_stmt(env, unary->code);
nspc_pop_value(env->gwion->mp, env->curr);
--env->scope->depth;
- CHECK_BO(ret)
+ CHECK_BN(ret)
return env->gwion->type[unary->op == insert_symbol("spork") ? et_shred : et_fork];
}
ERR_O(exp_self(unary)->pos, _("only function calls can be sporked..."))
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, late); // ???
exp_setvar(bin->rhs, 1);
- CHECK_BO(isa(bin->lhs->type , bin->rhs->type))
+ CHECK_BN(isa(bin->lhs->type , bin->rhs->type))
return bin->rhs->type;
}
static OP_CHECK(opck_ptr_assign) {
const Exp_Binary* bin = (Exp_Binary*)data;
- CHECK_BO(ptr_access(env, bin->lhs))
- CHECK_BO(ptr_access(env, bin->rhs))
+ CHECK_BN(ptr_access(env, bin->lhs))
+ CHECK_BN(ptr_access(env, bin->rhs))
exp_setvar(bin->lhs, 1);
exp_setvar(bin->rhs, 1);
Type t = bin->lhs->type;
free_exp(env->gwion->mp, exp_func);
free_exp(env->gwion->mp, exp_args);
e->d.exp_binary.op = insert_symbol(env->gwion->st, "==");
- CHECK_OO(check_exp(env, e))
+ CHECK_ON(check_exp(env, e))
return e->type;
}
}
if(!name || !name->next || name->next->next)
ERR_N(name->pos, "Union constructor takes two arguments, "
"'id' and 'value'")
- if(name->exp_type != ae_exp_primary ||
+ if(name->exp_type != ae_exp_primary ||
name->d.prim.prim_type != ae_prim_id)
return NULL;
const Exp val = name->next;
static INSTR(UnionCtor) {
POP_REG(shred, instr->m_val2);
POP_REG(shred, SZ_INT);
- const Type t = *(Type*)REG(-SZ_INT*2);
const m_uint index = *(m_uint*)REG(-SZ_INT);
const M_Object o = *(M_Object*)REG(-SZ_INT) = new_object(shred->info->vm->gwion->mp, NULL, (Type)instr->m_val);
*(m_uint*)o->data = index;// + 1;
Exp_Call *call = (Exp_Call*)data;
const Type base = actual_type(emit->gwion, call->func->type);
const Instr instr = emit_add_instr(emit, UnionCtor);
- instr->m_val = base;
+ instr->m_val = (m_uint)base;
instr->m_val2 = call->args->next->type->size;
return GW_OK;
}
ANN2(1) static M_Operator* operator_find2(const Vector v, const restrict Type lhs, const restrict Type rhs) {
for(m_uint i = vector_size(v) + 1; --i;) {
M_Operator* mo = (M_Operator*)vector_at(v, i - 1);
- if(lhs == mo->lhs && rhs == mo->rhs)
+ if(mo && lhs == mo->lhs && rhs == mo->rhs)
return mo;
}
return NULL;
return GW_OK;
}
-ANN static Type op_check_inner(struct OpChecker* ock) {
+ANN static Type op_check_inner(struct OpChecker* ock, const uint i) {
Type t, r = ock->opi->rhs;
do {
const M_Operator* mo;
const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op);
- if(v && (mo = operator_find(v, ock->opi->lhs, r))) {
+ if(v && (mo = !i ? operator_find2(v, ock->opi->lhs, r) : operator_find(v, ock->opi->lhs, r))) {
if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data))))
return t;
else
}
ANN Type op_check(const Env env, struct Op_Import* opi) {
+for(int i = 0; i < 2; ++i) {
Nspc nspc = env->curr;
do {
- if(nspc->info->op_map.ptr) {
- Type l = opi->lhs;
- do {
- struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
- struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
- const Type ret = op_check_inner(&ock);
- if(ret) {
- if(ret == env->gwion->type[et_error])
- return NULL;
- return ret;
- }
- } while(l && (l = l->info->parent));
- }
+ if(!nspc->info->op_map.ptr)
+ continue;
+ Type l = opi->lhs;
+ do {
+ struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
+ struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
+ const Type ret = op_check_inner(&ock, i);
+ if(ret) {
+ if(ret == env->gwion->type[et_error])
+ return NULL;
+ return ret;
+ }
+ } while(l && (l = l->info->parent));
} while((nspc = nspc->parent));
+}
if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
return opi->rhs;
if(opi->op == insert_symbol(env->gwion->st, "@func_check"))
}
ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
+ for(int i = 0; i < 2; ++i) {
Nspc nspc = emit->env->class_def ? emit->env->curr : emit->env->context->nspc;
do {
if(!nspc->info->op_map.ptr)continue;
const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
if(!v)
continue;
- const M_Operator* mo = operator_find(v, l, r);
+ const M_Operator* mo = !i ? operator_find2(v, l, r) :operator_find(v, l, r);
if(mo) {
if(mo->em) {
const m_bool ret = mo->em(emit, (void*)opi->data);
} while(r && (r = r->info->parent));
} while(l && (l = l->info->parent));
} while((nspc = nspc->parent));
+ }
return GW_ERROR;
}
t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
add_type(env, env->curr, t);
mk_class(env, t);
- SET_FLAG(t, final | ae_flag_abstract);
+ SET_FLAG(t, final);
+ if(strncmp(t->name, "Option", 6))
+ SET_FLAG(t, abstract);
return t;
}
if(var->array->exp)
CHECK_BB(scan1_exp(env, var->array->exp))
t = array_type(env, decl->type, var->array->depth);
- } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late))
- SET_FLAG(decl->td, late);
+ } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) {
+ ERR_B(var->pos, "Type '%s' is abstract, use late")
+ // SET_FLAG(decl->td, late);
+ }
const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
// rewrite logic
if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))