Signed-off-by: Jose E. Marchesi <[email protected]>

gcc/ChangeLog

        * algol68/a68-parser-debug.cc: New file.
---
 gcc/algol68/a68-parser-debug.cc | 255 ++++++++++++++++++++++++++++++++
 1 file changed, 255 insertions(+)
 create mode 100644 gcc/algol68/a68-parser-debug.cc

diff --git a/gcc/algol68/a68-parser-debug.cc b/gcc/algol68/a68-parser-debug.cc
new file mode 100644
index 00000000000..28646b3f31a
--- /dev/null
+++ b/gcc/algol68/a68-parser-debug.cc
@@ -0,0 +1,255 @@
+/* Debug facilities for the Algol 68 parser.
+   Copyright (C) 2025 Jose E. Marchesi.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define INCLUDE_MEMORY
+#include "config.h"
+#define INCLUDE_VECTOR
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "diagnostic.h"
+#include "text-art/types.h"
+#include "text-art/dump.h"
+#include "text-art/dump-widget-info.h"
+#include "text-art/canvas.h"
+#include "text-art/theme.h"
+#include "text-art/tree-widget.h"
+
+#include "a68.h"
+
+/* Write a printable representation of the parse tree with top node P to the
+   standard output.  */
+
+static void
+a68_dump_parse_tree_1 (NODE_T *p, const text_art::dump_widget_info &dwi,
+                      text_art::tree_widget &widget, bool tables, bool levels)
+{
+  for (; p != NO_NODE; FORWARD (p))
+    {
+      char *symbol;
+      if (ATTRIBUTE (p) == IDENTIFIER
+         || ATTRIBUTE (p) == DEFINING_IDENTIFIER
+         || ATTRIBUTE (p) == DEFINING_OPERATOR
+         || ATTRIBUTE (p) == BOLD_TAG)
+       symbol = xasprintf (" %s", NSYMBOL (p));
+      else
+       symbol = xstrdup ("");
+
+      char *tableinfo;
+      if (tables && TABLE (p) != NO_TABLE)
+       tableinfo = xasprintf (" table=%p prev=%p",
+                              (void *) TABLE (p),
+                              (void *) PREVIOUS (TABLE (p)));
+      else
+       tableinfo = xstrdup ("");
+
+      char *levelsinfo;
+      if (levels && TABLE (p) != NO_TABLE)
+       levelsinfo = xasprintf (" level=%d", LEVEL (TABLE (p)));
+      else
+       levelsinfo = xstrdup ("");
+
+      char mode[BUFFER_SIZE];
+      mode[0] = '\0';
+      if (MOID (p) != NO_MOID)
+       {
+         MOID_T *moid = MOID (p);
+         mode[0] = '\0';
+
+         a68_bufcat (mode, " (", 2);
+         if (IS (moid, SERIES_MODE))
+           {
+             if (PACK (moid) != NO_PACK && NEXT (PACK (moid)) == NO_PACK)
+               a68_bufcat (mode, a68_moid_to_string (MOID (PACK (moid)), 
MOID_ERROR_WIDTH, p),
+                           BUFFER_SIZE);
+             else
+               a68_bufcat (mode, a68_moid_to_string (moid, MOID_ERROR_WIDTH, 
p), BUFFER_SIZE);
+           }
+         else
+           a68_bufcat (mode, a68_moid_to_string (moid, MOID_ERROR_WIDTH, p), 
BUFFER_SIZE);
+         a68_bufcat (mode, ")", 2);
+       }
+
+      location_t loc = a68_get_node_location (p);
+      std::unique_ptr<text_art::tree_widget> cwidget
+       = text_art::tree_widget::from_fmt (dwi, nullptr,
+                                          "%s:%d:%d [%d] %s%s%s%s%s",
+                                          LOCATION_FILE (loc),
+                                          LOCATION_LINE (loc),
+                                          LOCATION_COLUMN (loc),
+                                          NUMBER (p),
+                                          a68_attribute_name (ATTRIBUTE (p)),
+                                          symbol,
+                                          mode,
+                                          tableinfo,
+                                          levelsinfo);
+      free (symbol);
+      free (tableinfo);
+      free (levelsinfo);
+
+      a68_dump_parse_tree_1 (SUB (p), dwi, *cwidget, tables, levels);
+      widget.add_child (std::move (cwidget));
+    }
+}
+
+void
+a68_dump_parse_tree (NODE_T *p, bool tables, bool levels)
+{
+  text_art::style_manager sm;
+  text_art::style::id_t default_style_id (sm.get_or_create_id (text_art::style 
()));
+  text_art::ascii_theme theme;
+  text_art::dump_widget_info dwi (sm, theme, default_style_id);
+  std::unique_ptr<text_art::tree_widget> widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "Parse Tree");
+
+  a68_dump_parse_tree_1 (p, dwi, *widget, tables, levels);
+
+  text_art::canvas c (widget->to_canvas (sm));
+  pretty_printer *const pp = global_dc->get_reference_printer ();
+  pp_clear_output_area (pp);
+  c.print_to_pp (pp);
+  printf ("%s", pp_formatted_text (pp));
+}
+
+/* Dump the modes in the list MOID.  */
+
+void
+a68_dump_modes (MOID_T *moid)
+{
+  for (; moid != NO_MOID; FORWARD (moid))
+    {
+      printf ("%p %s\n", (void *) moid,
+             a68_moid_to_string (moid, MOID_ERROR_WIDTH, NODE (moid),
+                                 true /* indicant_value */));
+    }
+}
+
+/* Dump a given MOIF.  */
+
+void
+a68_dump_moif (MOIF_T *moif)
+{
+  text_art::style_manager sm;
+  text_art::style::id_t default_style_id (sm.get_or_create_id (text_art::style 
()));
+  text_art::ascii_theme theme;
+  text_art::dump_widget_info dwi (sm, theme, default_style_id);
+  std::unique_ptr<text_art::tree_widget> widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "module interface: %s", 
NAME (moif));
+
+  std::unique_ptr<text_art::tree_widget> prelude_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "prelude: %s", PRELUDE 
(moif));
+  widget->add_child (std::move (prelude_widget));
+
+  std::unique_ptr<text_art::tree_widget> postlude_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "postlude: %s", POSTLUDE 
(moif));
+  widget->add_child (std::move (postlude_widget));
+
+  /* Mode table.  */
+  std::unique_ptr<text_art::tree_widget> modes_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "modes");
+  for (MOID_T *mode : MODES (moif))
+    {
+      const char *asm_label = ASM_LABEL (mode);
+      if (asm_label == NULL)
+       asm_label = a68_moid_to_string (mode, 80, NO_NODE, false);
+      std::unique_ptr<text_art::tree_widget> mode_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "mode: %s: %s",
+                                          asm_label,
+                                          a68_moid_to_string (mode, 80, 
NO_NODE, true));
+      modes_widget->add_child (std::move (mode_widget));
+    }
+  widget->add_child (std::move (modes_widget));
+
+  /* Module extracts.  */
+  std::unique_ptr<text_art::tree_widget> mod_extracts_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "module extracts");
+  for (EXTRACT_T *e : MODULES (moif))
+    {
+      std::unique_ptr<text_art::tree_widget> mod_extract_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "module extract: %s", 
EXTRACT_SYMBOL (e));
+      mod_extracts_widget->add_child (std::move (mod_extract_widget));
+    }
+  widget->add_child (std::move (mod_extracts_widget));
+
+  /* Mode extracts.  */
+  std::unique_ptr<text_art::tree_widget> mode_extracts_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "mode extracts");
+  for (EXTRACT_T *e : INDICANTS (moif))
+    {
+      const char *asm_label = ASM_LABEL (EXTRACT_MODE (e));
+      if (asm_label == NULL)
+       asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false);
+      std::unique_ptr<text_art::tree_widget> mode_extract_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "mode extract: %s 
[%s]",
+                                          EXTRACT_SYMBOL (e), asm_label);
+      mode_extracts_widget->add_child (std::move (mode_extract_widget));
+    }
+  widget->add_child (std::move (mode_extracts_widget));
+
+  /* Priority extracts.  */
+  std::unique_ptr<text_art::tree_widget> prio_extracts_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "prio extracts");
+  for (EXTRACT_T *e : PRIOS (moif))
+    {
+      std::unique_ptr<text_art::tree_widget> prio_extract_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "prio extract: %s 
[prio: %d]",
+                                          EXTRACT_SYMBOL (e), EXTRACT_PRIO 
(e));
+      prio_extracts_widget->add_child (std::move (prio_extract_widget));
+    }
+  widget->add_child (std::move (prio_extracts_widget));
+
+  /* Identifier extracts.  */
+  std::unique_ptr<text_art::tree_widget> id_extracts_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "identifier extracts");
+  for (EXTRACT_T *e : IDENTIFIERS (moif))
+    {
+      const char *asm_label = ASM_LABEL (EXTRACT_MODE (e));
+      if (asm_label == NULL)
+       asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false);
+      std::unique_ptr<text_art::tree_widget> id_extract_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "iden extract: %s [%s] 
variable=%d inproc=%d",
+                                          EXTRACT_SYMBOL (e), asm_label,
+                                          EXTRACT_VARIABLE (e),
+                                          EXTRACT_IN_PROC (e));
+      id_extracts_widget->add_child (std::move (id_extract_widget));
+    }
+  widget->add_child (std::move (id_extracts_widget));
+
+  /* Operator extracts.  */
+  std::unique_ptr<text_art::tree_widget> op_extracts_widget
+    = text_art::tree_widget::from_fmt (dwi, nullptr, "operator extracts");
+  for (EXTRACT_T *e : OPERATORS (moif))
+    {
+      const char *asm_label = ASM_LABEL (EXTRACT_MODE (e));
+      if (asm_label == NULL)
+       asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false);
+
+      std::unique_ptr<text_art::tree_widget> op_extract_widget
+       = text_art::tree_widget::from_fmt (dwi, nullptr, "op extract: %s [%s] 
variable=%d inproc=%d",
+                                          EXTRACT_SYMBOL (e), asm_label,
+                                          EXTRACT_VARIABLE (e),
+                                          EXTRACT_IN_PROC (e));
+      op_extracts_widget->add_child (std::move (op_extract_widget));
+    }
+  widget->add_child (std::move (op_extracts_widget));
+
+  text_art::canvas c (widget->to_canvas (sm));
+  pretty_printer *const pp = global_dc->get_reference_printer ();
+  pp_clear_output_area (pp);
+  c.print_to_pp (pp);
+  printf ("%s", pp_formatted_text (pp));
+}
-- 
2.30.2

Reply via email to