From ad4e6bdb96a603a2ef97947c554f9fe7c6fae1bd Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 20 Sep 2019 14:56:30 +0200 Subject: [PATCH] :art: Use operators for flow --- include/emit.h | 2 +- include/gwi.h | 2 +- include/import.h | 8 ++-- include/operator.h | 4 +- src/emit/emit.c | 69 +++++++++++------------------- src/lib/array.c | 3 +- src/lib/func.c | 19 ++++---- src/lib/import.c | 10 ++++- src/lib/object.c | 8 ++-- src/lib/opfunc.c | 7 ++- src/lib/prim.c | 11 +++-- src/lib/ptr.c | 5 +-- src/lib/string.c | 2 +- src/lib/tuple.c | 8 ++-- src/parse/check.c | 22 ++++------ src/parse/operator.c | 18 ++++---- tests/error/if_exp_invalid_cond.gw | 2 - tests/error/invalid_for.gw | 2 - tests/error/invalid_until.gw | 2 - tests/error/invalid_while.gw | 2 - 20 files changed, 92 insertions(+), 114 deletions(-) delete mode 100644 tests/error/if_exp_invalid_cond.gw delete mode 100644 tests/error/invalid_for.gw delete mode 100644 tests/error/invalid_until.gw delete mode 100644 tests/error/invalid_while.gw diff --git a/include/emit.h b/include/emit.h index fdfe3dfc..414f6c6c 100644 --- a/include/emit.h +++ b/include/emit.h @@ -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); diff --git a/include/gwi.h b/include/gwi.h index 7bd75d85..8e9300f1 100644 --- a/include/gwi.h +++ b/include/gwi.h @@ -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 { diff --git a/include/import.h b/include/import.h index ba881589..e9ae4665 100644 --- a/include/import.h +++ b/include/import.h @@ -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); diff --git a/include/operator.h b/include/operator.h index f7f8dbf0..9df6637f 100644 --- a/include/operator.h +++ b/include/operator.h @@ -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 diff --git a/src/emit/emit.c b/src/emit/emit.c index f64d88f9..88530019 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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)) diff --git a/src/lib/array.c b/src/lib/array.c index 974425b4..0ecec885 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -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 diff --git a/src/lib/func.c b/src/lib/func.c index 6167e2b0..24c31a82 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -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)) diff --git a/src/lib/import.c b/src/lib/import.c index 3170b796..10103aa2 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -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; diff --git a/src/lib/object.c b/src/lib/object.c index 48c09e40..482f66af 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -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)) diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 876cef5e..28ddad2f 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -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); } diff --git a/src/lib/prim.c b/src/lib/prim.c index e6788d6f..8a4048c9 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -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)) diff --git a/src/lib/ptr.c b/src/lib/ptr.c index d1465cdb..80d571d2 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -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) { diff --git a/src/lib/string.c b/src/lib/string.c index 4cee1dd1..d323bbce 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -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) : "") diff --git a/src/lib/tuple.c b/src/lib/tuple.c index b3a55d25..a7d94469 100644 --- a/src/lib/tuple.c +++ b/src/lib/tuple.c @@ -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) { diff --git a/src/parse/check.c b/src/parse/check.c index 9a3b9c21..f6fbbb71 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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) || diff --git a/src/parse/operator.c b/src/parse/operator.c index 169df4d2..c8fd1fe5 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -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 index 98a16df3..00000000 --- a/tests/error/if_exp_invalid_cond.gw +++ /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 index 9e8dce9c..00000000 --- a/tests/error/invalid_for.gw +++ /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 index 3314df6e..00000000 --- a/tests/error/invalid_until.gw +++ /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 index bf2235d2..00000000 --- a/tests/error/invalid_while.gw +++ /dev/null @@ -1,2 +0,0 @@ -#! [contains] in 'while' condition -while(null); -- 2.43.0