]> Nishi Git Mirror - gwion.git/commitdiff
:art: More on unary captures
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 26 Apr 2022 11:15:55 +0000 (13:15 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 26 Apr 2022 11:15:55 +0000 (13:15 +0200)
include/parse.h
src/emit/emit.c
src/lib/lib_func.c
src/parse/check.c
src/parse/scan1.c

index f70845fbd0465e7e25a7eecdd57febcf067aa148..6617a81ef5c116e745d372c2c0d0deb1a43a19f3 100644 (file)
@@ -115,4 +115,9 @@ static inline bool exp_is_zero(const Exp exp) {
   !exp->d.prim.d.num;
 }
 
+ANN static inline bool not_upvalue(const Env env, const Value v) {
+  return GET_FLAG(v, global) || vflag(v, vflag_fglobal) ||
+      (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) ||
+      nspc_lookup_value1(env->curr, insert_symbol(v->name));
+}
 #endif
index 4b3fcd975827b5cce39bfc637f1018bee10acb40..bf6c440da08be9c0b18e6de500236be5aa5416a4 100644 (file)
@@ -1951,11 +1951,22 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary *unary) {
   if(!sporker.is_spork)
     emit_local_exp(emit, exp_self(unary));
   spork_ini(emit, &sporker);
-
-if(sporker.captures) {
+  // add this if needed
+  uint32_t offset = 0;
+  if(emit->env->class_def && sporker.code) {
+    struct Exp_ exp = {
+      .d = { .prim = {
+        .d = { .var = insert_symbol("this") },
+          .prim_type = ae_prim_id
+        }},
+      .type = emit->env->class_def,
+      .exp_type = ae_exp_primary
+    };
+    emit_exp(emit, &exp);
+    offset += SZ_INT;
+  }
+  if(sporker.captures) {
     Capture_List caps = sporker.captures;
-// what about types?
-    uint32_t offset = 0;
     for (uint32_t i = 0; i < caps->len; i++) {
       Capture *cap = mp_vector_at(caps, Capture, i);
       const Value v = nspc_lookup_value1(emit->env->curr, cap->xid);
@@ -1968,17 +1979,16 @@ if(sporker.captures) {
         .type = v->type,
         .exp_type = ae_exp_primary
       };
-// handle emit var?
-//exp_setvar(&exp, false);
+      if(cap->is_ref) exp_setvar(&exp, true);
+      offset += exp_size(&exp);
       emit_exp(emit, &exp);
     }
-//      pop_exp(emit, &exp);
-regpop(emit, SZ_INT);
+  }
+  if(offset) {
+    regpop(emit, offset);
     const Instr args  = emit_add_instr(emit, SporkCode);
-    args->m_val       = 8; //emit->code->stack_depth;
+    args->m_val       = offset;
   }
-
-//    emit_local_exp(emit, exp_self(unary));
   (unary->unary_type == unary_code ? spork_code : spork_func)(emit, &sporker);
   return GW_OK;
 }
@@ -2537,6 +2547,7 @@ nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v);
 
 ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) {
   const uint n = emit->info->unroll;
+  nspc_push_value(emit->gwion->mp, emit->env->curr);
 
   CHECK_BB(emit_exp(emit, stmt->exp)); // add ref?
   regpop(emit, SZ_INT);
@@ -2550,6 +2561,7 @@ ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) {
   m_uint       end_pc = 0;
   const m_bool ret    = _emit_stmt_each(emit, stmt, &end_pc);
   emit_pop_stack(emit, end_pc);
+nspc_pop_value(emit->gwion->mp, emit->env->curr);
   emit->info->unroll = 0;
   return ret;
 }
@@ -2936,6 +2948,7 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
     emit->code->stack_depth += type->size;
     arg->var_decl.value->from->offset = emit_localn(emit, type);
     emit_debug(emit, arg->var_decl.value);
+    nspc_add_value(emit->env->curr, insert_symbol(arg->var_decl.value->name), arg->var_decl.value);
   }
 }
 
@@ -3057,8 +3070,10 @@ ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
   const Func f = fdef->base->func;
   if (f->memoize && fflag(f, fflag_pure))
     CHECK_BB(emit_memoize(emit, fdef));
+  nspc_push_value(emit->gwion->mp, emit->env->curr); // handle
   CHECK_BB(emit_func_def_body(emit, fdef));
   emit_func_def_return(emit);
+  nspc_pop_value(emit->gwion->mp, emit->env->curr); // handle
   return GW_OK;
 }
 
index 3edb530d0848fd50e256c0ced79bd2a4ec73530f..78ed4caabd349c36d5c9c08764158964657087a5 100644 (file)
@@ -666,7 +666,7 @@ static OP_CHECK(opck_spork) {
   }
   if (unary->unary_type == unary_code) {
     if(unary->captures) {
-      uint32_t offset = 0;
+      uint32_t offset = !env->class_def ? 0 : SZ_INT;
       for(uint32_t i = 0; i < unary->captures->len; i++) {
         Capture *const cap = mp_vector_at(unary->captures, Capture, i);
         DECL_OO(const Type, t, = upvalue_type(env, cap));
@@ -686,7 +686,8 @@ static OP_CHECK(opck_spork) {
     }
     const Func f = env->func;
     struct Value_ value = {};
-    set_vflag(&value, vflag_member);
+    if(env->class_def)
+      set_vflag(&value, vflag_member);
     struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = scope};
     struct Func_Def_ fdef = { .base = &fbase};
     struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
index a374bf54b9bfcd370e47610bc196ec730720635b..4318a512cd6540cbba181081fd189f1aa07daef7 100644 (file)
@@ -326,12 +326,6 @@ static inline Nspc value_owner(const Env env, const Value v) {
   return v ? v->from->owner : env->curr;
 }
 
-ANN bool not_upvalue(const Env env, const Value v) {
-  return GET_FLAG(v, global) || vflag(v, vflag_fglobal) ||
-      (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) ||
-      nspc_lookup_value1(env->curr, insert_symbol(v->name));
-}
-
 ANN static m_bool check_upvalue(const Env env, const Exp_Primary *prim) {
   const Value v = prim->value;
   if(not_upvalue(env, v))
index 8dba5259a2a96782b85bd574855c1b4ee61fe82e..28a31518e519b8d1fe4c8ca646eeaf8990bb215b 100644 (file)
@@ -236,6 +236,7 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If *exp_if) {
 ANN static inline m_bool scan1_exp_unary(const restrict Env env,
                                          Exp_Unary *const  unary) {
   if (unary->unary_type == unary_code) {
+/*
 if(strcmp("fork", s_name(unary->op))) {
     const loc_t pos = exp_self(unary)->pos;
     const Symbol sym = lambda_name(env->gwion->st, pos.first);
@@ -245,7 +246,7 @@ if(strcmp("fork", s_name(unary->op))) {
     mp_free(env->gwion->mp, Stmt, unary->code);
     unary->exp = new_exp_call(env->gwion->mp, lambda, NULL, pos);
     unary->unary_type = unary_exp;
-} else {
+} else */{
 return scan1_stmt(env, unary->code);
 }