From 10a442350d10ff0ed606fcd573a6f4caf9b47f1a Mon Sep 17 00:00:00 2001
From: Jose Antonio Ortega Ruiz <jao@gnu.org>
Date: Sat, 12 Jun 2004 14:40:37 +0000
Subject: recognition of ALF in listings.

---
 mixlib/mix_parser.c  | 72 +++++++++++++++++++++++++++++++++++++++-------------
 mixlib/mix_scanner.l | 12 ++++-----
 mixlib/xmix_parser.h |  5 +++-
 3 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/mixlib/mix_parser.c b/mixlib/mix_parser.c
index c99e971..e70c48e 100644
--- a/mixlib/mix_parser.c
+++ b/mixlib/mix_parser.c
@@ -136,6 +136,8 @@ mix_parser_new (const gchar *in_file)
       g_warning (_("No system resources"));
       return NULL;
     }
+  result->con_list = NULL;
+  result->alf_list = NULL;
   result->in_file = f;
   result->loc_count = MIX_SHORT_ZERO;
   result->start = MIX_SHORT_ZERO;
@@ -174,6 +176,8 @@ mix_parser_delete (mix_parser_t *parser)
   mix_symbol_table_delete (parser->symbol_table);
   mix_symbol_table_delete (parser->ls_table);
   g_hash_table_destroy (parser->future_refs);
+  g_slist_free (parser->con_list);
+  g_slist_free (parser->alf_list);
   mix_file_delete (parser->in_file);
   g_free (parser);
 }
@@ -340,7 +344,7 @@ mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
 typedef struct
 {
   FILE *file;
-  guint end;
+  mix_parser_t *parser;
 } listing_context_t;
 
 static gint
@@ -348,14 +352,11 @@ write_listing_ (gpointer address, gpointer ins, gpointer context)
 {
   guint k;
   FILE *file = ((listing_context_t *)context)->file;
-  guint end = ((listing_context_t *)context)->end;
+  mix_parser_t *parser = ((listing_context_t *)context)->parser;
+  guint end = parser->end;
   ins_node_ *ins_node = (ins_node_ *)ins;
   mix_ins_t instruct;
-  gchar *instext = NULL;
 
-  mix_ins_id_t id = mix_word_to_ins (ins_node->ins, &instruct);
-  if (id != mix_INVALID_INS)
-    instext = mix_ins_to_string (&instruct);
   fprintf (file, "%03d     %05d   %s ",
            ins_node->lineno,
            GPOINTER_TO_INT (address),
@@ -363,12 +364,31 @@ write_listing_ (gpointer address, gpointer ins, gpointer context)
   for ( k = 1; k < 6; ++k )
     fprintf (file, "%02d ", mix_word_get_byte (ins_node->ins, k));
 
-  if (GPOINTER_TO_UINT (address) <  end)
-    fprintf (file, _("\t%s\n"), instext);
-  else
+  if (g_slist_find (parser->con_list, GUINT_TO_POINTER (ins_node->lineno))
+      || GPOINTER_TO_UINT (address) >=  end)
     fprintf (file, "\tCON\t%04d\n", (int)(ins_node->ins));
+  else if (g_slist_find (parser->alf_list, GUINT_TO_POINTER (ins_node->lineno)))
+    {
+      size_t i;
+      fprintf (file, "\tALF\t\"");
+      for (i = 1; i < 6; ++i)
+        fprintf (file, "%c",
+                 mix_char_to_ascii (mix_byte_to_char
+                                    (mix_word_get_byte (ins_node->ins, i))));
+      fprintf (file, "\"\n");
+    }
+  else if (GPOINTER_TO_UINT (address) <  end)
+    {
+      gchar *instext = NULL;
+      mix_ins_id_t id = mix_word_to_ins (ins_node->ins, &instruct);
+      if (id != mix_INVALID_INS)
+        instext = mix_ins_to_string (&instruct);
+      fprintf (file, _("\t%s\n"), instext? instext : _("UNKNOWN"));
+      if (instext) g_free (instext);
+    }
+  else
+    g_assert_not_reached ();
 
-  if (instext) g_free (instext);
   return FALSE;
 }
 
@@ -387,6 +407,7 @@ mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file)
   mfile =  mix_file_new_with_def_ext (name, mix_io_WRITE, MIX_LIST_DEFEXT);
   if ( mfile == NULL ) return MIX_PERR_NOOUT;
   context.file = mix_file_to_FILE (mfile);
+  context.parser = parser;
   fprintf (context.file, _("*** %s%s: compilation summary ***\n\n"),
 	   mix_file_base_name (parser->in_file),
 	   mix_file_extension (parser->in_file));
@@ -394,7 +415,6 @@ mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file)
   fputs ( _("Src     Address  Compiled word           Symbolic rep\n"),
 	  context.file);
   fputs (sep, context.file);
-  context.end = (guint)parser->end;
   g_tree_traverse (parser->ins_table, write_listing_,
                    G_IN_ORDER, (gpointer)(&context));
   fputs (sep, context.file);
@@ -525,25 +545,41 @@ mix_parser_define_ls (mix_parser_t *parser, mix_word_t value)
 }
 
 /* Compilation */
+static void
+add_raw_ (mix_parser_t *parser, mix_word_t word, guint lineno)
+{
+  if ( parser->status == MIX_PERR_NOCOMP || parser->status == MIX_PERR_OK )
+    {
+      ins_node_ *node = g_new (ins_node_, 1);
+      node->ins = word;
+      node->lineno = lineno;
+      g_tree_insert (parser->ins_table, (gpointer)((guint)parser->loc_count),
+		     (gpointer)node);
+    }
+}
+
 void
 mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
 		    guint lineno)
 {
   g_assert (parser != NULL && new_ins != NULL);
-  mix_parser_add_raw (parser, mix_ins_to_word_uncheck (*new_ins), lineno);
+  add_raw_ (parser, mix_ins_to_word_uncheck (*new_ins), lineno);
 }
 
 void
-mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno)
+mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno,
+                    gboolean is_con)
 {
   g_assert (parser != NULL);
+  add_raw_ (parser, word, lineno);
   if ( parser->status == MIX_PERR_NOCOMP || parser->status == MIX_PERR_OK )
     {
-      ins_node_ *node = g_new (ins_node_, 1);
-      node->ins = word;
-      node->lineno = lineno;
-      g_tree_insert (parser->ins_table, (gpointer)((guint)parser->loc_count),
-		     (gpointer)node);
+      if (is_con)
+        parser->con_list = g_slist_append (parser->con_list,
+                                           GUINT_TO_POINTER (lineno));
+      else
+        parser->alf_list = g_slist_append (parser->alf_list,
+                                           GUINT_TO_POINTER (lineno));
     }
 }
 
diff --git a/mixlib/mix_scanner.l b/mixlib/mix_scanner.l
index aaa3146..fcd6054 100644
--- a/mixlib/mix_scanner.l
+++ b/mixlib/mix_scanner.l
@@ -64,10 +64,10 @@
     NEXT ();					\
   } while (FALSE)
 
-#define ADD_RAW(value)				\
-  do {						\
-    mix_parser_add_raw (parser, value, lineno);	\
-    NEXT ();	               			\
+#define ADD_RAW(value,is_con)                           \
+  do {                                                  \
+    mix_parser_add_raw (parser, value, lineno, is_con); \
+    NEXT ();                                            \
   } while (FALSE)
 
 
@@ -267,7 +267,7 @@ wexpr   {expr}({fpart})?(,{expr}({fpart})?)*
 
     value = mix_bytes_to_word (bytes, 5);
 
-    ADD_RAW (value);
+    ADD_RAW (value, FALSE);
    }
   ALF{ws}+.*\n {
     gchar* msg;
@@ -307,7 +307,7 @@ wexpr   {expr}({fpart})?(,{expr}({fpart})?)*
   {number}{ws}*\n |
   {number}{ws}+.*\n  {
     mix_word_t value = mix_word_new (atol (yytext));
-    ADD_RAW (value);
+    ADD_RAW (value, TRUE);
   }
 }
 
diff --git a/mixlib/xmix_parser.h b/mixlib/xmix_parser.h
index d2b3edc..2621eb1 100644
--- a/mixlib/xmix_parser.h
+++ b/mixlib/xmix_parser.h
@@ -37,6 +37,8 @@ struct mix_parser_t
   guint cur_ls;             /* current literal string symbol */
   GHashTable *future_refs;  /* a map from symbol name to list of addresses */
   GTree *ins_table;         /* a table of compiled instructions */
+  GSList *con_list;         /* CON instructions */
+  GSList *alf_list;         /* ALF instructions */
   mix_address_t loc_count;  /* current memory location during compilation */
   mix_parser_err_t status;  /* outcome of compilation */
   guint err_line;           /* line of the last error */
@@ -94,7 +96,8 @@ extern void
 mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
                     guint lineno);
 extern void
-mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno);
+mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno,
+                    gboolean is_con);
 
 /* Error handling */
 extern void
-- 
cgit v1.2.3