]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve Event and ternaries
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 24 Jan 2021 16:56:22 +0000 (17:56 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 24 Jan 2021 16:56:22 +0000 (17:56 +0100)
plug
src/emit/emit.c
src/lib/event.c
src/lib/prim.c
src/lib/shred.c
src/parse/check.c

diff --git a/plug b/plug
index ff877dc672747eb69bd20debd6e148023592296f..e79fc7281e80eb94b4adcbda3a4b2b0acf712a5c 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit ff877dc672747eb69bd20debd6e148023592296f
+Subproject commit e79fc7281e80eb94b4adcbda3a4b2b0acf712a5c
index dca1bc6faa1719471de5ab7e2b461b6202f59bf2..770d2e6eca5db416a3db46165dae29208f1417eb 100644 (file)
@@ -1371,6 +1371,11 @@ ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
 #define emit_flow(emit,b) _flow(emit, b, 1)
 
 ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
+  const Exp e = exp_if->if_exp ?: exp_if->cond;
+  if(exp_getvar(exp_self(exp_if))) {
+    exp_setvar(e, 1);
+    exp_setvar(exp_if->else_exp, 1);
+  }
   DECL_OB(const Instr, op, = emit_flow(emit, exp_if->cond))
   CHECK_BB(emit_exp_pop_next(emit, exp_if->if_exp ?: exp_if->cond))
   const Instr op2 = emit_add_instr(emit, Goto);
index 47ca622dbd0840d6d58401476f835d8a5d453655..5ebc373e3c0b3923db45bb3f2ace1ecb3068819f 100644 (file)
 #include "gwi.h"
 
 static CTOR(event_ctor) {
-  EV_SHREDS(o) = new_vector(shred->info->mp);
+  vector_init(&EV_SHREDS(o));
 }
 
 static DTOR(event_dtor) {
-  free_vector(shred->info->mp, EV_SHREDS(o));
+  vector_release(&EV_SHREDS(o));
 }
 
 static INSTR(EventWait) {
   POP_REG(shred, SZ_FLOAT);
   const M_Object event = *(M_Object*)REG(-SZ_INT);
   shreduler_remove(shred->tick->shreduler, shred, 0);
-  const Vector v = EV_SHREDS(event);
+  const Vector v = &EV_SHREDS(event);
   vector_add(v, (vtype)shred);
   *(m_int*)REG(-SZ_INT) = 1;
 }
 
 static MFUN(event_signal) {
-  const Vector v = EV_SHREDS(o);
+  const Vector v = &EV_SHREDS(o);
   const VM_Shred sh = (VM_Shred)vector_front(v);
   if(sh) {
     shredule(sh->tick->shreduler, sh, GWION_EPSILON);
@@ -36,11 +36,11 @@ static MFUN(event_signal) {
 }
 
 ANN void broadcast(const M_Object o) {
-  for(m_uint i = 0; i < vector_size(EV_SHREDS(o)); i++) {
-    const VM_Shred sh = (VM_Shred)vector_at(EV_SHREDS(o), i);
+  for(m_uint i = 0; i < vector_size(&EV_SHREDS(o)); i++) {
+    const VM_Shred sh = (VM_Shred)vector_at(&EV_SHREDS(o), i);
     shredule(sh->tick->shreduler, sh, GWION_EPSILON);
   }
-  vector_clear(EV_SHREDS(o));
+  vector_clear(&EV_SHREDS(o));
 }
 
 static MFUN(event_broadcast) {
index 8ccaa31f2a2ed9b5e193a6efcc137ecbba932680..682691a8af22eac73fdad697fef4e8c3b8f0fa79 100644 (file)
@@ -88,6 +88,7 @@ BINARY_FOLD(and,  et_bool, &&,,)
 BINARY_FOLD(or,   et_bool, ||,,)
 BINARY_FOLD(eq,   et_bool, ==,,)
 BINARY_FOLD(neq,  et_bool, !=,,)
+
 static GWION_IMPORT(int_logical) {
   GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
   GWI_BB(gwi_oper_add(gwi, opck_int_gt))
@@ -164,7 +165,6 @@ static OP_EMIT(opem_int_range) {
 #define UNARY_FOLD(name, TYPE, OP)                                    \
 static OP_CHECK(opck_int_##name) {                                    \
   /*const*/ Exp_Unary *unary = (Exp_Unary*)data;                      \
-  CHECK_NN(opck_unary_meta(env, data))                                \
   const Type t = env->gwion->type[TYPE];                              \
   if(!exp_self(unary)->pos.first.line || !is_prim_int(unary->exp))    \
     return t;                                                         \
@@ -177,6 +177,7 @@ static OP_CHECK(opck_int_##name) {                                    \
 
 UNARY_FOLD(negate, et_int, -)
 UNARY_FOLD(cmp, et_int, ~)
+UNARY_FOLD(not, et_bool, !)
 static GWION_IMPORT(int_unary) {
   GWI_BB(gwi_oper_ini(gwi, NULL, "int", "int"))
   GWI_BB(gwi_oper_add(gwi, opck_int_negate))
@@ -209,6 +210,7 @@ static GWION_IMPORT(int_values) {
   gwi->gwion->type[et_bool] = t_bool;
   GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool"))
   GWI_BB(gwi_oper_add(gwi, opck_unary_meta))
+  GWI_BB(gwi_oper_add(gwi, opck_int_not))
   GWI_BB(gwi_oper_end(gwi,  "!", IntNot))
   struct SpecialId_ spid = { .type=t_bool, .exec=RegPushMaybe, .is_const=1 };
   gwi_specialid(gwi, "maybe", &spid);
index c67a0f3f5c2bd8f7fd2fc38bb5c105be79173218..0ade7362f2080a34fd73a8dbc5163a361c8a73ab 100644 (file)
@@ -38,7 +38,7 @@ ANN static inline M_Object fork_object(const VM_Shred shred, const Type t) {
   const Gwion gwion = shred->info->vm->gwion;
   const M_Object o = new_object(gwion->mp, shred, t);
   *(M_Object*)(o->data + o_fork_ev) = new_object(gwion->mp, NULL, gwion->type[et_event]);
-  EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)) = new_vector(gwion->mp);
+  vector_init(&EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)));
   return o;
 }
 
@@ -206,7 +206,7 @@ static MFUN(fork_join) {
   if(*(m_int*)(o->data + o_fork_done))
     return;
   shreduler_remove(shred->tick->shreduler, shred, 0);
-  vector_add(EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)), (vtype)shred);
+  vector_add(&EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)), (vtype)shred);
 }
 
 static MFUN(shred_cancel) {
index 16184bf595f4c758d242d8c62acb0f6b76004583..973018f507018759c77d63f99f92641993e80fda 100644 (file)
@@ -807,20 +807,22 @@ ANN static Type _flow(const Env env, const Exp e, const m_bool b) {
 #define check_flow(emit,b) _flow(emit, b, 1)
 
 ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) {
+  const Exp e = exp_if->if_exp ?: exp_if->cond;
   DECL_OO(const Type, cond, = check_flow(env, exp_if->cond))
   DECL_OO(const Type, if_exp, = (exp_if->if_exp ? check_exp(env, exp_if->if_exp) : cond))
   DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp))
+
+  const uint meta = exp_getmeta(e) || exp_getmeta(exp_if->else_exp);
+  exp_setmeta(exp_self(exp_if), meta);
   const Type ret = find_common_anc(if_exp, else_exp);
   if(!ret)
     ERR_O(exp_self(exp_if)->pos,
           _("incompatible types '%s' and '%s' in if expression..."),
           if_exp->name, else_exp->name)
-  if(!exp_if->if_exp && isa(exp_if->cond->type, else_exp) < 0)
+  if(isa(if_exp, else_exp) < 0)
     ERR_O(exp_self(exp_if)->pos,
         _("condition type '%s' does not match '%s'"),
          cond->name, ret->name)
-  if(exp_getmeta(exp_if->if_exp ?: exp_if->cond) || exp_getmeta(exp_if->else_exp))
-    exp_setmeta(exp_self(exp_if), 1);
   return ret;
 }