]> Nishi Git Mirror - gwion.git/commitdiff
:art: Operator effects
authorJérémie Astor <fennecdjay@gmail.com>
Fri, 23 Apr 2021 17:02:29 +0000 (19:02 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Fri, 23 Apr 2021 17:02:29 +0000 (19:02 +0200)
include/import/checker.h
include/import/oper.h
include/operator.h
opcode.txt
src/import/import_oper.c
src/lib/prim.c
src/parse/check.c
src/parse/operator.c

index b0389e30177eb0ec9db2f22c01e02e26393b9ca3..1b4002986a038855c02581bb929c35cd8af8a789 100644 (file)
@@ -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);
index cf5bedcff388ed69e5b4b3121b7885e35403ac3b..f7514865815b85406ee253940ab22eba1f775f9b 100644 (file)
@@ -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                                  \
index d7cb256623a8b35862703faaec705a0c60cb1fcb..585c41859bcc562450203256c8cb5c9f84b99146 100644 (file)
@@ -18,6 +18,7 @@ typedef m_bool (*opem)(const Emitter, void*);
 struct Op_Func {
   opck ck;
   opem em;
+  struct Vector_ effect;
 };
 
 struct Op_Import {
index a1ac49401c357f56ae142d5fb81d8aee78d56500..bb4b88ecd39cf69eaf940142907f57a04628291f 100644 (file)
@@ -183,6 +183,7 @@ Gack
 TryIni
 TryEnd
 HandleEffect
+PerformEffect
 NoOp
 EOC
 Unroll2
index 6ed6dada3b772c3f4ad5639cd518ba679e219bb3..1b48f8e450da2d32899eeb856656c437b169eeae 100644 (file)
@@ -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);
index 370876841c11625f97518ce380ba4e0da738d503..15ccd115c33a7bbd8130f6356b18376ccf56e52e 100644 (file)
@@ -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)
index 6cdb5918cb67673e487f4ecdd0c4d796985fe1c8..df1622c3f434d3c133a9d28df73f9789a55341cf 100644 (file)
@@ -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) {
index a42b4e1bd1eb93fa8137b8794a5ea2b7278853f5..50250aec30485dfb4687e5742dc693c6d6b98b5c 100644 (file)
@@ -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);