]> Nishi Git Mirror - gwion.git/commitdiff
:art: Allow for index in foreach
authorJérémie Astor <fennecdjay@gmail.com>
Fri, 22 Jan 2021 12:25:06 +0000 (13:25 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Fri, 22 Jan 2021 12:25:06 +0000 (13:25 +0100)
ast
src/emit/emit.c
src/parse/check.c
src/parse/scan1.c

diff --git a/ast b/ast
index 664325fa5c67e0868dbd2cfa3bac2dce99ec3047..5e564441ae5a817734268a4b8d5dc03527216477 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 664325fa5c67e0868dbd2cfa3bac2dce99ec3047
+Subproject commit 5e564441ae5a817734268a4b8d5dc03527216477
index 0ba87f4d8f9b80fe7bec4ec19642e6322c6c38e0..dca1bc6faa1719471de5ab7e2b461b6202f59bf2 100644 (file)
@@ -1729,6 +1729,8 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_ui
   const Instr s1 = emit_add_instr(emit, MemSetImm);
   s1->m_val = offset + SZ_INT;
   stmt->v->from->offset = offset + SZ_INT*2;
+  if(stmt->idx)
+    stmt->vidx->from->offset = offset + SZ_INT;
   if(n) {
     const Instr instr = emit_add_instr(emit, AutoUnrollInit);
     instr->m_val = offset-SZ_INT;
index 5d7d39b84e518d8910a6417682f5d37f36833aa3..e302bf6dacd23d6f10906015159003d7d87912b1 100644 (file)
@@ -925,6 +925,11 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
   stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
   set_vflag(stmt->v, vflag_valid);
   nspc_add_value(env->curr, stmt->sym, stmt->v);
+  if(stmt->idx) {
+    stmt->vidx = new_value(env->gwion->mp, env->gwion->type[et_int], s_name(stmt->idx));
+    set_vflag(stmt->vidx, vflag_valid);
+    nspc_add_value(env->curr, stmt->idx, stmt->vidx);
+  }
   return check_conts(env, stmt_self(stmt), stmt->body);
 }
 
index d644ee850626c203e370d42c4b869520b8623e20..d6a7bd6e0e4b39892e741ae79db89a2b1898a255 100644 (file)
@@ -283,6 +283,14 @@ ANN static inline m_bool scan1_stmt_match(const restrict Env env, const Stmt_Mat
   RET_NSPC(_scan1_stmt_match(env, stmt))
 }
 
+ANN static inline m_bool stmt_each_defined(const restrict Env env, const Stmt_Each stmt) {
+  if(nspc_lookup_value1(env->curr, stmt->sym))
+    ERR_B(stmt_self(stmt)->pos, _("foreach value '%s' is already defined"), s_name(stmt->sym))
+  if(stmt->idx && nspc_lookup_value1(env->curr, stmt->idx))
+    ERR_B(stmt_self(stmt)->pos, _("foreach index '%s' is already defined"), s_name(stmt->idx))
+  return GW_OK;
+}
+
 #define describe_ret_nspc(name, type, prolog, exp) describe_stmt_func(scan1, name, type, prolog, exp)
 describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
@@ -292,7 +300,7 @@ describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 ||
     scan1_stmt(env, stmt->c2) < 0 ||
     (stmt->c3 && scan1_exp(env, stmt->c3) < 0) ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(each, Stmt_Each,, !(scan1_exp(env, stmt->exp) < 0 ||
+describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
 describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)