poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] pkl: trans: get rid of pkl_ast_finish_breaks


From: Mohammad-Reza Nabipoor
Subject: [PATCH] pkl: trans: get rid of pkl_ast_finish_breaks
Date: Thu, 14 Jul 2022 16:29:48 +0430

2022-07-14  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/pkl-ast.h (pkl_ast_finish_breaks): Remove.
        * libpoke/pkl-ast.c (pkl_ast_finish_breaks): Likewise.
        (pkl_ast_finish_breaks_1): Likewise.
        * libpoke/pkl-tab.y (stmt): Likewise.
        * libpoke/pkl-trans.h (struct pkl_trans_breakable_ctx): New struct.
        (PKL_TRANS_MAX_COMP_STMT_NEST): New macro.
        (struct pkl_trans_payload): Add new fields.
        * libpoke/pkl-trans.c (PKL_TRANS_BREAKABLE): New macro.
        (PKL_TRANS_PUSH_BREAKABLE): Likewise.
        (PKL_TRANS_POP_BREAKABLE): Likewise.
        (pkl_trans1_pr_comp_stmt): Add logic to track lexical frames around
        `break` and `continue` keywords.
        (pkl_trans1_ps_comp_stmt): Likewise.
        (pkl_trans1_pr_loop_stmt): Likewise.
        (pkl_trans1_ps_loop_stmt): Likewise.
        (pkl_trans1_pr_try_stmt_body): Likewise.
        (pkl_trans1_ps_try_stmt_body): Likewise.
        (pkl_trans1_pr_try_stmt): New handler.
        (pkl_trans1_ps_try_stmt): Likewise.
        (pkl_trans1_ps_break_stmt): Likewise.
        (pkl_trans1_ps_continue_stmt): Likewise.
        (pkl_phase_trans1): Register new handlers.
---
 ChangeLog           | 25 ++++++++++++
 libpoke/pkl-ast.c   | 86 ---------------------------------------
 libpoke/pkl-ast.h   |  2 -
 libpoke/pkl-tab.y   | 30 --------------
 libpoke/pkl-trans.c | 98 +++++++++++++++++++++++++++++++++++++++++++++
 libpoke/pkl-trans.h | 27 ++++++++++++-
 6 files changed, 149 insertions(+), 119 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5a220446..322f77cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2022-07-14  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/pkl-ast.h (pkl_ast_finish_breaks): Remove.
+       * libpoke/pkl-ast.c (pkl_ast_finish_breaks): Likewise.
+       (pkl_ast_finish_breaks_1): Likewise.
+       * libpoke/pkl-tab.y (stmt): Likewise.
+       * libpoke/pkl-trans.h (struct pkl_trans_breakable_ctx): New struct.
+       (PKL_TRANS_MAX_COMP_STMT_NEST): New macro.
+       (struct pkl_trans_payload): Add new fields.
+       * libpoke/pkl-trans.c (PKL_TRANS_BREAKABLE): New macro.
+       (PKL_TRANS_PUSH_BREAKABLE): Likewise.
+       (PKL_TRANS_POP_BREAKABLE): Likewise.
+       (pkl_trans1_pr_comp_stmt): Add logic to track lexical frames around
+       `break` and `continue` keywords.
+       (pkl_trans1_ps_comp_stmt): Likewise.
+       (pkl_trans1_pr_loop_stmt): Likewise.
+       (pkl_trans1_ps_loop_stmt): Likewise.
+       (pkl_trans1_pr_try_stmt_body): Likewise.
+       (pkl_trans1_ps_try_stmt_body): Likewise.
+       (pkl_trans1_pr_try_stmt): New handler.
+       (pkl_trans1_ps_try_stmt): Likewise.
+       (pkl_trans1_ps_break_stmt): Likewise.
+       (pkl_trans1_ps_continue_stmt): Likewise.
+       (pkl_phase_trans1): Register new handlers.
+
 2022-07-13  Jose E. Marchesi  <jemarch@gnu.org>
 
        * libpoke/pkl-trans.h (struct pkl_trans_function_ctx): Define.
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index ee7fd800..dd0eef9e 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -2625,92 +2625,6 @@ pkl_ast_reverse (pkl_ast_node ast)
   return prev;
 }
 
-/* Annotate the break and continue statements within a given entity
-   (loop or switch or...) with a pointer to the entity and their
-   lexical nest level within the entity.  */
-
-static void
-pkl_ast_finish_breaks_1 (pkl_ast_node entity, pkl_ast_node stmt,
-                         int *nframes)
-{
-  /* STMT can be a statement or a declaration.  */
-
-  switch (PKL_AST_CODE (stmt))
-    {
-    case PKL_AST_BREAK_STMT:
-      PKL_AST_BREAK_STMT_ENTITY (stmt) = entity; /* Note no ASTREF */
-      PKL_AST_BREAK_STMT_NFRAMES (stmt) = *nframes;
-      break;
-    case PKL_AST_CONTINUE_STMT:
-      PKL_AST_CONTINUE_STMT_ENTITY (stmt) = entity; /* Note no ASTREF */
-      PKL_AST_CONTINUE_STMT_NFRAMES (stmt) = *nframes;
-      break;
-    case PKL_AST_COMP_STMT:
-      {
-        pkl_ast_node t;
-
-        *nframes += 1;
-        for (t = PKL_AST_COMP_STMT_STMTS (stmt); t;
-             t = PKL_AST_CHAIN (t))
-          pkl_ast_finish_breaks_1 (entity, t, nframes);
-
-        /* Pop the frame of the compound itself.  */
-        *nframes -= 1;
-        break;
-      }
-    case PKL_AST_IF_STMT:
-      pkl_ast_finish_breaks_1 (entity,
-                               PKL_AST_IF_STMT_THEN_STMT (stmt),
-                               nframes);
-      if (PKL_AST_IF_STMT_ELSE_STMT (stmt))
-        pkl_ast_finish_breaks_1 (entity,
-                                 PKL_AST_IF_STMT_ELSE_STMT (stmt),
-                                 nframes);
-      break;
-    case PKL_AST_TRY_STMT_BODY:
-      pkl_ast_finish_breaks_1 (entity,
-                               PKL_AST_TRY_STMT_BODY_CODE (stmt),
-                               nframes);
-      break;
-    case PKL_AST_TRY_STMT:
-      pkl_ast_finish_breaks_1 (entity,
-                               PKL_AST_TRY_STMT_BODY (stmt),
-                               nframes);
-
-      if (PKL_AST_TRY_STMT_KIND (stmt) == PKL_AST_TRY_STMT_KIND_CATCH)
-        {
-          if (PKL_AST_TRY_STMT_ARG (stmt))
-            *nframes += 1;
-          pkl_ast_finish_breaks_1 (entity,
-                                   PKL_AST_TRY_STMT_HANDLER (stmt),
-                                   nframes);
-          if (PKL_AST_TRY_STMT_ARG (stmt))
-            *nframes -=1;
-        }
-      break;
-    case PKL_AST_DECL:
-    case PKL_AST_RETURN_STMT:
-    case PKL_AST_LOOP_STMT:
-    case PKL_AST_LOOP_STMT_ITERATOR:
-    case PKL_AST_EXP_STMT:
-    case PKL_AST_ASS_STMT:
-    case PKL_AST_PRINT_STMT:
-    case PKL_AST_RAISE_STMT:
-    case PKL_AST_NULL_STMT:
-      break;
-    default:
-      assert (0);
-      break;
-    }
-}
-
-void
-pkl_ast_finish_breaks (pkl_ast_node entity, pkl_ast_node stmt)
-{
-  int nframes = 0;
-  pkl_ast_finish_breaks_1 (entity, stmt, &nframes);
-}
-
 pkl_ast_node
 pkl_ast_type_incr_step (pkl_ast ast, pkl_ast_node type)
 {
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index 8447f6eb..06e0a42b 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -1898,8 +1898,6 @@ struct pkl_ast_break_stmt
 
 pkl_ast_node pkl_ast_make_break_stmt (pkl_ast ast);
 
-void pkl_ast_finish_breaks (pkl_ast_node entity, pkl_ast_node stmt);
-
 /* PKL_AST_RAISE_STMT nodes represent `raise' statements, which are
    used in order to raise exceptions at the program level.
 
diff --git a/libpoke/pkl-tab.y b/libpoke/pkl-tab.y
index 334c3ec0..7f0f1a30 100644
--- a/libpoke/pkl-tab.y
+++ b/libpoke/pkl-tab.y
@@ -2334,11 +2334,6 @@ stmt:
                                                NULL, /* tail */
                                                $5);  /* body */
                   PKL_AST_LOC ($$) = @$;
-
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $5);
                 }
         | FOR '(' pushlevel simple_declaration ';' expression_opt ';' 
simple_stmt_list ')' stmt
                 {
@@ -2351,11 +2346,6 @@ stmt:
                                                $10); /* body */
                   PKL_AST_LOC ($$) = @$;
 
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $10);
-
                   /* Pop the frame introduced by `pushlevel'
                      above.  */
                   pkl_parser->env = pkl_env_pop_frame (pkl_parser->env);
@@ -2370,11 +2360,6 @@ stmt:
                                                $6,   /* tail */
                                                $8);  /* body */
 
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $8);
-
                   PKL_AST_LOC ($$) = @$;
                 }
         | FOR '(' IDENTIFIER IN expression pushlevel
@@ -2421,11 +2406,6 @@ stmt:
                   /* Free the identifier.  */
                   $3 = ASTREF ($3); pkl_ast_node_free ($3);
 
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $9);
-
                   /* Pop the frame introduced by `pushlevel'
                      above.  */
                   pkl_parser->env = pkl_env_pop_frame (pkl_parser->env);
@@ -2474,11 +2454,6 @@ stmt:
                   PKL_AST_LOC ($3) = @3;
                   PKL_AST_LOC ($$) = @$;
 
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $11);
-
                   /* Pop the frame introduced by `pushlevel'
                      above.  */
                   pkl_parser->env = pkl_env_pop_frame (pkl_parser->env);
@@ -2553,11 +2528,6 @@ stmt:
                                               NULL /* arg */, $4);
                   PKL_AST_LOC (body) = @2;
                   PKL_AST_LOC ($$) = @$;
-
-                  /* Annotate the contained BREAK and CONTINUE
-                     statements with their lexical level within this
-                     loop.  */
-                  pkl_ast_finish_breaks ($$, $2);
                 }
         | RAISE ';'
                 {
diff --git a/libpoke/pkl-trans.c b/libpoke/pkl-trans.c
index 4d27cbe3..2503b253 100644
--- a/libpoke/pkl-trans.c
+++ b/libpoke/pkl-trans.c
@@ -128,6 +128,30 @@ pkl_trans_in_functions (struct pkl_trans_function_ctx 
functions[],
     }                                                           \
   while (0)
 
+#define PKL_TRANS_BREAKABLE                                     \
+  (PKL_TRANS_PAYLOAD->next_breakable == 0                       \
+   ? NULL                                                       \
+   : &PKL_TRANS_PAYLOAD->breakables[PKL_TRANS_PAYLOAD->next_breakable - 1])
+
+#define PKL_TRANS_PUSH_BREAKABLE(b)                             \
+  do                                                            \
+    {                                                           \
+      assert (PKL_TRANS_PAYLOAD->next_breakable < 
PKL_TRANS_MAX_COMP_STMT_NEST);\
+      PKL_TRANS_PAYLOAD->breakables[PKL_TRANS_PAYLOAD->next_breakable].nframes 
 \
+        = 0;                                                    \
+      
PKL_TRANS_PAYLOAD->breakables[PKL_TRANS_PAYLOAD->next_breakable++].breakable \
+        = (b);                                                  \
+    }                                                           \
+  while (0)
+
+#define PKL_TRANS_POP_BREAKABLE                                 \
+  do                                                            \
+    {                                                           \
+      assert (PKL_TRANS_PAYLOAD->next_breakable > 0);           \
+      PKL_TRANS_PAYLOAD->next_breakable--;                      \
+    }                                                           \
+  while (0)
+
 /* The following handler is used in all trans phases and initializes
    the phase payload.  */
 
@@ -1095,6 +1119,17 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_comp_stmt)
       PKL_TRANS_FUNCTION->ndrops++;
       PKL_TRANS_FUNCTION->npopes++;
     }
+
+  if (PKL_TRANS_BREAKABLE)
+    {
+      PKL_TRANS_BREAKABLE->nframes++;
+
+      /* try {} catch (Exception e) { if_we_are_here; } */
+      if (PKL_AST_CODE (PKL_PASS_PARENT) == PKL_AST_TRY_STMT
+          && PKL_AST_TRY_STMT_ARG (PKL_PASS_PARENT)
+          && PKL_AST_TRY_STMT_HANDLER (PKL_PASS_PARENT) == PKL_PASS_NODE)
+        PKL_TRANS_BREAKABLE->nframes++;
+    }
 }
 PKL_PHASE_END_HANDLER
 
@@ -1121,6 +1156,8 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_loop_stmt)
 
   if (PKL_TRANS_FUNCTION && PKL_AST_LOOP_STMT_ITERATOR (stmt))
     PKL_TRANS_FUNCTION->ndrops += 3;
+
+  PKL_TRANS_PUSH_BREAKABLE (stmt);
 }
 PKL_PHASE_END_HANDLER
 
@@ -1135,6 +1172,8 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_loop_stmt)
   if (PKL_TRANS_FUNCTION
       && (PKL_TRANS_FUNCTION && PKL_AST_LOOP_STMT_ITERATOR (stmt)))
     PKL_TRANS_FUNCTION->ndrops -= 3;
+
+  PKL_TRANS_POP_BREAKABLE;
 }
 PKL_PHASE_END_HANDLER
 
@@ -1169,6 +1208,17 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_comp_stmt)
       PKL_TRANS_FUNCTION->ndrops--;
       PKL_TRANS_FUNCTION->npopes--;
     }
+
+  if (PKL_TRANS_BREAKABLE)
+    {
+      PKL_TRANS_BREAKABLE->nframes--;
+
+      /* try {} catch (Exception e) { if_we_are_here; } */
+      if (PKL_AST_CODE (PKL_PASS_PARENT) == PKL_AST_TRY_STMT
+          && PKL_AST_TRY_STMT_ARG (PKL_PASS_PARENT)
+          && PKL_AST_TRY_STMT_HANDLER (PKL_PASS_PARENT) == PKL_PASS_NODE)
+        PKL_TRANS_BREAKABLE->nframes--;
+    }
 }
 PKL_PHASE_END_HANDLER
 
@@ -1220,6 +1270,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_try_stmt_body)
 {
   if (PKL_TRANS_FUNCTION)
     PKL_TRANS_FUNCTION->npopes++;
+
+  if (PKL_AST_TRY_STMT_KIND (PKL_PASS_PARENT) == PKL_AST_TRY_STMT_KIND_UNTIL)
+    PKL_TRANS_PUSH_BREAKABLE (PKL_PASS_PARENT);
 }
 PKL_PHASE_END_HANDLER
 
@@ -1227,6 +1280,47 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_try_stmt_body)
 {
   if (PKL_TRANS_FUNCTION)
     PKL_TRANS_FUNCTION->npopes--;
+
+  if (PKL_AST_TRY_STMT_KIND (PKL_PASS_PARENT) == PKL_AST_TRY_STMT_KIND_UNTIL)
+    PKL_TRANS_POP_BREAKABLE;
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_try_stmt)
+{
+  if (PKL_AST_TRY_STMT_KIND (PKL_PASS_NODE) == PKL_AST_TRY_STMT_KIND_UNTIL)
+    PKL_TRANS_PUSH_BREAKABLE (PKL_PASS_NODE);
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_try_stmt)
+{
+  if (PKL_AST_TRY_STMT_KIND (PKL_PASS_NODE) == PKL_AST_TRY_STMT_KIND_UNTIL)
+    PKL_TRANS_POP_BREAKABLE;
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_break_stmt)
+{
+  if (PKL_TRANS_BREAKABLE)
+    {
+      PKL_AST_BREAK_STMT_ENTITY (PKL_PASS_NODE)
+        = PKL_TRANS_BREAKABLE->breakable;
+      PKL_AST_BREAK_STMT_NFRAMES (PKL_PASS_NODE)
+        = PKL_TRANS_BREAKABLE->nframes;
+    }
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_continue_stmt)
+{
+  if (PKL_TRANS_BREAKABLE)
+    {
+      PKL_AST_CONTINUE_STMT_ENTITY (PKL_PASS_NODE)
+        = PKL_TRANS_BREAKABLE->breakable;
+      PKL_AST_CONTINUE_STMT_NFRAMES (PKL_PASS_NODE)
+        = PKL_TRANS_BREAKABLE->nframes;
+    }
 }
 PKL_PHASE_END_HANDLER
 
@@ -1250,6 +1344,10 @@ struct pkl_phase pkl_phase_trans1 =
    PKL_PHASE_PS_HANDLER (PKL_AST_LOOP_STMT_ITERATOR, 
pkl_trans1_ps_loop_stmt_iterator),
    PKL_PHASE_PR_HANDLER (PKL_AST_LOOP_STMT, pkl_trans1_pr_loop_stmt),
    PKL_PHASE_PS_HANDLER (PKL_AST_LOOP_STMT, pkl_trans1_ps_loop_stmt),
+   PKL_PHASE_PS_HANDLER (PKL_AST_BREAK_STMT, pkl_trans1_ps_break_stmt),
+   PKL_PHASE_PS_HANDLER (PKL_AST_CONTINUE_STMT, pkl_trans1_ps_continue_stmt),
+   PKL_PHASE_PR_HANDLER (PKL_AST_TRY_STMT_BODY, pkl_trans1_pr_try_stmt),
+   PKL_PHASE_PS_HANDLER (PKL_AST_TRY_STMT_BODY, pkl_trans1_ps_try_stmt),
    PKL_PHASE_PR_HANDLER (PKL_AST_TRY_STMT_BODY, pkl_trans1_pr_try_stmt_body),
    PKL_PHASE_PS_HANDLER (PKL_AST_TRY_STMT_BODY, pkl_trans1_ps_try_stmt_body),
    PKL_PHASE_PR_HANDLER (PKL_AST_STRUCT_TYPE_FIELD, 
pkl_trans1_pr_struct_type_field),
diff --git a/libpoke/pkl-trans.h b/libpoke/pkl-trans.h
index 8d3b1f6f..8e470368 100644
--- a/libpoke/pkl-trans.h
+++ b/libpoke/pkl-trans.h
@@ -53,6 +53,23 @@ struct pkl_trans_function_ctx
   struct pkl_trans_function_ctx *next;
 };
 
+/* The trans phases keep a stack of breakable/continuable entities (loops
+   and try-until statements) and corresponding `break' and `continue'
+   keywords, while they operate on the AST.
+
+   The following struct implements each entry on the breakable/continuable
+   entities stack.
+
+   BREAKABLE is the breakable/continuable entity (loops and try-until).
+
+   NFRAMES is the number of frames in the body of BREAKABLE.  */
+
+struct pkl_trans_breakable_ctx
+{
+  pkl_ast_node breakable;
+  int nframes;
+};
+
 /* The following struct defines the payload of the trans phases.
 
    ERRORS is the number of errors detected while running the phase.
@@ -69,10 +86,16 @@ struct pkl_trans_function_ctx
    when mapping and writing integral types.
 
    CUR_ENDIAN is the index to ENDIAN and marks the top of the stack of
-   endianness.  Initially PKL_AST_ENDIAN_DFL.  */
+   endianness.  Initially PKL_AST_ENDIAN_DFL.
+
+   BREAKABLES is a stack of breakables.
+
+   NEXT_BREAKABLE - 1 is the index for the enclosing breakable
+   entity.  */
 
 #define PKL_TRANS_MAX_FUNCTION_NEST 32
 #define PKL_TRANS_MAX_ENDIAN 25
+#define PKL_TRANS_MAX_COMP_STMT_NEST 32
 
 struct pkl_trans_payload
 {
@@ -82,6 +105,8 @@ struct pkl_trans_payload
   int next_function;
   enum pkl_ast_endian endian[PKL_TRANS_MAX_ENDIAN];
   int cur_endian;
+  struct pkl_trans_breakable_ctx breakables[PKL_TRANS_MAX_COMP_STMT_NEST];
+  int next_breakable;
 };
 
 typedef struct pkl_trans_payload *pkl_trans_payload;
-- 
2.36.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]