]> Nishi Git Mirror - gwion.git/commitdiff
:art: Expose internal operator
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 20 Sep 2019 22:49:21 +0000 (00:49 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 20 Sep 2019 22:49:21 +0000 (00:49 +0200)
ast
include/import.h
src/emit/emit.c
src/lib/opfunc.c
src/parse/check.c
src/parse/operator.c
src/parse/scan2.c
tests/tree/class_union.gw
tests/tree/union.gw

diff --git a/ast b/ast
index 59f147324289f644940968e3125cef2bde3a3f94..0a0c0d67d0ccfd81b1011e917e031a364fc07d6f 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 59f147324289f644940968e3125cef2bde3a3f94
+Subproject commit 0a0c0d67d0ccfd81b1011e917e031a364fc07d6f
index e9ae46652a1c8e8d13adab4ee46b46e1ff9c9cbf..d8bd808def35175edf5000ee87b2eceb3f99a027 100644 (file)
@@ -78,6 +78,7 @@ OP_CHECK(opck_post);
 OP_CHECK(opck_rassign);
 OP_CHECK(opck_rhs_emit_var);
 OP_CHECK(opck_basic_cast);
+OP_CHECK(opck_usr_implicit);
 OP_CHECK(opck_new);
 OP_EMIT(opem_basic_cast);
 OP_EMIT(opem_new);
index 594535dc96287bf1406e9ba35b1fab2eeaeef6d0..4577270c91161e5dba63b4a1578f73a4f139b190 100644 (file)
@@ -1112,8 +1112,9 @@ ANN static m_bool emit_implicit_cast(const Emitter emit,
 }
 
 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 };
+  CHECK_BO(emit_exp_pop_next(emit, e, 1))
+  struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+                           .rhs=e->type, .pos=e->pos, .data=(uintptr_t)e};
   return op_emit(emit, &opi);
 }
 #define emit_flow(emit,b) _flow(emit, b, 1)
@@ -1433,8 +1434,9 @@ ANN static m_bool emit_stmt_exp(const Emitter emit, const struct Stmt_Exp_* exp)
 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 };
+  const Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
+  struct Exp_ ebin = { .d={.exp_binary=bin}, .nspc=emit->env->curr};
+  struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type, .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos };
   CHECK_OB(op_emit(emit, &opi))
   regpop(emit, base->type->size);
   return GW_OK;
index 28ddad2f9fb7d447a3e1ece52569a95abe253f7d..0f4a9dfc1bcc977f3d37a7a0257da794c450e232 100644 (file)
@@ -23,6 +23,12 @@ OP_CHECK(opck_basic_cast) {
      exp_self(cast)->type : t_null;
 }
 
+OP_CHECK(opck_usr_implicit) {
+  struct Implicit* imp = (struct Implicit*)data;
+  imp->e->cast_to = imp->t;
+  return imp->t;
+}
+
 OP_EMIT(opem_basic_cast) {
   return (Instr)GW_OK;
 }
index a9851dc74ea4a2c122b0d133b7be8a5173d77daa..d60921333843ee034a0ef80e99cd445482552c2f 100644 (file)
@@ -157,20 +157,25 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   return decl->type;
 }
 
-ANN static m_bool prim_array_inner(const Env env, const Type t, Type type, const Exp e) {
-  const Type common = find_common_anc(t, type);
+
+ANN static inline void set_cast(const Env env, Type type, const Exp e) {
+  e->cast_to = type;
+  e->nspc = env->curr;
+}
+
+ANN static m_bool prim_array_inner(const Env env, Type type, const Exp e) {
+  const Type common = find_common_anc(e->type, type);
   if(common)
     return GW_OK;
-  else if(isa(t, t_int) > 0 && isa(type, t_float) > 0) {
-      e->cast_to = type;
-      return GW_OK;
-  }
-  ERR_B(e->pos, _("array init [...] contains incompatible types ..."))
+  else if(!(isa(e->type, t_int) > 0 && isa(type, t_float) > 0))
+    ERR_B(e->pos, _("array init [...] contains incompatible types ..."))
+  set_cast(env, type, e);
+  return GW_OK;
 }
 
 ANN static inline Type prim_array_match(const Env env, Exp e) {
   const Type type = e->type;
-  do CHECK_BO(prim_array_inner(env, e->type, type, e))
+  do CHECK_BO(prim_array_inner(env, type, e))
   while((e = e->next));
   return array_type(env, type->array_depth ? array_base(type) : type, type->array_depth + 1);
 }
@@ -283,7 +288,7 @@ ANN static m_bool vec_value(const Env env, Exp e, const m_str s) {
     const Type t = e->type;
     if(isa(t, t_float) < 0) {
       if(isa(t, t_int) > 0)
-        e->cast_to = t_float;
+        set_cast(env, t_float, e);
       else
         ERR_B(e->pos, _("invalid type '%s' in %s value #%d...\n"
               "    (must be of type 'int' or 'float')"), t->name, s, count)
@@ -463,7 +468,7 @@ ANN static m_bool func_match_inner(const Env env, const Exp e, const Type t,
         const struct Implicit imp = { e, t, e->pos };
         struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=e->type, .rhs=t, .data=(m_uint)&imp, .pos=e->pos };
         return op_check(env, &opi) ? GW_OK : GW_ERROR;
-    }
+      }
   }
   return match ? 1 : -1;
 }
@@ -866,16 +871,18 @@ 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 _flow(const Env env, const Exp e, const m_bool b) {
+  DECL_OO(const Type, type, = check_exp(env, e))
+  struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+    .rhs=type, .pos=e->pos, .data=(uintptr_t)e };
+  return op_check(env, &opi);
 }
+#define check_flow(emit,b) _flow(emit, b, 1)
 
 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, 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))
-  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,
@@ -1020,7 +1027,6 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) {
       array.depth = depth;
       td.array = &array;
     }
-//    ptr = type_decl_resolve(env, &td); exit(3);
     ptr = known_type(env, &td);
     if(!GET_FLAG(ptr, checked))
       check_class_def(env, ptr->e->def);
@@ -1041,24 +1047,25 @@ ANN static m_bool cond_type(const Env env, const Exp e) {
     return GW_OK;
   if(isa(t, t_float) > 0) {
     e->cast_to = t_int;
+    e->nspc = env->curr;
     return GW_OK;
   }
   ERR_B(e->pos, _("conditional must be of type 'int'..."))
 }
 #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) < 0   ||
+stmt_func_xxx(if, Stmt_If,, !(!check_flow(env, stmt->cond)   ||
   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) < 0 ||
+    !_flow(env, stmt->cond, !stmt->is_do ?
+       stmt_self(stmt)->stmt_type == ae_stmt_while :
+       stmt_self(stmt)->stmt_type != ae_stmt_while) ||
     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) < 0 ||
+  !check_flow(env, stmt->c2->d.stmt_exp.val) ||
   (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) ||
@@ -1189,7 +1196,7 @@ ANN static m_bool match_case_exp(const Env env, Exp e) {
 ANN static m_bool _check_stmt_case(const Env env, const Stmt_Match stmt) {
   CHECK_BB(match_case_exp(env, stmt->cond))
   if(stmt->when)
-    CHECK_OB(check_exp(env, stmt->when))
+    CHECK_OB(check_flow(env, stmt->when))
   return check_stmt_list(env, stmt->list);
 }
 
@@ -1329,15 +1336,6 @@ ANN static Value set_variadic(const Env env) {
   return variadic;
 }
 
-ANN static void operator_func(const Func f) {
-  const Arg_List a = f->def->base->args;
-  const m_bool is_unary = GET_FLAG(f->def, unary);
-  const Type l = is_unary ? NULL : a->type;
-  const Type r = is_unary ? a->type : a->next ? a->next->type : NULL;
-  struct Op_Import opi = { .op=f->def->base->xid, .lhs=l, .rhs=r, .data=(m_uint)f, .pos=f->def->pos };
-  operator_set_func(&opi);
-}
-
 ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
   const Func func = get_func(env, fdef);
   m_bool ret = GW_OK;
@@ -1370,8 +1368,6 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
       REM_REF(variadic, env->gwion)
     if(GET_FLAG(fdef, builtin))
       func->code->stack_depth = fdef->stack_depth;
-    else if(GET_FLAG(fdef, op))
-      operator_func(func);
   }
   if(fdef->base->tmpl)
     nspc_pop_type(env->gwion->mp, env->curr);
@@ -1398,7 +1394,7 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) {
   return GW_OK;
 }
 
-ANN /*static inline */void inherit(const Type t) {
+ANN static inline void inherit(const Type t) {
   const Nspc nspc = t->nspc, parent = t->e->parent->nspc;
   nspc->info->offset = parent->info->offset;
   if(parent->info->vtable.ptr)
index c8fd1fe58c1c5e7e010bcc370081bb999f26f8c8..c38d3f53015f2b1bf7bc5e4a24da462b73153113 100644 (file)
@@ -126,17 +126,17 @@ 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) {
-    if(ock->opi->rhs)
-      ((Exp_Binary*)ock->opi->data)->nspc = nspc;
-    else
-      ((Exp_Postfix*)ock->opi->data)->nspc = nspc;
-  } else
-    ((Exp_Unary*)ock->opi->data)->nspc = nspc;
+  if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit")) {
+    struct Implicit* imp = (struct Implicit*)ock->opi->data;
+    imp->e->nspc = nspc;
+    return;
+  }
+  if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@conditionnal") ||
+     ock->opi->op == insert_symbol(ock->env->gwion->st, "@unconditionnal")) {
+    ((Exp)ock->opi->data)->nspc = nspc;
+    return;
+  }
+  exp_self((union exp_data*)ock->opi->data)->nspc = nspc;
 }
 
 ANN static Type op_check_inner(struct OpChecker* ock) {
@@ -195,27 +195,27 @@ ANN m_bool operator_set_func(const struct Op_Import* opi) {
 
 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);
+    const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode);
+    push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
+    const Instr instr = emit_exp_call1(emit, mo->func);
+    if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditionnal"))
+      return emit_add_instr(emit, BranchEqInt);
+    if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditionnal"))
+      return emit_add_instr(emit, BranchNeqInt);
+    return instr;
   }
   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")     ||
-    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;
-  if(opi->lhs) {
-    if(opi->rhs)
-      return ((Exp_Binary*)opi->data)->nspc;
-    else
-      return ((Exp_Postfix*)opi->data)->nspc;
+  if(opi->op == insert_symbol(st, "@implicit")) {
+    struct Implicit* imp = (struct Implicit*)opi->data;
+    return imp->e->nspc;
   }
-  return ((Exp_Unary*)opi->data)->nspc;
+  if(opi->op == insert_symbol(st, "@conditionnal") ||
+     opi->op == insert_symbol(st, "@unconditionnal"))
+    return ((Exp)opi->data)->nspc;
+  return exp_self((union exp_data*)opi->data)->nspc;
 }
 
 ANN static inline Nspc ensure_nspc(SymTable *st, const struct Op_Import* opi) {
index 64180c5be6c1097839396dceb65dba3d256cdf96..83c15b15f4c32a6c39ec75d19e55cb15c1c264a3 100644 (file)
 #include "parse.h"
 #include "nspc.h"
 #include "operator.h"
+#include "object.h"
+
+#include "instr.h"
+#include "import.h"
 
 ANN static m_bool scan2_stmt(const Env, const Stmt);
 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
@@ -398,13 +402,19 @@ ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str
 }
 
 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
-  assert(f->base->args);
-  const Type l = GET_FLAG(f, unary) ? NULL :
+  const m_str str = s_name(f->base->xid);
+  const uint is_unary = GET_FLAG(f, unary) + (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
+  const Type l = is_unary ? NULL :
     f->base->args->var_decl->value->type;
-  const Type r = GET_FLAG(f, unary) ? f->base->args->var_decl->value->type :
-    f->base->args->next ? f->base->args->next->var_decl->value->type : NULL;
-  struct Op_Import opi = { .op=f->base->xid, .lhs=l, .rhs=r, .ret=f->base->ret_type, .pos=f->pos };
+  const Type r = is_unary ? f->base->args->var_decl->value->type :
+    f->base->args->next ? f->base->args->next->var_decl->value->type :
+    f->base->ret_type;
+  struct Op_Import opi = { .op=f->base->xid, .lhs=l, .rhs=r, .ret=f->base->ret_type,
+                           .pos=f->pos, .data=(uintptr_t)f->base->func };
+  if(!strcmp(str, "@implicit"))
+    opi.ck = opck_usr_implicit;
   CHECK_BB(add_op(env->gwion, &opi))
+  operator_set_func(&opi);
   return GW_OK;
 }
 
index 89962f555b9109a870845be6d7bb41c4b48b3578..4a27e0e2d2280aa62959e5646ed0c30a9a7d9d8b 100644 (file)
@@ -2,7 +2,7 @@ class C {
        union
        {
          int one;
-         string two;
+         string two;
        };
        <<< one, " ", two >>>;
 }
index 92af3a6e353e36907029d1144eead26bbf02baa2..5cc3de061fd7daa8fe3923893e71768077af428c 100644 (file)
@@ -1,6 +1,6 @@
 union
 {
   int one;
-  string two;
+  string two;
 };
 <<< one, " ", two >>>;