-Subproject commit ff877dc672747eb69bd20debd6e148023592296f
+Subproject commit e79fc7281e80eb94b4adcbda3a4b2b0acf712a5c
#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);
#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);
}
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) {
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))
#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; \
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))
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);
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;
}
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) {
#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;
}