poke-devel
[Top][All Lists]
Advanced

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

[PATCH 2/9] pkl: report location of constraint definition


From: Mohammad-Reza Nabipoor
Subject: [PATCH 2/9] pkl: report location of constraint definition
Date: Thu, 28 Dec 2023 02:19:27 +0100

In case of E_constraint exception, report the definition location
of the constraint.

2023-12-25  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/pkl-ast.h (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC):
        New macro.
        (struct pkl_ast_struct_type_field): Add new field
        `constraint_loc' to keep track of location.
        * libpoke/pkl-ast.c (pkl_ast_dup_type): Handle new field.
        (pkl_ast_node_free_1): Likewise.
        * libpoke/pkl-tab.y (struct_type_field): Populate the content of
        `PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC'.
        * libpoke/pkl-rt.pk (_pkl_e_constraint_msg): Add new func param
        for location.
        * libpoke/pkl-gen.pks (check_struct_field_constraint): Update
        `_pkl_e_constraint_msg' invocation.
---

Hi Jose.

This patch is the first step to enrich the exception message for
constraints failures.  The next one in this series is:

  pkl: report evaluation location in E_constraint exception


Regards,
Mohammad-Reza


 ChangeLog           | 15 +++++++++++++++
 libpoke/pkl-ast.c   |  6 ++++++
 libpoke/pkl-ast.h   |  7 +++++++
 libpoke/pkl-gen.pks |  3 +++
 libpoke/pkl-rt.pk   | 13 ++++++++-----
 libpoke/pkl-tab.y   | 22 ++++++++++++++++++++--
 6 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8086c62b..20b1356a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2023-12-25  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/pkl-ast.h (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC):
+       New macro.
+       (struct pkl_ast_struct_type_field): Add new field
+       `constraint_loc' to keep track of location.
+       * libpoke/pkl-ast.c (pkl_ast_dup_type): Handle new field.
+       (pkl_ast_node_free_1): Likewise.
+       * libpoke/pkl-tab.y (struct_type_field): Populate the content of
+       `PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC'.
+       * libpoke/pkl-rt.pk (_pkl_e_constraint_msg): Add new func param
+       for location.
+       * libpoke/pkl-gen.pks (check_struct_field_constraint): Update
+       `_pkl_e_constraint_msg' invocation.
+
 2023-12-22  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * utils/Makefile.am (bin_SCRIPTS): Add `pk-jojopatch'.
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 25ecd096..d6e011cc 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -630,6 +630,7 @@ pkl_ast_dup_type (pkl_ast_node type)
           pkl_ast_node struct_type_elem_size;
           pkl_ast_node struct_type_elem_constraint;
           char *struct_type_elem_constraint_src;
+          char *struct_type_elem_constraint_loc;
           pkl_ast_node struct_type_elem_initializer;
           pkl_ast_node struct_type_elem_label;
           pkl_ast_node new_struct_type_elem_name;
@@ -652,6 +653,8 @@ pkl_ast_dup_type (pkl_ast_node type)
             = (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC (t)
                ? xstrdup (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC (t))
                : NULL);
+          struct_type_elem_constraint_loc
+            = xstrdup (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC (t));
           struct_type_elem_initializer = PKL_AST_STRUCT_TYPE_FIELD_INITIALIZER 
(t);
           struct_type_elem_label = PKL_AST_STRUCT_TYPE_FIELD_LABEL (t);
           struct_type_elem_endian = PKL_AST_STRUCT_TYPE_FIELD_ENDIAN (t);
@@ -677,6 +680,8 @@ pkl_ast_dup_type (pkl_ast_node type)
 
           PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC (struct_type_elem)
             = struct_type_elem_constraint_src;
+          PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC (struct_type_elem)
+            = struct_type_elem_constraint_loc;
           PKL_AST_STRUCT_TYPE_FIELD_COMPUTED_P (struct_type_elem)
             = struct_type_elem_computed_p;
           PKL_AST_STRUCT_TYPE_FIELD_SIZE (struct_type_elem)
@@ -2521,6 +2526,7 @@ pkl_ast_node_free_1 (gl_set_t visitations, pkl_ast_node 
ast)
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_TYPE_FIELD_SIZE (ast));
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT (ast));
       free (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC (ast));
+      free (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC (ast));
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_TYPE_FIELD_INITIALIZER (ast));
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_TYPE_FIELD_LABEL (ast));
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_TYPE_FIELD_OPTCOND_PRE (ast));
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index e7f4794e..b6c49631 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -784,6 +784,11 @@ pkl_ast_node pkl_ast_make_struct_ref (pkl_ast ast,
    CONSTRAINT is a constraint associated with the struct field.  It is
    an expression that should evaluate to a boolean.
 
+   CONSTRAINT_SRC is the corresponding Poke code snippet.
+
+   CONSTRAINT_LOC is textual location of the beginning of constraint in
+   the source file.
+
    LABEL is an expression that, if present, should evaluate to an
    offset value.  If the struct type element doesn't have a label,
    this is NULL.
@@ -818,6 +823,7 @@ pkl_ast_node pkl_ast_make_struct_ref (pkl_ast ast,
 #define PKL_AST_STRUCT_TYPE_FIELD_SIZE(AST) ((AST)->sct_type_elem.size)
 #define PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT(AST) 
((AST)->sct_type_elem.constraint)
 #define PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC(AST) 
((AST)->sct_type_elem.constraint_src)
+#define PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC(AST) 
((AST)->sct_type_elem.constraint_loc)
 #define PKL_AST_STRUCT_TYPE_FIELD_LABEL(AST) ((AST)->sct_type_elem.label)
 #define PKL_AST_STRUCT_TYPE_FIELD_ENDIAN(AST) ((AST)->sct_type_elem.endian)
 #define PKL_AST_STRUCT_TYPE_FIELD_OPTCOND_PRE(AST) 
((AST)->sct_type_elem.optcond_pre)
@@ -843,6 +849,7 @@ struct pkl_ast_struct_type_field
   int endian;
   int computed_p;
   char *constraint_src;
+  char *constraint_loc;
 };
 
 pkl_ast_node pkl_ast_make_struct_type_field (pkl_ast ast,
diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
index aa245611..30286455 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -801,6 +801,9 @@
    .c {
         push ""
    .c }
+        .let #code_loc = \
+          pvm_make_string (PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC (@field))
+        push #code_loc
         .call _pkl_e_constraint_msg
         sset
         raise
diff --git a/libpoke/pkl-rt.pk b/libpoke/pkl-rt.pk
index 20f8b920..5645b18e 100644
--- a/libpoke/pkl-rt.pk
+++ b/libpoke/pkl-rt.pk
@@ -102,14 +102,16 @@ immutable var E_stack
   = Exception {code = EC_stack, name = "invalid stack", exit_status = 1};
 
 /* Given the name of a struct field FNAME, and a snippet with Poke
-   code CODE, return a suitable string to be put in the `msg' field of
-   an E_constraint exception resulting from the evaluation of an
-   expression whose source code is in CODE.
+   code CODE and the location of that Poke code, return a suitable
+   string to be put in the `msg' field of an E_constraint exception
+   resulting from the evaluation of an expression whose source code
+   is in CODE.
 
    Note that FNAME can be empty if the field is anonymous.
    Also, CODE may be empty.  */
 
-immutable fun _pkl_e_constraint_msg = (string fname, string code) string:
+immutable fun _pkl_e_constraint_msg = (string fname, string code,
+                                       string location) string:
 {
   var msg = "";
 
@@ -120,8 +122,9 @@ immutable fun _pkl_e_constraint_msg = (string fname, string 
code) string:
         msg += (c == '\n') ? "\n  " : c as string;
     }
 
+  msg += "\ndefined at " + location;
   if (fname != "")
-    msg += "\nin field " + fname;
+    msg += " in field " + fname;
 
   return msg;
 }
diff --git a/libpoke/pkl-tab.y b/libpoke/pkl-tab.y
index 304bfe95..b2c78c5f 100644
--- a/libpoke/pkl-tab.y
+++ b/libpoke/pkl-tab.y
@@ -1945,15 +1945,33 @@ struct_type_field:
                         char *code = pkl_loc_to_source (pkl_parser,
                                                         PKL_AST_LOC 
(constraint),
                                                         256);
+                        char *code_loc = NULL;
+                        int first_column = @6.first_column;
+
                         if (impl_constraint_p)
                           {
                             assert ($4 != NULL);
-                            code = pk_str_concat (PKL_AST_IDENTIFIER_POINTER 
($4),
-                                                  " == ", code, NULL);
+                            code
+                              = pk_str_concat (PKL_AST_IDENTIFIER_POINTER ($4),
+                                               " == ", code, NULL);
+                            first_column
+                              -= strlen (PKL_AST_IDENTIFIER_POINTER ($4)) + 1;
+                          }
+
+                        if (asprintf (&code_loc, "%s:%d:%d",
+                                      pkl_parser->filename,
+                                      @6.first_line, first_column) == -1)
+                          {
+                            pkl_error (pkl_parser->compiler, pkl_parser->ast,
+                                       @1, "asprintf failed to allocate "
+                                       "location info for constraint");
+                            YYERROR;
                           }
 
                         PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_SRC ($$)
                           = code;
+                        PKL_AST_STRUCT_TYPE_FIELD_CONSTRAINT_LOC ($$)
+                          = code_loc;
                       }
 
                     /* If endianness is empty or there is no
-- 
2.42.1




reply via email to

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