]> Nishi Git Mirror - gwion.git/commitdiff
:art: Use operators for flow
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 20 Sep 2019 12:56:30 +0000 (14:56 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 20 Sep 2019 12:56:30 +0000 (14:56 +0200)
20 files changed:
include/emit.h
include/gwi.h
include/import.h
include/operator.h
src/emit/emit.c
src/lib/array.c
src/lib/func.c
src/lib/import.c
src/lib/object.c
src/lib/opfunc.c
src/lib/prim.c
src/lib/ptr.c
src/lib/string.c
src/lib/tuple.c
src/parse/check.c
src/parse/operator.c
tests/error/if_exp_invalid_cond.gw [deleted file]
tests/error/invalid_for.gw [deleted file]
tests/error/invalid_until.gw [deleted file]
tests/error/invalid_while.gw [deleted file]

index fdfe3dfcbd58077b6708d18ab7a1565d9a32f3d4..414f6c6c2aaba5c29349ecb26fc7817f1b8868cb 100644 (file)
@@ -30,7 +30,7 @@ ANEW ANN Emitter new_emitter(MemPool);
 ANN void free_emitter(MemPool, Emitter);
 ANEW ANN VM_Code emit_code(const Emitter);
 ANN VM_Code emit_ast(const Emitter emit, Ast ast);
-ANN m_bool emit_exp_call1(const Emitter, const Func);
+ANN Instr emit_exp_call1(const Emitter, const Func);
 ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((returns_nonnull));
 ANN Code* emit_class_code(const Emitter, const m_str);
 ANN m_bool emit_array_extend(const Emitter, const Type, const Exp);
index 7bd75d859886e2f9524383b15904fd782cbe4046..8e9300f1bf1b8cdf8198fa47962ea472ccab128e 100644 (file)
@@ -25,7 +25,7 @@ typedef struct {
   Symbol op;
   m_str ret, lhs, rhs;
   Type   (*ck)(Env, void*, m_bool*);
-  m_bool (*em)(Emitter, void*);
+  Instr  (*em)(Emitter, void*);
 } DL_Oper;
 
 typedef struct {
index ba8815897812c34e96131c9f5e93e40e645ce72d..e9ae46652a1c8e8d13adab4ee46b46e1ff9c9cbf 100644 (file)
@@ -13,7 +13,7 @@ typedef struct Gwi_* Gwi;
 #define CTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
 #define DTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
 #define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
-#define OP_EMIT(a)  ANN m_bool a(const Emitter emit NUSED, void* data NUSED)
+#define OP_EMIT(a)  ANN Instr a(const Emitter emit NUSED, void* data NUSED)
 #ifdef GWION_BUILTIN
 #define GWI_BB(a) (void)(a);
 #define GWI_OB(a) (void)(a);
@@ -63,10 +63,10 @@ ANN m_int gwi_func_arg(const Gwi gwi, const __restrict__ m_str t, const __restri
 ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag);
 
 ANN2(1) m_int gwi_oper_ini(const Gwi gwi, const m_str l, const m_str r, const m_str t);
-ANN m_int gwi_oper_add(const Gwi gwi, opck);
-ANN m_int gwi_oper_emi(const Gwi gwi, opem);
+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 Type_Decl* str2decl(const Env, const m_str, m_uint* depth);
 
 OP_CHECK(opck_const_rhs);
index f7f8dbf0f4a33077223661044e87a0f8133556f6..9df6637fdfc11891fa020a6e58c4ebc7ff1895ba 100644 (file)
@@ -5,7 +5,7 @@
 #define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; }
 
 typedef Type (*opck)(const Env, void*, m_bool*);
-typedef m_bool (*opem)(const Emitter, void*);
+typedef struct Instr_* (*opem)(const Emitter, void*);
 
 struct Op_Import {
   Type lhs, rhs, ret;
@@ -23,7 +23,7 @@ struct Implicit {
 };
 ANN m_bool add_op(const Gwion gwion, const struct Op_Import*);
 ANN Type   op_check(const Env, struct Op_Import*);
-ANN m_bool op_emit(const Emitter, const struct Op_Import*);
+ANN struct Instr_* op_emit(const Emitter, const struct Op_Import*);
 ANN m_bool operator_set_func(const struct Op_Import*);
 ANN void free_op_map(Map map, struct Gwion_* gwion);
 #endif
index f64d88f9577721ae30ec3b528f521e51e38edf9c..88530019062e8c16d27b4673b33b2e3d5a5e8d06 100644 (file)
@@ -775,7 +775,7 @@ ANN static m_bool prepare_call(const Emitter emit, const Exp_Call* exp_call) {
 
 ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
   CHECK_BB(prepare_call(emit, exp_call))
-  return emit_exp_call1(emit, exp_call->m_func);
+  return emit_exp_call1(emit, exp_call->m_func) ? GW_OK : GW_ERROR;
 }
 
 ANN static m_uint get_decl_size(Var_Decl_List a) {
@@ -819,7 +819,7 @@ ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) {
   struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .pos=exp_self(bin)->pos, .data = (uintptr_t)bin };
   CHECK_BB(emit_exp_pop_next(emit, lhs, 1))
   CHECK_BB(emit_exp_pop_next(emit, rhs, 1))
-  return op_emit(emit, &opi);
+  return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
 }
 
 ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
@@ -832,7 +832,7 @@ ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
 ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) {
   struct Op_Import opi = { .op=post->op, .lhs=post->exp->type, .data=(uintptr_t)post };
   CHECK_BB(emit_exp(emit, post->exp, 1))
-  return op_emit(emit, &opi);
+  return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
 }
 
 ANN static m_bool is_special(const Type t) {
@@ -963,11 +963,11 @@ ANN static Instr emit_call(const Emitter emit, const Func f) {
   return emit_add_instr(emit, Overflow);
 }
 
-ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
+ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
   if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
     if(GET_FLAG(f, template) && !is_fptr(f->value_ref->type)) {
       if(emit->env->func != f)
-        CHECK_BB(emit_template_code(emit, f))
+        CHECK_BO(emit_template_code(emit, f))
       else {
         const Instr back = (Instr)vector_back(&emit->code->instr);
         back->opcode = ePushStaticCode;
@@ -1003,7 +1003,7 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
   const Instr instr = emit_call(emit, f);
   instr->m_val = f->def->base->ret_type->size;
   instr->m_val2 = offset;
-  return GW_OK;
+  return instr;
 }
 
 ANN static void emit_exp_spork_finish(const Emitter emit, const m_uint depth) {
@@ -1051,10 +1051,11 @@ static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t
 ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) {
   if(GET_FLAG(exp->m_func, member))
     SET_FLAG(emit->code, member);
-  return emit_exp_call1(emit, exp->m_func);
+  return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
 }
 
-ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
+// TODO header
+ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
   const m_bool is_spork = unary->op == insert_symbol("spork");
   const Func f = !unary->code ? unary->exp->d.exp_call.m_func : NULL;
   if(unary->code) {
@@ -1062,11 +1063,11 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
     push_spork_code(emit, is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, unary->code->pos);
     if(!SAFE_FLAG(emit->env->func, member))
       stack_alloc_this(emit);
-    CHECK_BB(scoped_stmt(emit, unary->code, 0))
+    CHECK_BO(scoped_stmt(emit, unary->code, 0))
   } else {
-    CHECK_BB(prepare_call(emit, &unary->exp->d.exp_call))
+    CHECK_BO(prepare_call(emit, &unary->exp->d.exp_call))
     push_spork_code(emit, is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, unary->exp->pos);
-    CHECK_BB(spork_func(emit, &unary->exp->d.exp_call))
+    CHECK_BO(spork_func(emit, &unary->exp->d.exp_call))
   }
   const VM_Code code = finalyze(emit);
   const Instr ini = emit_add_instr(emit, unary->op == insert_symbol("spork") ? SporkIni : ForkIni);
@@ -1091,7 +1092,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
     const Instr end = emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
     end->m_val2 = f->def->base->ret_type->size;
   }
-  return GW_OK;
+  return ini;
 }
 
 ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
@@ -1100,26 +1101,25 @@ ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
     CHECK_BB(emit_exp_pop_next(emit, unary->exp, 1))
     opi.rhs = unary->exp->type;
   }
-  return op_emit(emit, &opi);
+  return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
 }
 
 ANN static m_bool emit_implicit_cast(const Emitter emit,
     const restrict Exp  from, const restrict Type to) {
   const struct Implicit imp = { from, to, from->pos };
   struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->type, .rhs=to, .data=(m_uint)&imp };
-  return op_emit(emit, &opi);
+  return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
 }
 
-ANN static Instr emit_flow(const Emitter emit, const Type type,
-    const f_instr f1, const f_instr f2) {
-  if(isa(type, t_float) > 0 || isa(type, t_dur) > 0 || isa(type, t_time) > 0)
-    return emit_add_instr(emit, f2);
-  return emit_add_instr(emit, f1);
+ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
+  CHECK_BO(emit_exp_pop_next(emit, e, 0))
+  struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"), .rhs=e->type, .pos=e->pos };
+  return op_emit(emit, &opi);
 }
+#define emit_flow(emit,b) _flow(emit, b, 1)
 
 ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
-  CHECK_BB(emit_exp(emit, exp_if->cond, 0))
-  const Instr op = emit_flow(emit, exp_if->cond->type, BranchEqInt, BranchEqFloat);
+  const Instr op = emit_flow(emit, exp_if->cond);
   CHECK_BB(emit_exp(emit, exp_if->if_exp ?: exp_if->cond, 0))
   const Instr op2 = emit_add_instr(emit, Goto);
   op->m_val = emit_code_size(emit);
@@ -1168,9 +1168,7 @@ ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) {
 
 ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
   emit_push_scope(emit);
-  CHECK_BB(emit_exp_pop_next(emit, stmt->cond, 0))
-  DECL_OB(const Instr, op, = emit_flow(emit, isa(stmt->cond->type, t_object) > 0 ?
-      t_int : stmt->cond->type, BranchEqInt, BranchEqFloat))
+  DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond))
   CHECK_BB(scoped_stmt(emit, stmt->if_body, 1))
   const Instr op2 = emit_add_instr(emit, Goto);
   op->m_val = emit_code_size(emit);
@@ -1238,13 +1236,6 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) {
   emit_pop_scope(emit);
 }
 
-ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
-  CHECK_BO(emit_exp_pop_next(emit, e, 0))
-  const f_instr instr_i = b ? BranchEqInt : BranchNeqInt;
-  const f_instr instr_f = b ? BranchEqFloat : BranchNeqFloat;
-  return emit_flow(emit, e->type, instr_i, instr_f);
-}
-
 ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) {
   const m_uint index = emit_code_size(emit);
   Instr op = NULL;
@@ -1268,12 +1259,7 @@ ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) {
   emit_push_stack(emit);
   CHECK_BB(emit_stmt(emit, stmt->c1, 1))
   const m_uint index = emit_code_size(emit);
-  if(stmt->c2->stmt_type == ae_stmt_exp)
-    emit_exp_pop_next(emit, stmt->c2->d.stmt_exp.val, 0);
-  else
-    CHECK_BB(emit_stmt(emit, stmt->c2, 0))
-  const Instr op = emit_flow(emit, stmt->c2->d.stmt_exp.val->type,
-    BranchEqInt, BranchEqFloat);
+  const Instr op = emit_flow(emit, stmt->c2->d.stmt_exp.val);
   CHECK_BB(scoped_stmt(emit, stmt->body, 1))
   const m_uint action_index = emit_code_size(emit);
   if(stmt->c3) {
@@ -1444,23 +1430,18 @@ ANN static m_bool emit_stmt_exp(const Emitter emit, const struct Stmt_Exp_* exp)
   return exp->val ? emit_exp(emit, exp->val, 0) : 1;
 }
 
-ANN static Instr emit_when(const Emitter emit, const Exp when) {
-  CHECK_BO(emit_exp(emit, when, 1))
-  return emit_add_instr(emit, BranchEqInt);
-}
-
 ANN static m_bool emit_case_head(const Emitter emit, const Exp base, const Exp e, const Symbol op) {
   CHECK_BB(emit_exp(emit, base, 1))
   CHECK_BB(emit_exp(emit, e, 1))
   Exp_Binary bin = { .lhs=base, .rhs=e, .op=op, .nspc=emit->env->curr };
   struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type, .data=(uintptr_t)&bin, .pos=e->pos };
-  CHECK_BB(op_emit(emit, &opi))
+  CHECK_OB(op_emit(emit, &opi))
   regpop(emit, base->type->size);
   return GW_OK;
 }
 
 ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* stmt) {
-  const Instr when = stmt->when ? emit_when(emit, stmt->when) : NULL;
+  const Instr when = stmt->when ? emit_flow(emit, stmt->when) : NULL;
   if(stmt->when)
     CHECK_OB(when)
   CHECK_BB(emit_stmt_list(emit, stmt->list))
index 974425b4d470a184df15dea92d5556b62096598e..0ecec885679285985cf619bc2867b9b921318601 100644 (file)
@@ -167,8 +167,7 @@ static OP_EMIT(opem_array_shift) {
   pop->m_val = type->size;
   if(!GET_FLAG(bin->lhs->type, nonnull))
     emit_add_instr(emit, GWOP_EXCEPT);
-  emit_add_instr(emit, ArrayAppend);
-  return GW_OK;
+  return emit_add_instr(emit, ArrayAppend);
 }
 
 // check me. use common ancestor maybe
index 6167e2b070b546bd4c4293d851e39c801cf9cd12..24c31a82316c2f1ae3f6b0c3c51b405b52f0cb2a 100644 (file)
@@ -19,7 +19,7 @@
 #include "parse.h"
 
 ANN Type check_exp_call1(const Env env, const Exp_Call *exp);
-ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary*);
+ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*);
 
 static INSTR(LambdaAssign) {
   POP_REG(shred, SZ_INT)
@@ -48,12 +48,12 @@ static OP_EMIT(opem_func_assign) {
   Exp_Binary* bin = (Exp_Binary*)data;
   if(bin->rhs->type->e->d.func->def->base->tmpl)
     fptr_instr(emit, bin->lhs->type->e->d.func, 2);
-  emit_add_instr(emit, int_r_assign);
+  const Instr instr = emit_add_instr(emit, int_r_assign);
   if(isa(bin->lhs->type, t_fptr) < 0 && GET_FLAG(bin->rhs->type->e->d.func, member)) {
-    const Instr instr = emit_add_instr(emit, LambdaAssign);
-    instr->m_val = SZ_INT;
+    const Instr pop = emit_add_instr(emit, LambdaAssign);
+    pop->m_val = SZ_INT;
   }
-  return GW_OK;
+  return instr;
 }
 
 struct FptrInfo {
@@ -231,14 +231,14 @@ static void member_fptr(const Emitter emit) {
 }
 
 static OP_EMIT(opem_fptr_cast) {
-  CHECK_BB(opem_basic_cast(emit, data))
+  CHECK_OO(opem_basic_cast(emit, data))
   Exp_Cast* cast = (Exp_Cast*)data;
   if(exp_self(cast)->type->e->d.func->def->base->tmpl)
     fptr_instr(emit, cast->exp->type->e->d.func, 1);
   if(GET_FLAG(cast->exp->type->e->d.func, member) &&
     !(GET_FLAG(cast->exp->type, nonnull) || GET_FLAG(exp_self(cast)->type, nonnull)))
     member_fptr(emit);
-  return GW_OK;
+  return (Instr)GW_OK;// ???
 }
 
 static OP_CHECK(opck_fptr_impl) {
@@ -256,7 +256,7 @@ static OP_EMIT(opem_fptr_impl) {
     member_fptr(emit);
   if(impl->t->e->d.func->def->base->tmpl)
     fptr_instr(emit, ((Exp)impl->e)->type->e->d.func, 1);
-  return GW_OK;
+  return (Instr)GW_OK;
 }
 
 ANN Type check_exp_unary_spork(const Env env, const Stmt code);
@@ -300,9 +300,12 @@ static FREEARG(freearg_dottmpl) {
 }
 
 GWION_IMPORT(func) {
+  GWI_BB(gwi_oper_cond(gwi, "@func_ptr", BranchEqInt, BranchNeqInt))
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@function", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_func_call))
   GWI_BB(gwi_oper_end(gwi, "=>", NULL))
+  GWI_BB(gwi_oper_ini(gwi, NULL, "@func_ptr", "int"))
+  GWI_BB(gwi_oper_end(gwi, "!", IntNot))
   GWI_BB(gwi_oper_ini(gwi, "@function", "@func_ptr", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_fptr_at))
   GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
index 3170b796edff6c5add37c004c6db1167ecd63733..10103aa287f05d17d3679c3ef8b010d67fa9406a 100644 (file)
@@ -500,7 +500,7 @@ ANN m_int gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void*, m_bool*)) {
   return GW_OK;
 }
 
-ANN m_int gwi_oper_emi(const Gwi gwi, m_bool (*em)(Emitter, void*)) {
+ANN m_int gwi_oper_emi(const Gwi gwi, const opem em) {
   gwi->oper.em = em;
   return GW_OK;
 }
@@ -513,6 +513,14 @@ ANN m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f) {
   return ret;
 }
 
+ANN m_int gwi_oper_cond(const Gwi gwi, const m_str type,
+  const f_instr f1, const f_instr f2) {
+  GWI_BB(gwi_oper_ini(gwi, NULL, type, "int"))
+  GWI_BB(gwi_oper_end(gwi, "@conditionnal", f1))
+  GWI_BB(gwi_oper_end(gwi, "@unconditionnal", f2))
+  return GW_OK;
+}
+
 ANN m_int gwi_fptr_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
   dl_func_init(&gwi->func, type, name, 0);
   return GW_OK;
index 48c09e405105b6ae04a43aaf6fc78d0fa1d3f0c4..482f66afe588312f14aa3de6d947c465356ecc2c 100644 (file)
@@ -144,8 +144,7 @@ static OP_EMIT(opem_at_object) {
     const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
     instr->m_val = SZ_INT;
   }
-  emit_add_instr(emit, ObjectAssign);
-  return GW_OK;
+  return emit_add_instr(emit, ObjectAssign);
 }
 
 #define STR_FORCE ":force"
@@ -185,7 +184,7 @@ static OP_EMIT(opem_object_cast) {
   const Type r = exp_self(cast)->type;
   if(nonnull_check(l, r))
     emit_add_instr(emit, GWOP_EXCEPT);
-  return GW_OK;
+  return (Instr)GW_OK;
 }
 
 static OP_CHECK(opck_implicit_null2obj) {
@@ -204,13 +203,14 @@ static OP_EMIT(opem_implicit_null2obj) {
   const Type r = imp->t;
   if(nonnull_check(l, r))
     emit_add_instr(emit, GWOP_EXCEPT);
-  return GW_OK;
+  return (Instr)GW_OK;
 }
 
 GWION_IMPORT(object) {
   t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
   GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
   GWI_BB(gwi_class_end(gwi))
+  GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
   GWI_BB(gwi_oper_ini(gwi, "@null", "Object", "Object"))
   GWI_BB(gwi_oper_add(gwi, at_object))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
index 876cef5e57f436929ccf074358dfdddb531e81a9..28ddad2f9fb7d447a3e1ece52569a95abe253f7d 100644 (file)
@@ -24,7 +24,7 @@ OP_CHECK(opck_basic_cast) {
 }
 
 OP_EMIT(opem_basic_cast) {
-  return GW_OK;
+  return (Instr)GW_OK;
 }
 
 OP_CHECK(opck_const_rhs) {
@@ -110,8 +110,7 @@ OP_CHECK(opck_new) {
 
 OP_EMIT(opem_new) {
   const Exp_Unary* unary = (Exp_Unary*)data;
-  CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type,
+  CHECK_BO(emit_instantiate_object(emit, exp_self(unary)->type,
     unary->td->array, GET_FLAG(unary->td, ref)))
-  CHECK_OB(emit_add_instr(emit, GcAdd))
-  return GW_OK;
+  return emit_add_instr(emit, GcAdd);
 }
index e6788d6fc572efe64f8efa59adeb1998c18c0eaf..8a4048c9798ef6a42dfeecf4fa4ffa60d9b4569c 100644 (file)
@@ -85,6 +85,7 @@ static GWION_IMPORT(int_values) {
 }
 
 static GWION_IMPORT(int) {
+  GWI_BB(gwi_oper_cond(gwi, "int", BranchEqInt, BranchNeqInt))
   GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
   GWI_BB(import_int_op(gwi))
   GWI_BB(import_int_logical(gwi))
@@ -143,14 +144,13 @@ static OP_CHECK(opck_implicit_i2f) {
   return t_float;
 }
 
+// can't it be just declared?
 static OP_EMIT(opem_i2f) {
-  emit_add_instr(emit, CastI2F);
-  return GW_OK;
+  return emit_add_instr(emit, CastI2F);
 }
 
 static OP_EMIT(opem_f2i) {
-  emit_add_instr(emit, CastF2I);
-  return GW_OK;
+  return emit_add_instr(emit, CastF2I);
 }
 
 #define CHECK_FF(op, check, func) _CHECK_OP(op, check, float_##func)
@@ -210,6 +210,7 @@ static GWION_IMPORT(floatint) {
 }
 
 static GWION_IMPORT(dur) {
+  GWI_BB(gwi_oper_cond(gwi, "dur", BranchEqFloat, BranchNeqFloat))
   GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "dur"))
   CHECK_FF("=>", rassign, r_assign)
   GWI_BB(gwi_oper_end(gwi, "+",         FloatPlus))
@@ -226,6 +227,7 @@ static GWION_IMPORT(dur) {
 }
 
 static GWION_IMPORT(time) {
+  GWI_BB(gwi_oper_cond(gwi, "time", BranchEqFloat, BranchNeqFloat))
   GWI_BB(gwi_oper_ini(gwi, "time", "time", "time"))
   CHECK_FF("=>", rassign, r_assign)
   GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time"))
@@ -243,6 +245,7 @@ static GWION_IMPORT(time) {
 }
 
 static GWION_IMPORT(float) {
+  GWI_BB(gwi_oper_cond(gwi, "float", BranchEqFloat, BranchNeqFloat))
   GWI_BB(gwi_oper_ini(gwi, "float", "float", "float"))
   GWI_BB(gwi_oper_end(gwi, "+",          FloatPlus))
   GWI_BB(gwi_oper_end(gwi, "-",         FloatMinus))
index d1465cdb8205d9887c0f2e6e2361f4d94791616d..80d571d2ed77c9e661d08aa06d67f0cfa3757786 100644 (file)
@@ -35,8 +35,7 @@ static INSTR(instr_ptr_assign) {
 
 static OP_EMIT(opem_ptr_assign) {
   emit_add_instr(emit, GWOP_EXCEPT);
-  emit_add_instr(emit, instr_ptr_assign);
-  return GW_OK;
+  return emit_add_instr(emit, instr_ptr_assign);
 }
 
 static OP_CHECK(opck_ptr_deref) {
@@ -99,7 +98,7 @@ static OP_EMIT(opem_ptr_deref) {
   const Instr instr = emit_add_instr(emit, instr_ptr_deref);
   instr->m_val = exp_self(unary)->type->size;
   instr->m_val2 = exp_self(unary)->emit_var;
-  return GW_OK;
+  return instr;
 }
 
 GWION_IMPORT(ptr) {
index 4cee1dd18055c139f7df8ca0ceb69eb966b564a2..d323bbce26e620d2385046381d107b9dd79a08fd 100644 (file)
@@ -128,7 +128,7 @@ describe_string(Vec4, m_vec4, SZ_VEC4,
   num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + num_digit((m_uint)lhs.w),,
   "@(%.4f, %.4f, %.4f, %.4f)%s", lhs.x, lhs.y, lhs.z, lhs.w, rhs ? STRING(rhs) : "")
 describe_string(Object, M_Object, SZ_INT,
-  16 + (rhs ? strlen(STRING(rhs)) : 0), release(lhs, shred),
+  17 + (rhs ? strlen(STRING(rhs)) : 0), /*release(lhs, shred)*/,
   "%p%s", (void*)lhs, rhs ? STRING(rhs) : "")
 
 
index b3a55d257077f36c1833c817b02c924339145f0a..a7d94469b5c630b54ae93cc9842529184f8bb61e 100644 (file)
@@ -180,8 +180,7 @@ static OP_EMIT(opem_##name##_tuple_object) {              \
   const type exp = (type)data;                            \
   const Instr instr = emit_add_instr(emit, Tuple2Object); \
   instr->m_val = (m_uint)rhs;                             \
-  emit_add_instr(emit, ObjectAssign);                     \
-  return 1;                                               \
+  return emit_add_instr(emit, ObjectAssign);              \
 }
 mk_opem_tuple2object(at, Exp_Binary *, exp->rhs->type)
 mk_opem_tuple2object(cast, Exp_Cast *, exp_self(exp)->type)
@@ -203,14 +202,13 @@ static OP_EMIT(opem_at_tuple) {
   const Exp_Binary *bin = (Exp_Binary*)data;
   if(!(bin->rhs->exp_type == ae_exp_primary &&
       bin->rhs->d.exp_primary.primary_type == ae_primary_unpack)) {
-      emit_add_instr(emit, ObjectAssign);
-      return GW_OK;
+      return emit_add_instr(emit, ObjectAssign);
   }
   const Exp e = bin->rhs->d.exp_primary.d.tuple.exp;
   const Vector v = &bin->lhs->type->e->tuple->types;
   struct TupleEmit te = { .e=e, .v=v };
   emit_unpack_instr(emit, &te);
-  return GW_OK;
+  return (Instr)GW_OK;
 }
 
 ANN void tuple_info(const Env env, Type_Decl *base, const Var_Decl var) {
index 9a3b9c212f1467a83562d50a42aec6e97cf77f3e..f6fbbb71f312961d2849cf182d16f5513b3ea6be 100644 (file)
@@ -866,13 +866,16 @@ ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
   return op_check(env, &opi);
 }
 
+ANN static m_bool check_flow(const Env env, const Exp exp) {
+  struct Op_Import opi = { .op=insert_symbol("@conditionnal"), .rhs=exp->type, .pos=exp->pos };
+  return op_check(env, &opi) ? GW_OK : GW_ERROR;
+}
+
 ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) {
   DECL_OO(const Type, cond, = check_exp(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))
-  if(isa(cond, t_int) < 0 && isa(cond, t_float) < 0 && isa(cond, t_object) < 0)
-    ERR_O(exp_self(exp_if)->pos,
-          _("Invalid type '%s' in if expression condition."), cond->name)
+  CHECK_BO(check_flow(env, exp_if->cond))
   const Type ret = find_common_anc(if_exp, else_exp);
   if(!ret)
     ERR_O(exp_self(exp_if)->pos,
@@ -965,13 +968,6 @@ ANN static m_bool check_stmt_code(const Env env, const Stmt_Code stmt) {
   return GW_OK;
 }
 
-ANN static m_bool check_flow(const Env env, const Exp exp, const m_str orig) {
-  if(isa(exp->type, t_object) > 0 || isa(exp->type, t_int) > 0 || isa(exp->type, t_float) > 0 ||
-     isa(exp->type, t_dur) > 0 || isa(exp->type, t_time)  > 0)
-    return GW_OK;
-  ERR_B(exp->pos, _("invalid type '%s' (in '%s' condition)"), exp->type->name, orig)
-}
-
 ANN static m_bool check_breaks(const Env env, const Stmt a, const Stmt b) {
   vector_add(&env->scope->breaks, (vtype)a);
   RET_NSPC(check_stmt(env, b))
@@ -1051,18 +1047,18 @@ ANN static m_bool cond_type(const Env env, const Exp e) {
 }
 #define stmt_func_xxx(name, type, prolog, exp) describe_stmt_func(check, name, type, prolog, exp)
 stmt_func_xxx(if, Stmt_If,, !(!check_exp(env, stmt->cond) ||
-  check_flow(env, stmt->cond, "if") < 0   ||
+  check_flow(env, stmt->cond) < 0   ||
   check_stmt(env, stmt->if_body) < 0 ||
   (stmt->else_body && check_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
 stmt_func_xxx(flow, Stmt_Flow,,
   !(!check_exp(env, stmt->cond) ||
-    check_flow(env, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while ? "while" : "until") < 0 ||
+    check_flow(env, stmt->cond) < 0 ||
     check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
 stmt_func_xxx(for, Stmt_For,, !(
   for_empty(env, stmt) < 0 ||
   check_stmt(env, stmt->c1) < 0 ||
   check_stmt(env, stmt->c2) < 0 ||
-  check_flow(env, stmt->c2->d.stmt_exp.val, "for") < 0 ||
+  check_flow(env, stmt->c2->d.stmt_exp.val) < 0 ||
   (stmt->c3 && !check_exp(env, stmt->c3)) ||
   check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
 stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) ||
index 169df4d2fb13afde2ce6d893821630044c901966..c8fd1fe58c1c5e7e010bcc370081bb999f26f8c8 100644 (file)
@@ -127,6 +127,7 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
 
 ANN static void set_nspc(struct OpChecker* ock, const Nspc nspc) {
   if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit"))return;
+  if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@conditionnal"))return;
   if(ock->opi->op == insert_symbol(ock->env->gwion->st, "$"))
     ((Exp_Cast*)ock->opi->data)->nspc = nspc;
   if(ock->opi->lhs) {
@@ -192,18 +193,19 @@ ANN m_bool operator_set_func(const struct Op_Import* opi) {
   return GW_OK;
 }
 
-ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
+ANN static Instr handle_instr(const Emitter emit, const M_Operator* mo) {
   if(mo->func) {
     const Instr instr = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode);
     instr->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
     return emit_exp_call1(emit, mo->func);
   }
-  emit_add_instr(emit, mo->instr);
-  return GW_OK;
+  return emit_add_instr(emit, mo->instr);
 }
 
 ANN static Nspc get_nspc(SymTable *st, const struct Op_Import* opi) {
-  if(opi->op == insert_symbol(st, "@implicit"))
+  if(opi->op == insert_symbol(st, "@implicit")     ||
+    opi->op == insert_symbol(st, "@conditionnal")  ||
+    opi->op == insert_symbol(st, "@unconditionnal"))
     return opi->rhs->e->owner;
   if(opi->op == insert_symbol(st, "$"))
     return ((Exp_Cast*)opi->data)->nspc;
@@ -223,10 +225,8 @@ ANN static inline Nspc ensure_nspc(SymTable *st, const struct Op_Import* opi) {
   return nspc;
 }
 
-ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
-  Nspc nspc = ensure_nspc(emit->gwion->st, opi);
-  if(!nspc)
-    return GW_OK;
+ANN Instr op_emit(const Emitter emit, const struct Op_Import* opi) {
+  DECL_OO(Nspc, nspc, = ensure_nspc(emit->gwion->st, opi))
   Type l = opi->lhs;
   do {
     Type r = opi->rhs;
@@ -240,5 +240,5 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
       }
     } while(r && (r = op_parent(emit->env, r)));
   } while(l && (l = op_parent(emit->env, l)));
-  return GW_ERROR;
+  return NULL;
 }
diff --git a/tests/error/if_exp_invalid_cond.gw b/tests/error/if_exp_invalid_cond.gw
deleted file mode 100644 (file)
index 98a16df..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] Invalid type
-null ? <<< 1 >>> : <<< 2 >>>;
diff --git a/tests/error/invalid_for.gw b/tests/error/invalid_for.gw
deleted file mode 100644 (file)
index 9e8dce9..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] in 'for' condition
-for(;null;);
diff --git a/tests/error/invalid_until.gw b/tests/error/invalid_until.gw
deleted file mode 100644 (file)
index 3314df6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] in 'until' condition
-until(null);
diff --git a/tests/error/invalid_while.gw b/tests/error/invalid_while.gw
deleted file mode 100644 (file)
index bf2235d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] in 'while' condition
-while(null);