[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] pkl: support for post-{increment,decrement} in integers and
From: |
Jose E. Marchesi |
Subject: |
[COMMITTED] pkl: support for post-{increment,decrement} in integers and offsets |
Date: |
Sun, 22 Nov 2020 18:56:28 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
2020-11-22 Jose E. Marchesi <jemarch@gnu.org>
* libpoke/pkl-ast.h (enum pkl_ast_code): Add PKL_AST_INCRDECR.
(struct pkl_ast_incrdecr): New type.
(PKL_AST_INCRDECR_ORDER): Define.
(PKL_AST_INCRDECR_SIGN): Likewise.
(PKL_AST_INCRDECR_EXP): Likewise.
(PKL_AST_INCRDECR_ASS_STMT): Likewise.
(PKL_AST_PRE): Likewise.
(PKL_AST_POST): Likewise.
(PKL_AST_INCR): Likewise.
(PKL_AST_DECR): Likewise.
(pkl_ast_make_incrdecr): New prototype.
(pkl_ast_type_incr_step): Likewise.
(union pkl_ast_node): New field incrdecr.
* libpoke/pkl-ast.c (pkl_ast_make_incrdecr): New function.
(pkl_ast_type_incr_step): Likewise.
(pkl_ast_node_free): Handle PKL_AST_INCRDECR nodes.
* libpoke/pkl-pass.c (pkl_do_pass_1): LIkewise.
* libpoke/pkl-tab.y (primary): syntax for INCRDECR.
* libpoke/pkl-typify.c (pkl_typify1_ps_incrdecr): New handler.
(pkl_phase_typify1): Register handler.
* libpoke/pkl-anal.c (pkl_analf_ps_incrdecr): New handler.
(pkl_phase_analf): Install handler.
* libpoke/pkl-trans.c (pkl_trans1_ps_incrdecr): New handler.
(pkl_phase_trans1): Install handler.
* libpoke/pkl-gen.c (pkl_gen_pr_incrdecr): New handler.
(pkl_phase_gen): Install handler.
* testsuite/poke.pkl/postincr-diag-1.pk: New test.
* testsuite/poke.pkl/postincr-diag-2.pk: Likewise.
* testsuite/poke.pkl/postincr-diag-3.pk: Likewise.
* testsuite/poke.pkl/postincr-diag-4.pk: Likewise.
* testsuite/poke.pkl/postincr-diag-5.pk: Likewise.
* testsuite/poke.pkl/postdecr-diag-1.pk: Likewise.
* testsuite/poke.pkl/postdecr-diag-2.pk: Likewise.
* testsuite/poke.pkl/postdecr-diag-3.pk: Likewise.
* testsuite/poke.pkl/postdecr-diag-4.pk: Likewise.
* testsuite/poke.pkl/postdecr-diag-5.pk: Likewise.
* testsuite/poke.pkl/postincr-1.pk: Likewise.
* testsuite/poke.pkl/postincr-2.pk: Likewise.
* testsuite/poke.pkl/postdecr-1.pk: Likewise.
* testsuite/poke.pkl/postdecr-2.pk: Likewise.
* testsuite/poke.pkl/postincr-offset-1.pk: Likewise.
* testsuite/poke.pkl/postincr-offset-2.pk: Likewise.
* testsuite/poke.pkl/postdecr-offset-1.pk: Likewise.
* testsuite/poke.pkl/postdecr-offset-2.pk: Likewise.
* testsuite/poke.pkl/postincr-aelem-1.pk: Likewise.
* testsuite/poke.pkl/postdecr-aelem-2.pk: Likewise.
* testsuite/poke.pkl/postdecr-field-1.pk: Likewise.
* testsuite/poke.pkl/postincr-field-1.pk: Likewise.
* testsuite/Makefile.am (EXTRA_DIST): Update.
---
ChangeLog | 52 +++++++++++++++++++
libpoke/pkl-anal.c | 29 +++++++++++
libpoke/pkl-ast.c | 69 +++++++++++++++++++++++++
libpoke/pkl-ast.h | 43 +++++++++++++++
libpoke/pkl-gen.c | 26 ++++++++++
libpoke/pkl-pass.c | 5 ++
libpoke/pkl-tab.y | 26 ++++++++++
libpoke/pkl-trans.c | 35 +++++++++++++
libpoke/pkl-typify.c | 32 ++++++++++++
testsuite/Makefile.am | 22 ++++++++
testsuite/poke.pkl/postdecr-1.pk | 8 +++
testsuite/poke.pkl/postdecr-2.pk | 8 +++
testsuite/poke.pkl/postdecr-aelem-1.pk | 8 +++
testsuite/poke.pkl/postdecr-diag-1.pk | 3 ++
testsuite/poke.pkl/postdecr-diag-2.pk | 3 ++
testsuite/poke.pkl/postdecr-diag-3.pk | 3 ++
testsuite/poke.pkl/postdecr-diag-4.pk | 3 ++
testsuite/poke.pkl/postdecr-diag-5.pk | 3 ++
testsuite/poke.pkl/postdecr-field-1.pk | 9 ++++
testsuite/poke.pkl/postdecr-offset-1.pk | 8 +++
testsuite/poke.pkl/postdecr-offset-2.pk | 10 ++++
testsuite/poke.pkl/postincr-1.pk | 8 +++
testsuite/poke.pkl/postincr-2.pk | 8 +++
testsuite/poke.pkl/postincr-aelem-1.pk | 8 +++
testsuite/poke.pkl/postincr-diag-1.pk | 3 ++
testsuite/poke.pkl/postincr-diag-2.pk | 3 ++
testsuite/poke.pkl/postincr-diag-3.pk | 3 ++
testsuite/poke.pkl/postincr-diag-4.pk | 3 ++
testsuite/poke.pkl/postincr-diag-5.pk | 3 ++
testsuite/poke.pkl/postincr-field-1.pk | 9 ++++
testsuite/poke.pkl/postincr-offset-1.pk | 8 +++
testsuite/poke.pkl/postincr-offset-2.pk | 10 ++++
32 files changed, 471 insertions(+)
create mode 100644 testsuite/poke.pkl/postdecr-1.pk
create mode 100644 testsuite/poke.pkl/postdecr-2.pk
create mode 100644 testsuite/poke.pkl/postdecr-aelem-1.pk
create mode 100644 testsuite/poke.pkl/postdecr-diag-1.pk
create mode 100644 testsuite/poke.pkl/postdecr-diag-2.pk
create mode 100644 testsuite/poke.pkl/postdecr-diag-3.pk
create mode 100644 testsuite/poke.pkl/postdecr-diag-4.pk
create mode 100644 testsuite/poke.pkl/postdecr-diag-5.pk
create mode 100644 testsuite/poke.pkl/postdecr-field-1.pk
create mode 100644 testsuite/poke.pkl/postdecr-offset-1.pk
create mode 100644 testsuite/poke.pkl/postdecr-offset-2.pk
create mode 100644 testsuite/poke.pkl/postincr-1.pk
create mode 100644 testsuite/poke.pkl/postincr-2.pk
create mode 100644 testsuite/poke.pkl/postincr-aelem-1.pk
create mode 100644 testsuite/poke.pkl/postincr-diag-1.pk
create mode 100644 testsuite/poke.pkl/postincr-diag-2.pk
create mode 100644 testsuite/poke.pkl/postincr-diag-3.pk
create mode 100644 testsuite/poke.pkl/postincr-diag-4.pk
create mode 100644 testsuite/poke.pkl/postincr-diag-5.pk
create mode 100644 testsuite/poke.pkl/postincr-field-1.pk
create mode 100644 testsuite/poke.pkl/postincr-offset-1.pk
create mode 100644 testsuite/poke.pkl/postincr-offset-2.pk
diff --git a/ChangeLog b/ChangeLog
index c2946380..1afdbb57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2020-11-22 Jose E. Marchesi <jemarch@gnu.org>
+
+ * libpoke/pkl-ast.h (enum pkl_ast_code): Add PKL_AST_INCRDECR.
+ (struct pkl_ast_incrdecr): New type.
+ (PKL_AST_INCRDECR_ORDER): Define.
+ (PKL_AST_INCRDECR_SIGN): Likewise.
+ (PKL_AST_INCRDECR_EXP): Likewise.
+ (PKL_AST_INCRDECR_ASS_STMT): Likewise.
+ (PKL_AST_PRE): Likewise.
+ (PKL_AST_POST): Likewise.
+ (PKL_AST_INCR): Likewise.
+ (PKL_AST_DECR): Likewise.
+ (pkl_ast_make_incrdecr): New prototype.
+ (pkl_ast_type_incr_step): Likewise.
+ (union pkl_ast_node): New field incrdecr.
+ * libpoke/pkl-ast.c (pkl_ast_make_incrdecr): New function.
+ (pkl_ast_type_incr_step): Likewise.
+ (pkl_ast_node_free): Handle PKL_AST_INCRDECR nodes.
+ * libpoke/pkl-pass.c (pkl_do_pass_1): LIkewise.
+ * libpoke/pkl-tab.y (primary): syntax for INCRDECR.
+ * libpoke/pkl-typify.c (pkl_typify1_ps_incrdecr): New handler.
+ (pkl_phase_typify1): Register handler.
+ * libpoke/pkl-anal.c (pkl_analf_ps_incrdecr): New handler.
+ (pkl_phase_analf): Install handler.
+ * libpoke/pkl-trans.c (pkl_trans1_ps_incrdecr): New handler.
+ (pkl_phase_trans1): Install handler.
+ * libpoke/pkl-gen.c (pkl_gen_pr_incrdecr): New handler.
+ (pkl_phase_gen): Install handler.
+ * testsuite/poke.pkl/postincr-diag-1.pk: New test.
+ * testsuite/poke.pkl/postincr-diag-2.pk: Likewise.
+ * testsuite/poke.pkl/postincr-diag-3.pk: Likewise.
+ * testsuite/poke.pkl/postincr-diag-4.pk: Likewise.
+ * testsuite/poke.pkl/postincr-diag-5.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-diag-1.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-diag-2.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-diag-3.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-diag-4.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-diag-5.pk: Likewise.
+ * testsuite/poke.pkl/postincr-1.pk: Likewise.
+ * testsuite/poke.pkl/postincr-2.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-1.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-2.pk: Likewise.
+ * testsuite/poke.pkl/postincr-offset-1.pk: Likewise.
+ * testsuite/poke.pkl/postincr-offset-2.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-offset-1.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-offset-2.pk: Likewise.
+ * testsuite/poke.pkl/postincr-aelem-1.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-aelem-2.pk: Likewise.
+ * testsuite/poke.pkl/postdecr-field-1.pk: Likewise.
+ * testsuite/poke.pkl/postincr-field-1.pk: Likewise.
+ * testsuite/Makefile.am (EXTRA_DIST): Update.
+
2020-11-22 Jose E. Marchesi <jemarch@gnu.org>
* libpoke/pkl-gen.pks (struct_printer): Print struct elements
diff --git a/libpoke/pkl-anal.c b/libpoke/pkl-anal.c
index efb34b2a..a32df76b 100644
--- a/libpoke/pkl-anal.c
+++ b/libpoke/pkl-anal.c
@@ -968,6 +968,34 @@ PKL_PHASE_BEGIN_HANDLER (pkl_analf_ps_ass_stmt)
}
PKL_PHASE_END_HANDLER
+/* Make sure that the argument to an incrdecr operator is of the right
+ kind, i.e. it is a valid lvalue.
+
+ XXX this shouldn't be necessary due to the check in ass_stmt! */
+
+PKL_PHASE_BEGIN_HANDLER (pkl_analf_ps_incrdecr)
+{
+ pkl_ast_node incrdecr = PKL_PASS_NODE;
+ pkl_ast_node incrdecr_exp = PKL_AST_INCRDECR_EXP (incrdecr);
+
+ if (!pkl_ast_lvalue_p (incrdecr_exp))
+ {
+ int incrdecr_order = PKL_AST_INCRDECR_ORDER (incrdecr);
+ int incrdecr_sign = PKL_AST_INCRDECR_SIGN (incrdecr);
+
+ if (!pkl_ast_lvalue_p (incrdecr_exp))
+ {
+ PKL_ERROR (PKL_AST_LOC (incrdecr_exp),
+ "invalid operand to %s%s",
+ incrdecr_order == PKL_AST_PRE ? "pre" : "post",
+ incrdecr_sign == PKL_AST_INCR ? "increment" :
"decrement");
+ PKL_ANAL_PAYLOAD->errors++;
+ PKL_PASS_ERROR;
+ }
+ }
+}
+PKL_PHASE_END_HANDLER
+
struct pkl_phase pkl_phase_analf
__attribute__ ((visibility ("hidden"))) =
{
@@ -975,4 +1003,5 @@ struct pkl_phase pkl_phase_analf
PKL_PHASE_PS_HANDLER (PKL_AST_PROGRAM, pkl_anal_ps_program),
PKL_PHASE_PS_HANDLER (PKL_AST_OFFSET, pkl_analf_ps_array_initializer),
PKL_PHASE_PS_HANDLER (PKL_AST_ASS_STMT, pkl_analf_ps_ass_stmt),
+ PKL_PHASE_PS_HANDLER (PKL_AST_INCRDECR, pkl_analf_ps_incrdecr),
};
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 144ec8a5..92ea1034 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -1566,6 +1566,26 @@ pkl_ast_make_var (pkl_ast ast, pkl_ast_node name,
return var;
}
+/* Build and return an AST node for an incrdecr expression. */
+
+pkl_ast_node
+pkl_ast_make_incrdecr (pkl_ast ast,
+ pkl_ast_node exp, int order, int sign)
+{
+ pkl_ast_node incrdecr = pkl_ast_make_node (ast,
+ PKL_AST_INCRDECR);
+
+ assert (order == PKL_AST_PRE || order == PKL_AST_POST);
+ assert (sign == PKL_AST_INCR || sign == PKL_AST_DECR);
+ assert (exp);
+
+ PKL_AST_INCRDECR_EXP (incrdecr) = ASTREF (exp);
+ PKL_AST_INCRDECR_ORDER (incrdecr) = order;
+ PKL_AST_INCRDECR_SIGN (incrdecr) = sign;
+
+ return incrdecr;
+}
+
/* Build and return an AST node for a lambda expression. */
pkl_ast_node
@@ -2121,6 +2141,11 @@ pkl_ast_node_free (pkl_ast_node ast)
pkl_ast_node_free (PKL_AST_VAR_DECL (ast));
break;
+ case PKL_AST_INCRDECR:
+
+ pkl_ast_node_free (PKL_AST_INCRDECR_EXP (ast));
+ break;
+
case PKL_AST_LAMBDA:
pkl_ast_node_free (PKL_AST_LAMBDA_FUNCTION (ast));
@@ -2363,6 +2388,41 @@ pkl_ast_finish_breaks (pkl_ast_node entity, pkl_ast_node
stmt)
pkl_ast_finish_breaks_1 (entity, stmt, &nframes);
}
+pkl_ast_node
+pkl_ast_type_incr_step (pkl_ast ast, pkl_ast_node type)
+{
+ pkl_ast_node step = NULL;
+
+ assert (PKL_AST_CODE (type) == PKL_AST_TYPE);
+
+ switch (PKL_AST_TYPE_CODE (type))
+ {
+ case PKL_TYPE_INTEGRAL:
+ {
+ /* The obvious step for integral types is 1, of the same
+ type. */
+ step = pkl_ast_make_integer (ast, 1);
+ PKL_AST_TYPE (step) = ASTREF (type);
+ break;
+ }
+ case PKL_TYPE_OFFSET:
+ {
+ /* The step for an offset type is one unit. */
+ pkl_ast_node one = pkl_ast_make_integer (ast, 1);
+
+ PKL_AST_TYPE (one) = PKL_AST_TYPE_O_BASE_TYPE (type);
+ step = pkl_ast_make_offset (ast, one,
+ PKL_AST_TYPE_O_UNIT (type));
+ PKL_AST_TYPE (step) = ASTREF (type);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return step;
+}
+
/* Annotate FUNCTIONs return statements with the function and their
nest level within the function.
@@ -2921,6 +2981,15 @@ pkl_ast_print_1 (FILE *fp, pkl_ast_node ast, int indent)
PRINT_AST_SUBAST (function, LAMBDA_FUNCTION);
break;
+ case PKL_AST_INCRDECR:
+ IPRINTF ("INCRDECR::\n");
+
+ PRINT_COMMON_FIELDS;
+ PRINT_AST_IMM (order, INCRDECR_ORDER, "%d");
+ PRINT_AST_IMM (sign, INCRDECR_SIGN, "%d");
+ PRINT_AST_SUBAST (exp, INCRDECR_EXP);
+ break;
+
case PKL_AST_COMP_STMT:
IPRINTF ("COMP_STMT::\n");
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index eeaf4490..41348286 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -56,6 +56,7 @@ enum pkl_ast_code
PKL_AST_FUNCALL_ARG,
PKL_AST_VAR,
PKL_AST_LAMBDA,
+ PKL_AST_INCRDECR,
PKL_AST_GCD,
PKL_AST_LAST_EXP = PKL_AST_GCD,
/* Types. */
@@ -1019,6 +1020,12 @@ char *pkl_type_str (pkl_ast_node type, int
use_given_name);
pkl_ast_node pkl_struct_type_traverse (pkl_ast_node type, const char *path);
+/* Return an expression that evaluates to an increment step for the
+ given TYPE. If the provided type doesn't support the notion of
+ increment step this function returns NULL. */
+
+pkl_ast_node pkl_ast_type_incr_step (pkl_ast ast, pkl_ast_node type);
+
/* PKL_AST_DECL nodes represent the declaration of a named entity:
function, type, variable....
@@ -1330,6 +1337,41 @@ struct pkl_ast_lambda
pkl_ast_node pkl_ast_make_lambda (pkl_ast ast, pkl_ast_node function);
+/* PKL_AST_INCRDECR nodes represent {pre,post}{increment,decrement}
+ expressions.
+
+ ORDER is either PKL_AST_PRE or PKL_AST_POST.
+ SIGN is either PKL_AST_INCR or PKL_AST_DECR.
+ EXP is the expression to which the operator is applied.
+
+ ASS_STMT is an AST node that is used in a transformation phase in
+ order to hold an assignment statement. */
+
+#define PKL_AST_INCRDECR_ORDER(AST) ((AST)->incrdecr.order)
+#define PKL_AST_INCRDECR_SIGN(AST) ((AST)->incrdecr.sign)
+#define PKL_AST_INCRDECR_EXP(AST) ((AST)->incrdecr.exp)
+#define PKL_AST_INCRDECR_ASS_STMT(AST) ((AST)->incrdecr.ass_stmt)
+
+#define PKL_AST_PRE 0
+#define PKL_AST_POST 1
+
+#define PKL_AST_INCR 0
+#define PKL_AST_DECR 1
+
+struct pkl_ast_incrdecr
+{
+ struct pkl_ast_common common;
+
+ int order;
+ int sign;
+ union pkl_ast_node *exp;
+ union pkl_ast_node *ass_stmt;
+};
+
+pkl_ast_node pkl_ast_make_incrdecr (pkl_ast ast,
+ pkl_ast_node exp, int order, int sign);
+
+
/* PKL_AST_COMPOUND_STMT nodes represent compound statements in the
language.
@@ -1774,6 +1816,7 @@ union pkl_ast_node
struct pkl_ast_funcall_arg funcall_arg;
struct pkl_ast_var var;
struct pkl_ast_lambda lambda;
+ struct pkl_ast_incrdecr incrdecr;
/* Types. */
struct pkl_ast_type type;
struct pkl_ast_struct_type_field sct_type_elem;
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index 6a92c770..48f4e675 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -626,6 +626,31 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_comp_stmt)
}
PKL_PHASE_END_HANDLER
+/*
+ * INCRDECR
+ * | EXP
+ * | ASS_STMT
+ */
+
+PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_incrdecr)
+{
+ pkl_ast_node incrdecr = PKL_PASS_NODE;
+ pkl_ast_node incrdecr_exp = PKL_AST_INCRDECR_EXP (incrdecr);
+ pkl_ast_node incrdecr_ass_stmt = PKL_AST_INCRDECR_ASS_STMT (incrdecr);
+ int incrdecr_order = PKL_AST_INCRDECR_ORDER (incrdecr);
+
+ if (incrdecr_order == PKL_AST_PRE)
+ PKL_PASS_SUBPASS (incrdecr_ass_stmt);
+
+ PKL_PASS_SUBPASS (incrdecr_exp);
+
+ if (incrdecr_order == PKL_AST_POST)
+ PKL_PASS_SUBPASS (incrdecr_ass_stmt);
+
+ PKL_PASS_BREAK;
+}
+PKL_PHASE_END_HANDLER
+
/*
* ASS_STMT
* | EXP
@@ -3725,6 +3750,7 @@ struct pkl_phase pkl_phase_gen
PKL_PHASE_PS_HANDLER (PKL_AST_COMP_STMT, pkl_gen_ps_comp_stmt),
PKL_PHASE_PS_HANDLER (PKL_AST_NULL_STMT, pkl_gen_ps_null_stmt),
PKL_PHASE_PR_HANDLER (PKL_AST_ASS_STMT, pkl_gen_pr_ass_stmt),
+ PKL_PHASE_PR_HANDLER (PKL_AST_INCRDECR, pkl_gen_pr_incrdecr),
PKL_PHASE_PR_HANDLER (PKL_AST_IF_STMT, pkl_gen_pr_if_stmt),
PKL_PHASE_PS_HANDLER (PKL_AST_BREAK_STMT, pkl_gen_ps_break_stmt),
PKL_PHASE_PS_HANDLER (PKL_AST_CONTINUE_STMT, pkl_gen_ps_continue_stmt),
diff --git a/libpoke/pkl-pass.c b/libpoke/pkl-pass.c
index 090da852..07071741 100644
--- a/libpoke/pkl-pass.c
+++ b/libpoke/pkl-pass.c
@@ -574,6 +574,11 @@ pkl_do_pass_1 (pkl_compiler compiler,
case PKL_AST_LAMBDA:
PKL_PASS (PKL_AST_LAMBDA_FUNCTION (node));
break;
+ case PKL_AST_INCRDECR:
+ PKL_PASS (PKL_AST_INCRDECR_EXP (node));
+ if (PKL_AST_INCRDECR_ASS_STMT (node))
+ PKL_PASS (PKL_AST_INCRDECR_ASS_STMT (node));
+ break;
case PKL_AST_NULL_STMT:
case PKL_AST_INTEGER:
case PKL_AST_STRING:
diff --git a/libpoke/pkl-tab.y b/libpoke/pkl-tab.y
index a620f544..2a32269e 100644
--- a/libpoke/pkl-tab.y
+++ b/libpoke/pkl-tab.y
@@ -1002,6 +1002,32 @@ primary:
pkl_ast_finish_returns ($3);
$$ = pkl_ast_make_lambda (pkl_parser->ast, $3);
}
+ | expression INC
+ {
+ $$ = pkl_ast_make_incrdecr (pkl_parser->ast, $1,
+ PKL_AST_POST, PKL_AST_INCR);
+ PKL_AST_LOC ($$) = @$;
+ }
+ | expression DEC
+ {
+ $$ = pkl_ast_make_incrdecr (pkl_parser->ast, $1,
+ PKL_AST_POST, PKL_AST_DECR);
+ PKL_AST_LOC ($$) = @$;
+ }
+/*
+ | INC expression
+ {
+ $$ = pkl_ast_make_incrdecr (pkl_parser->ast, $2,
+ PKL_AST_PRE, PKL_AST_INCR);
+ PKL_AST_LOC ($$) = @$;
+ }
+ | DEC expression
+ {
+ $$ = pkl_ast_make_incrdecr (pkl_parser->ast, $2,
+ PKL_AST_PRE, PKL_AST_DECR);
+ PKL_AST_LOC ($$) = @$;
+ }
+*/
;
funcall:
diff --git a/libpoke/pkl-trans.c b/libpoke/pkl-trans.c
index 09837224..e5fa2b3d 100644
--- a/libpoke/pkl-trans.c
+++ b/libpoke/pkl-trans.c
@@ -1298,6 +1298,40 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_type_offset)
}
PKL_PHASE_END_HANDLER
+/* Add an assignment statement to INCRDECR expressions. */
+
+PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_incrdecr)
+{
+ pkl_ast_node incrdecr = PKL_PASS_NODE;
+ pkl_ast_node incrdecr_stmt = PKL_AST_INCRDECR_ASS_STMT (incrdecr);
+
+ if (!incrdecr_stmt)
+ {
+ pkl_ast_node incrdecr_exp = PKL_AST_INCRDECR_EXP (incrdecr);
+ pkl_ast_node incrdecr_exp_type = PKL_AST_TYPE (incrdecr_exp);
+ int incrdecr_sign = PKL_AST_INCRDECR_SIGN (incrdecr);
+ pkl_ast_node step, ass_stmt, exp_plus_one;
+
+ int op = (incrdecr_sign == PKL_AST_INCR
+ ? PKL_AST_OP_ADD : PKL_AST_OP_SUB);
+
+ /* Get the step. The type of the expression is safe as per
+ typify. */
+ step = pkl_ast_type_incr_step (PKL_PASS_AST, incrdecr_exp_type);
+ assert (step); /* XXX turn to ICE. */
+
+ /* Build a statement EXP = EXP +/- STEP */
+ exp_plus_one = pkl_ast_make_binary_exp (PKL_PASS_AST, op,
+ incrdecr_exp, step);
+ PKL_AST_TYPE (exp_plus_one) = ASTREF (incrdecr_exp_type);
+ ass_stmt = pkl_ast_make_ass_stmt (PKL_PASS_AST,
+ incrdecr_exp, exp_plus_one);
+
+ PKL_AST_INCRDECR_ASS_STMT (incrdecr) = ASTREF (ass_stmt);
+ PKL_PASS_RESTART = 1;
+ }
+}
+PKL_PHASE_END_HANDLER
struct pkl_phase pkl_phase_trans2
__attribute__ ((visibility ("hidden"))) =
@@ -1311,6 +1345,7 @@ struct pkl_phase pkl_phase_trans2
PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT, pkl_trans2_ps_struct),
PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT_REF, pkl_trans2_ps_struct_ref),
PKL_PHASE_PS_HANDLER (PKL_AST_CAST, pkl_trans2_ps_cast),
+ PKL_PHASE_PS_HANDLER (PKL_AST_INCRDECR, pkl_trans2_ps_incrdecr),
PKL_PHASE_PS_TYPE_HANDLER (PKL_TYPE_OFFSET, pkl_trans2_ps_type_offset),
};
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index e0010f06..5ab71bc4 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -2074,6 +2074,37 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_var)
}
PKL_PHASE_END_HANDLER
+/* The type of an incrdecr expression is the type of the expression it
+ applies to. Not all types support this operations though. */
+
+PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_incrdecr)
+{
+ pkl_ast_node incrdecr = PKL_PASS_NODE;
+ pkl_ast_node incrdecr_exp = PKL_AST_INCRDECR_EXP (incrdecr);
+ pkl_ast_node incrdecr_exp_type = PKL_AST_TYPE (incrdecr_exp);
+ int incrdecr_order = PKL_AST_INCRDECR_ORDER (incrdecr);
+ int incrdecr_sign = PKL_AST_INCRDECR_SIGN (incrdecr);
+
+ /* Only values of certain types can be decremented/incremented. */
+ switch (PKL_AST_TYPE_CODE (incrdecr_exp_type))
+ {
+ case PKL_TYPE_INTEGRAL:
+ case PKL_TYPE_OFFSET:
+ break;
+ default:
+ PKL_ERROR (PKL_AST_LOC (incrdecr),
+ "invalid operand to %s%s",
+ incrdecr_order == PKL_AST_PRE ? "pre" : "post",
+ incrdecr_sign == PKL_AST_INCR ? "increment" : "decrement");
+ PKL_TYPIFY_PAYLOAD->errors++;
+ PKL_PASS_ERROR;
+ }
+
+ /* The type of the construction is the type of the expression. */
+ PKL_AST_TYPE (incrdecr) = ASTREF (incrdecr_exp_type);
+}
+PKL_PHASE_END_HANDLER
+
/* The type of a lambda node is the type of its function. */
PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_lambda)
@@ -2810,6 +2841,7 @@ struct pkl_phase pkl_phase_typify1
PKL_PHASE_PR_HANDLER (PKL_AST_PROGRAM, pkl_typify_pr_program),
PKL_PHASE_PS_HANDLER (PKL_AST_VAR, pkl_typify1_ps_var),
PKL_PHASE_PS_HANDLER (PKL_AST_LAMBDA, pkl_typify1_ps_lambda),
+ PKL_PHASE_PS_HANDLER (PKL_AST_INCRDECR, pkl_typify1_ps_incrdecr),
PKL_PHASE_PS_HANDLER (PKL_AST_CAST, pkl_typify1_ps_cast),
PKL_PHASE_PS_HANDLER (PKL_AST_ISA, pkl_typify1_ps_isa),
PKL_PHASE_PS_HANDLER (PKL_AST_MAP, pkl_typify1_ps_map),
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index f05c8625..8e0b9ad3 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -457,6 +457,28 @@ EXTRA_DIST = \
poke.map/trimmed-map-4.pk \
poke.map/unmap-1.pk \
poke.pkl/pkl.exp \
+ poke.pkl/postincr-1.pk \
+ poke.pkl/postincr-2.pk \
+ poke.pkl/postdecr-1.pk \
+ poke.pkl/postdecr-2.pk \
+ poke.pkl/postincr-offset-1.pk \
+ poke.pkl/postincr-offset-2.pk \
+ poke.pkl/postdecr-offset-1.pk \
+ poke.pkl/postdecr-offset-2.pk \
+ poke.pkl/postincr-aelem-1.pk \
+ poke.pkl/postdecr-aelem-1.pk \
+ poke.pkl/postincr-diag-1.pk \
+ poke.pkl/postincr-diag-2.pk \
+ poke.pkl/postincr-diag-3.pk \
+ poke.pkl/postincr-diag-4.pk \
+ poke.pkl/postincr-diag-5.pk \
+ poke.pkl/postdecr-diag-1.pk \
+ poke.pkl/postdecr-diag-2.pk \
+ poke.pkl/postdecr-diag-3.pk \
+ poke.pkl/postdecr-diag-4.pk \
+ poke.pkl/postdecr-diag-5.pk \
+ poke.pkl/postincr-field-1.pk \
+ poke.pkl/postdecr-field-1.pk \
poke.pkl/acons-diag-1.pk \
poke.pkl/acons-diag-2.pk \
poke.pkl/acons-diag-3.pk \
diff --git a/testsuite/poke.pkl/postdecr-1.pk b/testsuite/poke.pkl/postdecr-1.pk
new file mode 100644
index 00000000..8a24e09b
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 10;
+
+/* { dg-command {a--} } */
+/* { dg-output "10" } */
+/* { dg-command {a} } */
+/* { dg-output "\n9" } */
diff --git a/testsuite/poke.pkl/postdecr-2.pk b/testsuite/poke.pkl/postdecr-2.pk
new file mode 100644
index 00000000..e8072e44
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-2.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 10L;
+
+/* { dg-command {a--} } */
+/* { dg-output "10L" } */
+/* { dg-command {a} } */
+/* { dg-output "\n9L" } */
diff --git a/testsuite/poke.pkl/postdecr-aelem-1.pk
b/testsuite/poke.pkl/postdecr-aelem-1.pk
new file mode 100644
index 00000000..d808d22a
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-aelem-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = [1,2,3];
+
+/* { dg-command {a[1]--} } */
+/* { dg-output "2" } */
+/* { dg-command {a[1]} } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/postdecr-diag-1.pk
b/testsuite/poke.pkl/postdecr-diag-1.pk
new file mode 100644
index 00000000..65b5312b
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-diag-1.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+"foo"--; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postdecr-diag-2.pk
b/testsuite/poke.pkl/postdecr-diag-2.pk
new file mode 100644
index 00000000..2ff4621a
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-diag-2.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+[1,2,3]--; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postdecr-diag-3.pk
b/testsuite/poke.pkl/postdecr-diag-3.pk
new file mode 100644
index 00000000..ef139dc9
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-diag-3.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+E_generic--; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postdecr-diag-4.pk
b/testsuite/poke.pkl/postdecr-diag-4.pk
new file mode 100644
index 00000000..33b3c104
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-diag-4.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+lambda void:{}++; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postdecr-diag-5.pk
b/testsuite/poke.pkl/postdecr-diag-5.pk
new file mode 100644
index 00000000..962ac43e
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-diag-5.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+23--; /* { dg-error "invalid" } */
diff --git a/testsuite/poke.pkl/postdecr-field-1.pk
b/testsuite/poke.pkl/postdecr-field-1.pk
new file mode 100644
index 00000000..110cda71
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-field-1.pk
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+
+type Foo = struct { int i; };
+var f = Foo { i = 10 };
+
+/* { dg-command { f.i-- } } */
+/* { dg-output "10" } */
+/* { dg-command { f.i } } *?
+/* { dg-output "\n9" } */
diff --git a/testsuite/poke.pkl/postdecr-offset-1.pk
b/testsuite/poke.pkl/postdecr-offset-1.pk
new file mode 100644
index 00000000..e1ea25e5
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-offset-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 10L#B;
+
+/* { dg-command {a--} } */
+/* { dg-output "10L#B" } */
+/* { dg-command {a} } */
+/* { dg-output "\n9L#B" } */
diff --git a/testsuite/poke.pkl/postdecr-offset-2.pk
b/testsuite/poke.pkl/postdecr-offset-2.pk
new file mode 100644
index 00000000..cf80ef05
--- /dev/null
+++ b/testsuite/poke.pkl/postdecr-offset-2.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+type Packet = struct { byte a; byte b; };
+
+var a = 10#Packet;
+
+/* { dg-command {a--} } */
+/* { dg-output "10#16" } */
+/* { dg-command {a} } */
+/* { dg-output "\n9#16" } */
diff --git a/testsuite/poke.pkl/postincr-1.pk b/testsuite/poke.pkl/postincr-1.pk
new file mode 100644
index 00000000..d60663d7
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 0;
+
+/* { dg-command {a++} } */
+/* { dg-output "0" } */
+/* { dg-command {a} } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/postincr-2.pk b/testsuite/poke.pkl/postincr-2.pk
new file mode 100644
index 00000000..d4ef9b6a
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-2.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 0L;
+
+/* { dg-command {a++} } */
+/* { dg-output "0L" } */
+/* { dg-command {a} } */
+/* { dg-output "\n1L" } */
diff --git a/testsuite/poke.pkl/postincr-aelem-1.pk
b/testsuite/poke.pkl/postincr-aelem-1.pk
new file mode 100644
index 00000000..fe99b4ba
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-aelem-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = [1,2,3];
+
+/* { dg-command {a[1]++} } */
+/* { dg-output "2" } */
+/* { dg-command {a[1]} } */
+/* { dg-output "\n3" } */
diff --git a/testsuite/poke.pkl/postincr-diag-1.pk
b/testsuite/poke.pkl/postincr-diag-1.pk
new file mode 100644
index 00000000..3c327eb3
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-diag-1.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+"foo"++; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postincr-diag-2.pk
b/testsuite/poke.pkl/postincr-diag-2.pk
new file mode 100644
index 00000000..b5d5e3d3
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-diag-2.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+[1,2,3]++; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postincr-diag-3.pk
b/testsuite/poke.pkl/postincr-diag-3.pk
new file mode 100644
index 00000000..21691360
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-diag-3.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+E_generic++; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postincr-diag-4.pk
b/testsuite/poke.pkl/postincr-diag-4.pk
new file mode 100644
index 00000000..33b3c104
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-diag-4.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+lambda void:{}++; /* { dg-error "invalid operand" } */
diff --git a/testsuite/poke.pkl/postincr-diag-5.pk
b/testsuite/poke.pkl/postincr-diag-5.pk
new file mode 100644
index 00000000..38d28873
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-diag-5.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+23++; /* { dg-error "invalid" } */
diff --git a/testsuite/poke.pkl/postincr-field-1.pk
b/testsuite/poke.pkl/postincr-field-1.pk
new file mode 100644
index 00000000..1e65ce9f
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-field-1.pk
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+
+type Foo = struct { int i; };
+var f = Foo {};
+
+/* { dg-command { f.i++ } } */
+/* { dg-output "0" } */
+/* { dg-command { f.i } } *?
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/postincr-offset-1.pk
b/testsuite/poke.pkl/postincr-offset-1.pk
new file mode 100644
index 00000000..1b71b768
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-offset-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+
+var a = 0L#B;
+
+/* { dg-command {a++} } */
+/* { dg-output "0L#B" } */
+/* { dg-command {a} } */
+/* { dg-output "\n1L#B" } */
diff --git a/testsuite/poke.pkl/postincr-offset-2.pk
b/testsuite/poke.pkl/postincr-offset-2.pk
new file mode 100644
index 00000000..1d73b844
--- /dev/null
+++ b/testsuite/poke.pkl/postincr-offset-2.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+type Packet = struct { byte a; byte b; };
+
+var a = 3#Packet;
+
+/* { dg-command {a++} } */
+/* { dg-output "3#16" } */
+/* { dg-command {a} } */
+/* { dg-output "\n4#16" } */
--
2.25.0.2.g232378479e
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED] pkl: support for post-{increment,decrement} in integers and offsets,
Jose E. Marchesi <=