[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/2] pkl: trans: get rid of pkl_ast_finish_breaks
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH v2 2/2] pkl: trans: get rid of pkl_ast_finish_breaks |
Date: |
Thu, 14 Jul 2022 23:43:23 +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_escapable_ctx): New struct.
(PKL_TRANS_MAX_COMP_STMT_NEST): New macro.
(struct pkl_trans_payload): Add new fields.
* libpoke/pkl-trans.c (PKL_TRANS_ESCAPABLE): New macro.
(PKL_TRANS_PUSH_ESCAPABLE): Likewise.
(PKL_TRANS_POP_ESCAPABLE): 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_pr_try_stmt_handler): Likewise.
(pkl_trans1_ps_try_stmt_handler): Likewise.
(pkl_trans1_ps_break_stmt): Likewise.
(pkl_trans1_ps_continue_stmt): Likewise.
(pkl_phase_trans1): Register new handlers.
---
ChangeLog | 27 +++++++++++++
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, 151 insertions(+), 119 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f3322b03..867cd228 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+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_escapable_ctx): New struct.
+ (PKL_TRANS_MAX_COMP_STMT_NEST): New macro.
+ (struct pkl_trans_payload): Add new fields.
+ * libpoke/pkl-trans.c (PKL_TRANS_ESCAPABLE): New macro.
+ (PKL_TRANS_PUSH_ESCAPABLE): Likewise.
+ (PKL_TRANS_POP_ESCAPABLE): 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_pr_try_stmt_handler): Likewise.
+ (pkl_trans1_ps_try_stmt_handler): Likewise.
+ (pkl_trans1_ps_break_stmt): Likewise.
+ (pkl_trans1_ps_continue_stmt): Likewise.
+ (pkl_phase_trans1): Register new handlers.
+
2022-07-14 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* etc/hacking.org (try_stmt): Update the topology.
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 92b2f936..697e70e8 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -2644,92 +2644,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 8ebd6dad..498cf46b 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -1913,8 +1913,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 c12bb0f6..9fcd3708 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);
@@ -2559,11 +2534,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 dcb3d613..07204ab2 100644
--- a/libpoke/pkl-trans.c
+++ b/libpoke/pkl-trans.c
@@ -107,6 +107,30 @@ pkl_trans_in_functions (struct pkl_trans_function_ctx
functions[],
} \
while (0)
+#define PKL_TRANS_ESCAPABLE \
+ (PKL_TRANS_PAYLOAD->next_escapable == 0 \
+ ? NULL \
+ : &PKL_TRANS_PAYLOAD->escapables[PKL_TRANS_PAYLOAD->next_escapable - 1])
+
+#define PKL_TRANS_PUSH_ESCAPABLE(b) \
+ do \
+ { \
+ assert (PKL_TRANS_PAYLOAD->next_escapable <
PKL_TRANS_MAX_COMP_STMT_NEST);\
+ PKL_TRANS_PAYLOAD->escapables[PKL_TRANS_PAYLOAD->next_escapable].nframes
\
+ = 0; \
+ PKL_TRANS_PAYLOAD->escapables[PKL_TRANS_PAYLOAD->next_escapable++].node \
+ = (b); \
+ } \
+ while (0)
+
+#define PKL_TRANS_POP_ESCAPABLE \
+ do \
+ { \
+ assert (PKL_TRANS_PAYLOAD->next_escapable > 0); \
+ PKL_TRANS_PAYLOAD->next_escapable--; \
+ } \
+ while (0)
+
/* The following handler is used in all trans phases and initializes
the phase payload. */
@@ -1094,6 +1118,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_comp_stmt)
PKL_TRANS_FUNCTION->npopes++;
}
}
+
+ if (PKL_TRANS_ESCAPABLE)
+ PKL_TRANS_ESCAPABLE->nframes++;
}
PKL_PHASE_END_HANDLER
@@ -1123,6 +1150,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_ESCAPABLE (stmt);
}
PKL_PHASE_END_HANDLER
@@ -1139,6 +1168,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_ESCAPABLE;
}
PKL_PHASE_END_HANDLER
@@ -1182,6 +1213,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_comp_stmt)
PKL_TRANS_FUNCTION->npopes--;
}
}
+
+ if (PKL_TRANS_ESCAPABLE)
+ PKL_TRANS_ESCAPABLE->nframes--;
}
PKL_PHASE_END_HANDLER
@@ -1237,6 +1271,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_ESCAPABLE (PKL_PASS_PARENT);
}
PKL_PHASE_END_HANDLER
@@ -1248,6 +1285,61 @@ 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_ESCAPABLE;
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_try_stmt_handler)
+{
+ if (PKL_TRANS_ESCAPABLE)
+ PKL_TRANS_ESCAPABLE->nframes++;
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_try_stmt_handler)
+{
+ if (PKL_TRANS_ESCAPABLE)
+ PKL_TRANS_ESCAPABLE->nframes--;
+}
+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_ESCAPABLE (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_ESCAPABLE;
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_break_stmt)
+{
+ if (PKL_TRANS_ESCAPABLE)
+ {
+ PKL_AST_BREAK_STMT_ENTITY (PKL_PASS_NODE)
+ = PKL_TRANS_ESCAPABLE->node;
+ PKL_AST_BREAK_STMT_NFRAMES (PKL_PASS_NODE)
+ = PKL_TRANS_ESCAPABLE->nframes;
+ }
+}
+PKL_PHASE_END_HANDLER
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_continue_stmt)
+{
+ if (PKL_TRANS_ESCAPABLE)
+ {
+ PKL_AST_CONTINUE_STMT_ENTITY (PKL_PASS_NODE)
+ = PKL_TRANS_ESCAPABLE->node;
+ PKL_AST_CONTINUE_STMT_NFRAMES (PKL_PASS_NODE)
+ = PKL_TRANS_ESCAPABLE->nframes;
+ }
}
PKL_PHASE_END_HANDLER
@@ -1271,7 +1363,13 @@ 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_HANDLER,
pkl_trans1_ps_try_stmt_handler),
+ PKL_PHASE_PR_HANDLER (PKL_AST_TRY_STMT_HANDLER,
pkl_trans1_pr_try_stmt_handler),
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),
PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT_TYPE_FIELD,
pkl_trans1_ps_struct_type_field),
diff --git a/libpoke/pkl-trans.h b/libpoke/pkl-trans.h
index 8d3b1f6f..e5ca68d4 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 escapable entities (loops and
+ try-until statements) and the corresponding `break' and `continue'
+ keywords, while they operate on the AST.
+
+ The following struct implements each entry on the escapable/continuable
+ entities stack.
+
+ NODE is the escapable entity (loop or try-until statement).
+
+ NFRAMES is the number of frames in the body of NODE. */
+
+struct pkl_trans_escapable_ctx
+{
+ pkl_ast_node node;
+ 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.
+
+ ESCAPABLES is a stack of escapables.
+
+ NEXT_ESCAPABLE - 1 is the index for the enclosing escapable
+ 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_escapable_ctx escapables[PKL_TRANS_MAX_COMP_STMT_NEST];
+ int next_escapable;
};
typedef struct pkl_trans_payload *pkl_trans_payload;
--
2.36.1