From c23c41b22de65de71700ae2156afad856c54a86d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Fri, 23 Apr 2021 19:02:29 +0200 Subject: [PATCH] :art: Operator effects --- include/import/checker.h | 1 + include/import/oper.h | 2 +- include/operator.h | 1 + opcode.txt | 1 + src/import/import_oper.c | 8 +++++++- src/lib/prim.c | 7 +++++++ src/parse/check.c | 2 +- src/parse/operator.c | 10 ++++++++-- 8 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/import/checker.h b/include/import/checker.h index b0389e30..1b400298 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -42,6 +42,7 @@ typedef struct OperCK { // name_checker ? m_bool (*em)(Emitter, void*); // oper m_str lhs;// oper m_str rhs;// oper + struct Vector_ effect; } OperCK; ANN void func_checker_clean(const Gwi gwi, struct ImportCK *ck); diff --git a/include/import/oper.h b/include/import/oper.h index cf5bedcf..f7514865 100644 --- a/include/import/oper.h +++ b/include/import/oper.h @@ -6,7 +6,7 @@ ANN m_int gwi_oper_add(const Gwi gwi, const opck); ANN m_int gwi_oper_emi(const Gwi gwi, const opem); ANN2(1) m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f); ANN m_int gwi_oper_cond(const Gwi, const m_str, const f_instr, const f_instr); - +ANN void gwi_oper_eff(const Gwi gwi, const m_str effect); #define _EQUALITY_OPER(sz, sign) \ POP_REG(shred, sz*2 - SZ_INT); \ *(m_uint*)REG(-SZ_INT) = sign \ diff --git a/include/operator.h b/include/operator.h index d7cb2566..585c4185 100644 --- a/include/operator.h +++ b/include/operator.h @@ -18,6 +18,7 @@ typedef m_bool (*opem)(const Emitter, void*); struct Op_Func { opck ck; opem em; + struct Vector_ effect; }; struct Op_Import { diff --git a/opcode.txt b/opcode.txt index a1ac4940..bb4b88ec 100644 --- a/opcode.txt +++ b/opcode.txt @@ -183,6 +183,7 @@ Gack TryIni TryEnd HandleEffect +PerformEffect NoOp EOC Unroll2 diff --git a/src/import/import_oper.c b/src/import/import_oper.c index 6ed6dada..1b48f8e4 100644 --- a/src/import/import_oper.c +++ b/src/import/import_oper.c @@ -35,7 +35,7 @@ ANN2(1,2) static int import_op(const Gwi gwi, const struct OperCK* op, 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 }; + const struct Op_Func opfunc = { .ck=op->ck, .em=op->em, .effect = { .ptr=op->effect.ptr } }; const struct Op_Import opi = { .lhs=lhs, .rhs=rhs, .ret=ret, .func=&opfunc, .data=(uintptr_t)f, .pos=gwi->loc, .op=op->sym }; return add_op(gwi->gwion, &opi); @@ -60,6 +60,12 @@ ANN m_int gwi_oper_emi(const Gwi gwi, const opem em) { return GW_OK; } +ANN void gwi_oper_eff(const Gwi gwi, const m_str effect) { + if(!gwi->oper->effect.ptr) + vector_init(&gwi->oper->effect); + vector_add(&gwi->oper->effect, (m_uint)insert_symbol(gwi->gwion->st, effect)); +} + ANN m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f) { gwi->oper->sym = insert_symbol(gwi->gwion->st, op); const m_bool ret = import_op(gwi, gwi->oper, f); diff --git a/src/lib/prim.c b/src/lib/prim.c index 37087684..15ccd115 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -91,6 +91,7 @@ GWION_IMPORT(int_op) { GWI_BB(gwi_oper_add(gwi, opck_int_mul)) GWI_BB(gwi_oper_end(gwi, "*", int_mul)) GWI_BB(gwi_oper_add(gwi, opck_int_div)) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", int_div)) GWI_BB(gwi_oper_add(gwi, opck_int_mod)) return gwi_oper_end(gwi, "%", int_modulo); @@ -293,6 +294,7 @@ static GWION_IMPORT(intfloat) { GWI_BB(gwi_oper_add(gwi, opck_int_float_sub)) GWI_BB(gwi_oper_end(gwi, "-", int_float_minus)) GWI_BB(gwi_oper_add(gwi, opck_int_float_div)) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", int_float_div)) CHECK_IF("=>", rassign, r_assign) CHECK_IF("+=>", rassign, r_plus) @@ -342,6 +344,7 @@ static GWION_IMPORT(floatint) { GWI_BB(gwi_oper_add(gwi, opck_float_int_mul)) GWI_BB(gwi_oper_end(gwi, "*", float_int_mul)) GWI_BB(gwi_oper_add(gwi, opck_float_int_div)) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", float_int_div)) CHECK_FI("=>", rassign, r_assign) CHECK_FI("+=>", rassign, r_plus) @@ -382,9 +385,11 @@ static GWION_IMPORT(dur) { GWI_BB(gwi_oper_end(gwi, "-", FloatMinus)) GWI_BB(gwi_oper_end(gwi, "*", FloatTimes)) GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "float")) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) GWI_BB(gwi_oper_ini(gwi, "dur", "float", "dur")) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur")) @@ -420,6 +425,7 @@ static GWION_IMPORT(time) { GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time")) GWI_BB(gwi_oper_end(gwi, "+", FloatPlus)) GWI_BB(gwi_oper_end(gwi, "*", FloatTimes)) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) GWI_BB(gwi_oper_ini(gwi, "time", "time", "dur")) GWI_BB(gwi_oper_end(gwi, "-", FloatMinus)) @@ -473,6 +479,7 @@ static GWION_IMPORT(float) { GWI_BB(gwi_oper_add(gwi, opck_float_mul)) GWI_BB(gwi_oper_end(gwi, "*", FloatTimes)) GWI_BB(gwi_oper_add(gwi, opck_float_div)) + GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException")) GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) CHECK_FF("=>", rassign, r_assign) diff --git a/src/parse/check.c b/src/parse/check.c index 6cdb5918..df1622c3 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -722,7 +722,7 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { ANN m_bool func_check(const Env env, Exp_Call *const exp) { CHECK_OB(check_exp(env, exp->func)) if(exp->func->exp_type == ae_exp_decl) - ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site")) + ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site. did you meant to use `@=>`?")) const Type t = actual_type(env->gwion, exp->func->type); if(isa(t, env->gwion->type[et_function]) > 0 && exp->func->exp_type == ae_exp_dot && !t->info->value->from->owner_class) { diff --git a/src/parse/operator.c b/src/parse/operator.c index a42b4e1b..50250aec 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -19,6 +19,7 @@ typedef struct M_Operator_{ Func func; opck ck; opem em; + struct Vector_ effect; } M_Operator; ANN void free_op_map(Map map, struct Gwion_ *gwion) { @@ -26,8 +27,13 @@ ANN void free_op_map(Map map, struct Gwion_ *gwion) { for(m_uint i = map_size(map) + 1; --i;) { const restrict Vector v = (Vector)map_at(map, (vtype)i - 1); LOOP_OPTIM - for(m_uint j = vector_size(v) + 1; --j;) - mp_free(gwion->mp, M_Operator, (M_Operator*)vector_at(v, j - 1)); + for(m_uint j = vector_size(v) + 1; --j;) { + M_Operator *const mop = (M_Operator*)vector_at(v, j - 1); + if(mop->effect.ptr) + vector_release(&mop->effect); + mp_free(gwion->mp, M_Operator, mop); + + } free_vector(gwion->mp, v); } map_release(map); -- 2.43.0