From a867edb09c5cec073fbf0bf8451efce148c641c2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Fri, 18 Dec 2020 00:31:58 +0100 Subject: [PATCH] :bomb: Messed with git :confused: --- include/opcode.h | 12 ++++++++---- opcode.txt | 6 ++++-- src/emit/emit.c | 4 ++-- src/lib/prim.c | 34 ++++++++++++++++++++-------------- src/lib/union.c | 31 +++++++++++++++++++++---------- src/parse/check.c | 13 ++++++++++--- src/parse/scan1.c | 8 ++++++-- src/vm/vm.c | 44 ++++++++++++++++++++++++++++++++++++-------- 8 files changed, 107 insertions(+), 45 deletions(-) diff --git a/include/opcode.h b/include/opcode.h index 3a698a5b..84550cfb 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -163,8 +163,10 @@ enum { eDotMember2, eDotMember3, eDotMember4, - eUnionSet, - eUnionCheck, + eUnionMember, + eUnionMember2, + eUnionMember3, + eUnionMember4, eDotStatic, eDotStatic2, eDotStatic3, @@ -348,8 +350,10 @@ enum { #define DotMember2 (f_instr)eDotMember2 #define DotMember3 (f_instr)eDotMember3 #define DotMember4 (f_instr)eDotMember4 -#define UnionSet (f_instr)eUnionSet -#define UnionCheck (f_instr)eUnionCheck +#define UnionMember (f_instr)eUnionMember +#define UnionMember2 (f_instr)eUnionMember2 +#define UnionMember3 (f_instr)eUnionMember3 +#define UnionMember4 (f_instr)eUnionMember4 #define DotStatic (f_instr)eDotStatic #define DotStatic2 (f_instr)eDotStatic2 #define DotStatic3 (f_instr)eDotStatic3 diff --git a/opcode.txt b/opcode.txt index 3392b39a..58eae8de 100644 --- a/opcode.txt +++ b/opcode.txt @@ -160,8 +160,10 @@ DotMember DotMember2 DotMember3 DotMember4 -UnionSet -UnionCheck +UnionMember +UnionMember2 +UnionMember3 +UnionMember4 DotStatic DotStatic2 DotStatic3 diff --git a/src/emit/emit.c b/src/emit/emit.c index e8564449..b2246733 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -964,13 +964,13 @@ ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e) { ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) { const Exp lhs = bin->lhs; const Exp rhs = bin->rhs; - struct Op_Import opi = { .op=bin->op, .lhs=lhs->info->type, .rhs=rhs->info->type, - .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary }; CHECK_BB(emit_exp_pop_next(emit, lhs)) CHECK_BB(emit_exp_pop_next(emit, rhs)) const m_int size = exp_size(rhs); emit_exp_addref1(emit, lhs, -exp_size(lhs) - size); emit_exp_addref1(emit, rhs, -size); + struct Op_Import opi = { .op=bin->op, .lhs=lhs->info->type, .rhs=rhs->info->type, + .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary }; return op_emit(emit, &opi); } diff --git a/src/lib/prim.c b/src/lib/prim.c index ce258f8a..a5281ac3 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -28,10 +28,7 @@ GWION_IMPORT(int_op) { } static GWION_IMPORT(int_logical) { - GWI_BB(gwi_oper_end(gwi, "&&", int_and)) - GWI_BB(gwi_oper_end(gwi, "||", int_or)) - GWI_BB(gwi_oper_end(gwi, "==", int_eq)) - GWI_BB(gwi_oper_end(gwi, "!=", int_neq)) + GWI_BB(gwi_oper_ini(gwi, "int", "int", "int")) GWI_BB(gwi_oper_end(gwi, ">", int_gt)) GWI_BB(gwi_oper_end(gwi, ">=", int_ge)) GWI_BB(gwi_oper_end(gwi, "<", int_lt)) @@ -40,10 +37,16 @@ static GWION_IMPORT(int_logical) { GWI_BB(gwi_oper_end(gwi, "<<", int_sl)) GWI_BB(gwi_oper_end(gwi, "&", int_sand)) GWI_BB(gwi_oper_end(gwi, "|", int_sor)) - return gwi_oper_end(gwi, "^", int_xor); + GWI_BB(gwi_oper_end(gwi, "^", int_xor)) + GWI_BB(gwi_oper_ini(gwi, "int", "int", "bool")) + GWI_BB(gwi_oper_end(gwi, "&&", int_and)) + GWI_BB(gwi_oper_end(gwi, "||", int_or)) + GWI_BB(gwi_oper_end(gwi, "==", int_eq)) + return gwi_oper_end(gwi, "!=", int_neq); } static GWION_IMPORT(int_r) { + GWI_BB(gwi_oper_ini(gwi, "int", "int", "int")) CHECK_OP("=>", rassign, r_assign) CHECK_OP("+=>", rassign, r_plus) CHECK_OP("-=>", rassign, r_minus) @@ -154,10 +157,6 @@ static OP_CHECK(opck_implicit_i2f) { static GWION_IMPORT(intfloat) { GWI_BB(gwi_oper_ini(gwi, "int", "float", "int")) - GWI_BB(gwi_oper_end(gwi, "&&", int_float_and)) - GWI_BB(gwi_oper_end(gwi, "||", int_float_or)) - GWI_BB(gwi_oper_end(gwi, "==", int_float_eq)) - GWI_BB(gwi_oper_end(gwi, "!=", int_float_neq)) GWI_BB(gwi_oper_end(gwi, ">", int_float_gt)) GWI_BB(gwi_oper_end(gwi, ">=", int_float_ge)) GWI_BB(gwi_oper_end(gwi, "<", int_float_lt)) @@ -174,6 +173,11 @@ static GWION_IMPORT(intfloat) { CHECK_IF("/=>", rassign, r_div) _CHECK_OP("$", cast_i2f, CastI2F) _CHECK_OP("@implicit", implicit_i2f, CastI2F) + GWI_BB(gwi_oper_ini(gwi, "int", "float", "bool")) + GWI_BB(gwi_oper_end(gwi, "&&", int_float_and)) + GWI_BB(gwi_oper_end(gwi, "||", int_float_or)) + GWI_BB(gwi_oper_end(gwi, "==", int_float_eq)) + GWI_BB(gwi_oper_end(gwi, "!=", int_float_neq)) return GW_OK; } @@ -184,10 +188,6 @@ static GWION_IMPORT(floatint) { GWI_BB(gwi_oper_end(gwi, "*", float_int_mul)) GWI_BB(gwi_oper_end(gwi, "/", float_int_div)) GWI_BB(gwi_oper_ini(gwi, "float", "int", "int")) - GWI_BB(gwi_oper_end(gwi, "&&", float_int_and)) - GWI_BB(gwi_oper_end(gwi, "||", float_int_or)) - GWI_BB(gwi_oper_end(gwi, "==", float_int_eq)) - GWI_BB(gwi_oper_end(gwi, "!=", float_int_neq)) GWI_BB(gwi_oper_end(gwi, ">", float_int_gt)) GWI_BB(gwi_oper_end(gwi, ">=", float_int_ge)) GWI_BB(gwi_oper_end(gwi, "<", float_int_lt)) @@ -199,6 +199,11 @@ static GWION_IMPORT(floatint) { CHECK_FI("/=>", rassign, r_div) _CHECK_OP("$", cast_f2i, CastF2I) _CHECK_OP("@implicit", implicit_f2i, CastF2I) + GWI_BB(gwi_oper_ini(gwi, "float", "int", "bool")) + GWI_BB(gwi_oper_end(gwi, "&&", float_int_and)) + GWI_BB(gwi_oper_end(gwi, "||", float_int_or)) + GWI_BB(gwi_oper_end(gwi, "==", float_int_eq)) + GWI_BB(gwi_oper_end(gwi, "!=", float_int_neq)) return GW_OK; } @@ -276,11 +281,12 @@ static GWION_IMPORT(float) { CHECK_FF("-=>", rassign, r_minus) CHECK_FF("*=>", rassign, r_mul) CHECK_FF("/=>", rassign, r_div) - GWI_BB(gwi_oper_ini(gwi, "float", "float", "int")) + GWI_BB(gwi_oper_ini(gwi, "float", "float", "bool")) GWI_BB(gwi_oper_end(gwi, "&&", float_and)) GWI_BB(gwi_oper_end(gwi, "||", float_or)) GWI_BB(gwi_oper_end(gwi, "==", float_eq)) GWI_BB(gwi_oper_end(gwi, "!=", float_neq)) + GWI_BB(gwi_oper_ini(gwi, "float", "float", "int")) GWI_BB(gwi_oper_end(gwi, ">", float_gt)) GWI_BB(gwi_oper_end(gwi, ">=", float_ge)) GWI_BB(gwi_oper_end(gwi, "<", float_lt)) diff --git a/src/lib/union.c b/src/lib/union.c index d02f6ae1..d9b770a7 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -11,6 +11,7 @@ #include "gwi.h" #include "specialid.h" #include "gack.h" +#include "traverse.h" static GACK(gack_none) { INTERP_PRINTF("None") @@ -29,8 +30,7 @@ static OP_EMIT(opem_none) { return GW_OK; } -static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 }; - +static const f_instr unionmember[] = { UnionMember, UnionMember2, UnionMember3, UnionMember4 }; ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]); static OP_EMIT(opem_union_dot) { @@ -43,15 +43,16 @@ static OP_EMIT(opem_union_dot) { instr->m_val = (m_uint)f->code; return GW_OK; } + if(!strcmp(s_name(member->xid), "@index")) { + emit_add_instr(emit, DotMember); + return GW_OK; + } for(m_uint i = 0; i < map_size(map); ++i) { if(VKEY(map, i) == (m_uint)member->xid) { const Value v = (Value)VVAL(map, i); const uint emit_addr = exp_getvar(exp_self(member)); - const Instr pre = emit_add_instr(emit, - !emit_addr ? UnionCheck : UnionSet); - pre->m_val = i + 1; - const Instr instr = emit_kind(emit, v->type->size, emit_addr, dotmember); - instr->m_val = SZ_INT; + const Instr instr = emit_kind(emit, v->type->size, emit_addr, unionmember); + instr->m_val = i + 1; instr->m_val2 = v->type->size; return GW_OK; } @@ -83,9 +84,19 @@ static OP_CHECK(opck_union_is) { for(m_uint i = 0; i < map_size(map); ++i) { const Value v = (Value)VVAL(map, i); if(!strcmp(s_name(exp->d.prim.d.var), v->name)) { - exp->d.prim.prim_type = ae_prim_num; - exp->d.prim.d.num = i+1; - return env->gwion->type[et_bool]; + *mut = 1; + const Exp exp_func = call->func; + const Exp exp_base = call->func->d.exp_dot.base; + const Exp exp_args = call->args; + e->exp_type = ae_exp_binary; + e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func); + e->d.exp_binary.lhs->d.exp_dot.xid = insert_symbol(env->gwion->st, "@index"); + e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, loc_cpy(env->gwion->mp, e->pos)); + free_exp(env->gwion->mp, exp_func); + free_exp(env->gwion->mp, exp_args); + e->d.exp_binary.op = insert_symbol(env->gwion->st, "=="); + CHECK_OO(check_exp(env, e)) + return e->info->type; } } return env->gwion->type[et_error]; diff --git a/src/parse/check.c b/src/parse/check.c index cfa39e0c..bf90bd57 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -703,14 +703,18 @@ ANN m_bool func_check(const Env env, const Exp_Call *exp) { const Type t = actual_type(env->gwion, exp->func->info->type); const Exp e = exp_self(exp); struct Op_Import opi = { .op=insert_symbol("@func_check"), - .rhs=t, .pos=exp_self(exp)->pos, .data=(uintptr_t)e, .op_type=op_exp }; + .rhs=t, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp }; CHECK_NB(op_check(env, &opi)) // doesn't really return NULL + if(e->exp_type != ae_exp_call) + return 0; return e->info->type != env->gwion->type[et_error] ? GW_OK : GW_ERROR; } ANN Type check_exp_call1(const Env env, const Exp_Call *exp) { - CHECK_BO(func_check(env, exp)) + DECL_BO(const m_bool, ret, = func_check(env, exp)) + if(!ret) + return exp_self(exp)->info->type; const Type t = actual_type(env->gwion, exp->func->info->type); if(isa(t, env->gwion->type[et_function]) < 0) { // use func flag? @@ -789,7 +793,10 @@ ANN static m_bool predefined_call(const Env env, const Type t, const loc_t pos) ANN static Type check_exp_call(const Env env, Exp_Call* exp) { if(exp->tmpl) { - CHECK_BO(func_check(env, exp)) +// CHECK_BO(func_check(env, exp)) + DECL_BO(const m_bool, ret, = func_check(env, exp)) + if(!ret) + return exp_self(exp)->info->type; const Type t = actual_type(env->gwion, exp->func->info->type); if(isa(t, env->gwion->type[et_function]) < 0) return check_exp_call1(env, exp); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 44699f98..8377b33c 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -397,19 +397,23 @@ ANN static inline m_bool scan1_union_def_inner_loop(const Env env, Union_Def ude nspc_allocdata(env->gwion->mp, udef->type->nspc); Union_List l = udef->l; m_uint sz = 0; + const Value v = new_value(env->gwion->mp, env->gwion->type[et_int], "@index"); + nspc_add_value_front(env->curr, insert_symbol("@index"), v); + valuefrom(env ,v->from); do { DECL_OB(const Type, t, = known_type(env, l->td)) if(nspc_lookup_value0(env->curr, l->xid)) ERR_B(l->pos, _("'%s' already declared in union"), s_name(l->xid)) const Value v = new_value(env->gwion->mp, t, s_name(l->xid)); - if(!tflag(t, tflag_scan1)) - tuple_contains(env, v); + if(!tflag(t, tflag_scan1)) // ??? + tuple_contains(env, v); // ??? v->from->offset = SZ_INT; valuefrom(env ,v->from); nspc_add_value_front(env->curr, l->xid, v); if(t->size > sz) sz = t->size; } while((l = l->next)); +udef->type->nspc->info->offset = SZ_INT +sz; return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 45dc6e37..f0263392 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -324,7 +324,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid, &&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, - &&unionset, &&unioncheck, + &&unionint, &&unionfloat, &&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother, &&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr, &&dotfunc, &&dotstaticfunc, @@ -825,15 +825,43 @@ PRAGMA_POP() dotaddr: *(m_bit**)(reg-SZ_INT) = ((*(M_Object*)(reg-SZ_INT))->data + VAL); DISPATCH() -unionset: - *(m_uint*)(*(M_Object*)(reg-SZ_INT))->data = VAL; - DISPATCH() -unioncheck: - if(*(m_uint*)(*(M_Object*)(reg-SZ_INT))->data != VAL) { - exception(shred, "invalid union acces"); - continue; + +#define UNION_CHECK\ + register const m_bit *data = (*(M_Object*)(reg-SZ_INT))->data;\ + if(*(m_uint*)data != VAL) {\ + exception(shred, "invalid union acces");\ + continue;\ } + +unionint: +{ + UNION_CHECK + *(m_uint*)(reg-SZ_INT) = *(m_uint*)(data + SZ_INT); + DISPATCH() +} +unionfloat: +{ + UNION_CHECK + *(m_float*)(reg-SZ_INT) = *(m_float*)(data + SZ_INT); + reg += SZ_FLOAT - SZ_INT; + DISPATCH() +} +unionother: +{ + UNION_CHECK +PRAGMA_PUSH() + for(m_uint i = 0; i <= VAL2; i += SZ_INT) + *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)(data + SZ_INT + i); +PRAGMA_POP() + reg += VAL2 - SZ_INT; DISPATCH() +} +unionaddr: +{ + *(m_uint*)(*(M_Object*)(reg-SZ_INT))->data = VAL; + *(m_bit**)(reg - SZ_INT)= &*(m_bit*)((*(M_Object*)(reg-SZ_INT))->data + SZ_INT); + DISPATCH() +} staticint: *(m_uint*)reg = *(m_uint*)VAL; reg += SZ_INT; -- 2.43.0