summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mixlib/mix_parser.c73
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;
}