diff options
Diffstat (limited to 'mixlib/mix_parser.c')
-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; } |