]> Nishi Git Mirror - gwion.git/commitdiff
:bomb: Messed with git :confused:
authorJérémie Astor <fennecdjay@gmail.com>
Thu, 17 Dec 2020 23:31:58 +0000 (00:31 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Thu, 17 Dec 2020 23:38:28 +0000 (00:38 +0100)
include/opcode.h
opcode.txt
src/emit/emit.c
src/lib/prim.c
src/lib/union.c
src/parse/check.c
src/parse/scan1.c
src/vm/vm.c

index 3a698a5bf4ed9156dda10df842b84de816188769..84550cfb912dc5aa0587bd11d64b120da51a6286 100644 (file)
@@ -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
index 3392b39aaab24850caef84ecec0b781c79acbb0a..58eae8de6d87100117c44488d6e16a5103dc13b7 100644 (file)
@@ -160,8 +160,10 @@ DotMember
 DotMember2
 DotMember3
 DotMember4
-UnionSet
-UnionCheck
+UnionMember
+UnionMember2
+UnionMember3
+UnionMember4
 DotStatic
 DotStatic2
 DotStatic3
index e85644490aa31a09fa7a9fb7bec8d8a6ea7f3bad..b22467335db342eb2226c3a4c8be7d41658c8f48 100644 (file)
@@ -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);
 }
 
index ce258f8a685a88f0e1c4b0d0b0a55dfd6d8b5e5d..a5281ac38a338fc7cd264de567842ea25ee63efa 100644 (file)
@@ -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))
index d02f6ae12d2bc810e1516346b22f5aea677f45b8..d9b770a7cfe50048ee5dd068dbbfc45e9783c47f 100644 (file)
@@ -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];
index cfa39e0c62ef5a051e1bd6b3f6f84e5972f76b80..bf90bd57e588565a0df803641cb471dd147d38ed 100644 (file)
@@ -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);
index 44699f982ffbed4ea06e39aba24fdacaed2502c9..8377b33cb85c9dba7d8cb20cf04eb9558c76ee37 100644 (file)
@@ -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;
 }
 
index 45dc6e371bf776befbb8876cabdc2254247c9843..f0263392eac5c57dd2449e5b1c8d35e7c9f68c2f 100644 (file)
@@ -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;