[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
- [PATCH] pkl: trans: get rid of pkl_ast_finish_breaks,
Mohammad-Reza Nabipoor <=
- Re: [PATCH] pkl: trans: get rid of pkl_ast_finish_breaks, Jose E. Marchesi, 2022/07/14
- [PATCH v2 1/2] pkl: change AST structure for try-catch stmts, Mohammad-Reza Nabipoor, 2022/07/14
- [PATCH v2 2/2] pkl: trans: get rid of pkl_ast_finish_breaks, Mohammad-Reza Nabipoor, 2022/07/14
- Re: [PATCH v2 2/2] pkl: trans: get rid of pkl_ast_finish_breaks, Jose E. Marchesi, 2022/07/14
- [PATCH v3] pkl: trans: get rid of pkl_ast_finish_breaks, Mohammad-Reza Nabipoor, 2022/07/17
- Re: [PATCH v3] pkl: trans: get rid of pkl_ast_finish_breaks, Jose E. Marchesi, 2022/07/17
- Re: [PATCH v3] pkl: trans: get rid of pkl_ast_finish_breaks, Mohammad-Reza Nabipoor, 2022/07/18
- Re: [PATCH v2 1/2] pkl: change AST structure for try-catch stmts, Jose E. Marchesi, 2022/07/14
- Re: [PATCH v2 1/2] pkl: change AST structure for try-catch stmts, Mohammad-Reza Nabipoor, 2022/07/17