diff options
Diffstat (limited to 'mixlib')
| -rw-r--r-- | mixlib/mix_parser.c | 73 | 
1 files changed, 47 insertions, 26 deletions
| diff --git a/mixlib/mix_parser.c b/mixlib/mix_parser.c index 012345b..cae7ab9 100644 --- a/mixlib/mix_parser.c +++ b/mixlib/mix_parser.c @@ -177,16 +177,17 @@ mix_parser_delete (mix_parser_t *parser)  }  /* Compile a mix source file */ -static void +static guint  update_future_refs_value_ (mix_parser_t *parser, const gchar *name,  			   mix_short_t value, gboolean remove)  {    GSList *list = NULL;    gpointer key; +  guint line = 0;    g_assert (parser != NULL && name != NULL);    if ( g_hash_table_lookup_extended (parser->future_refs, name, &key, -				     (gpointer *)&list) ) +				     (gpointer *)(&list)) )      {        GSList *tmp = list;        ins_node_ *node; @@ -203,6 +204,8 @@ update_future_refs_value_ (mix_parser_t *parser, const gchar *name,  	  }  	  mix_word_add_address (node->ins, value);  	  g_tree_insert (parser->ins_table, tmp->data, (gpointer)node); +          /* record the first line the ref appears */ +          if (line == 0 || line > node->lineno) line = node->lineno;  	  tmp = g_slist_next (tmp);  	}        if (remove) { @@ -211,6 +214,7 @@ update_future_refs_value_ (mix_parser_t *parser, const gchar *name,        }        g_slist_free (list);      } +  return line;  }  #define update_future_refs_(parser,name,rem) \ @@ -224,8 +228,8 @@ update_ls_ (gpointer symbol, gpointer value, gpointer parser)    mix_parser_t *par = (mix_parser_t *) parser;    mix_word_to_ins_uncheck (w, ins); -  mix_parser_add_ins (par, &ins, 0); -  update_future_refs_ (par, (const gchar *)symbol, TRUE); +  mix_parser_add_ins (par, &ins, +                      update_future_refs_ (par, (const gchar *)symbol, TRUE));    par->loc_count++;  } @@ -236,12 +240,10 @@ undef_warning_ (gpointer symbol, gpointer value, gpointer data)    const gchar *name = (const gchar *)symbol;    mix_ins_t ins; -  mix_word_to_ins_uncheck (MIX_WORD_ZERO, ins); -  mix_parser_add_ins (parser, &ins, 0);    mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, 0, name, TRUE); -  /* move the symbol to the symbol table */ -  update_future_refs_ (parser, name, FALSE); +  mix_word_to_ins_uncheck (MIX_WORD_ZERO, ins); +  mix_parser_add_ins (parser, &ins, update_future_refs_ (parser, name, FALSE));    mix_symbol_table_insert (parser->symbol_table, name,                             mix_short_to_word_fast (parser->loc_count)); @@ -265,11 +267,9 @@ mix_parser_compile (mix_parser_t *parser)        mix_symbol_table_foreach (parser->ls_table, update_ls_, (gpointer)parser);        if ( g_hash_table_size (parser->future_refs) > 0)          { -          parser->loc_count = parser->end + parser->cur_ls; +          parser->loc_count--;            g_hash_table_foreach_remove (parser->future_refs,                                         undef_warning_, (gpointer)parser); - -          parser->end = parser->loc_count;          }      } @@ -334,11 +334,18 @@ mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,  }  /* Produce a listing file summarising the compilation */ +typedef struct +{ +  FILE *file; +  guint end; +} listing_context_t; +  static gint  write_listing_ (gpointer address, gpointer ins, gpointer context)  {    guint k; -  FILE *file = (FILE *)context; +  FILE *file = ((listing_context_t *)context)->file; +  guint end = ((listing_context_t *)context)->end;    ins_node_ *ins_node = (ins_node_ *)ins;    mix_ins_t instruct;    gchar *instext = NULL; @@ -346,12 +353,18 @@ write_listing_ (gpointer address, gpointer ins, gpointer context)    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, "%d\t%s ", GPOINTER_TO_INT (address), +  fprintf (file, "%03d     %05d   %s ", +           ins_node->lineno, +           GPOINTER_TO_INT (address),  	   mix_word_is_negative (ins_node->ins)? "-":"+");    for ( k = 1; k < 6; ++k )      fprintf (file, "%02d ", mix_word_get_byte (ins_node->ins, k)); -  fprintf (file, _("\t%s\t(line %d)\n"), instext? instext:"--DATA--", -	   ins_node->lineno); + +  if (GPOINTER_TO_UINT (address) <  end) +    fprintf (file, _("\t%s\n"), instext); +  else +    fprintf (file, "\tCON\t%04d\n", (int)(ins_node->ins)); +    if (instext) g_free (instext);    return FALSE;  } @@ -359,28 +372,36 @@ write_listing_ (gpointer address, gpointer ins, gpointer context)  mix_parser_err_t  mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file)  { -  FILE *file;    mix_file_t *mfile;    const gchar *name; +  listing_context_t context; +  static const char *sep = +    "-----------------------------------------------------------------\n";    g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);    if (parser->status != MIX_PERR_OK ) return parser->status;    name = (list_file) ? list_file : mix_file_base_name (parser->in_file);    mfile =  mix_file_new_with_def_ext (name, mix_io_WRITE, MIX_LIST_DEFEXT);    if ( mfile == NULL ) return MIX_PERR_NOOUT; -  file = mix_file_to_FILE (mfile); -  fprintf (file, _("*** %s%s: compilation summary ***\n\n"), +  context.file = mix_file_to_FILE (mfile); +  fprintf (context.file, _("*** %s%s: compilation summary ***\n\n"),  	   mix_file_base_name (parser->in_file),  	   mix_file_extension (parser->in_file)); -  fputs ( _("*** Address / Compiled word / Symbolic rep / Source file line\n"), -	  file); +  fputs (sep, context.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)file); -  fprintf (file, _("\n*** Start address: %d\n"), -	   mix_short_magnitude (parser->start)); -  fprintf (file, _("\n*** Symbol table\n")); -  mix_symbol_table_print (parser->symbol_table, MIX_SYM_ROWS, file, TRUE); -  fprintf (file, _("\n*** End of summary ***\n")); +                   G_IN_ORDER, (gpointer)(&context)); +  fputs (sep, context.file); +  fprintf (context.file, _("\n*** Start address:\t%d\n*** End address:\t%d\n"), +	   mix_short_magnitude (parser->start), +           mix_short_magnitude (parser->end)); +  fprintf (context.file, _("\n*** Symbol table\n")); +  mix_symbol_table_print (parser->symbol_table, MIX_SYM_ROWS, +                          context.file, TRUE); +  fprintf (context.file, _("\n*** End of summary ***\n"));    mix_file_delete (mfile);    return parser->status;  } | 
