⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mix_parser.c

📁 汇编语言编程源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static gintwrite_code_ (gpointer address, gpointer ins_node, gpointer context){  mix_ins_desc_t desc;  struct write_code_context_ *cntx = (struct write_code_context_ *)context;  desc.ins = ((ins_node_ *)ins_node)->ins;  desc.lineno = ((ins_node_ *)ins_node)->lineno;  desc.address = (mix_address_t)GPOINTER_TO_UINT (address);  if ( mix_code_file_write_ins (cntx->file, &desc) )    return FALSE;  else     {      cntx->parser->status = MIX_PERR_NOWRITE;      return TRUE;    }}mix_parser_err_tmix_parser_write_code (mix_parser_t *parser, const gchar *code_file, 		       gboolean debug){  struct write_code_context_ context;  const gchar *cfname = (code_file) ?    code_file : mix_file_base_name (parser->in_file);  gchar *source_path;      g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);  if  (parser->status != MIX_PERR_OK ) return parser->status;  context.parser = parser;  if (!g_path_is_absolute (mix_file_base_name (parser->in_file)))    {      gchar *dir = g_get_current_dir ();      source_path = g_strconcat (dir, G_DIR_SEPARATOR_S,				 mix_file_base_name (parser->in_file), NULL);      g_free (dir);    }  else    source_path = g_strdup (mix_file_base_name (parser->in_file));      context.file = mix_code_file_new_write (cfname, parser->start, source_path,					  debug, parser->symbol_table);  g_free (source_path);  if (context.file == NULL) return MIX_PERR_NOOUT;  g_tree_traverse (parser->ins_table, write_code_, 		   G_IN_ORDER, (gpointer)&context);  mix_code_file_delete (context.file);  return parser->status;}/* Produce a listing file summarising the compilation */static gintwrite_listing_ (gpointer address, gpointer ins, gpointer context){  guint k;  FILE *file = (FILE *)context;  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, "%d\t%s ", 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 (instext) g_free (instext);  return FALSE;}mix_parser_err_tmix_parser_write_listing (mix_parser_t *parser, const gchar *list_file){  FILE *file;  mix_file_t *mfile;  const gchar *name;    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"), 	   mix_file_base_name (parser->in_file), 	   mix_file_extension (parser->in_file));  fputs ( _("*** Address / Compiled word / Symbolic rep / Source file line\n"),	  file);  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"));  mix_file_delete (mfile);  return parser->status;}/* load a virtual machine's memory with the contents of a compiled file */static gintload_vm_ (gpointer address, gpointer ins, gpointer vm){  mix_vm_set_addr_contents ((mix_vm_t*)vm,			    (mix_address_t)GPOINTER_TO_UINT (address), 			    ((ins_node_ *)ins)->ins);  return FALSE;}mix_parser_err_tmix_parser_load_vm (const mix_parser_t *parser, mix_vm_t *vm){  g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);  g_return_val_if_fail (vm != NULL, MIX_PERR_INTERNAL);  g_return_val_if_fail (parser->status == MIX_PERR_OK, parser->status);  mix_vm_reset (vm);  g_tree_traverse (parser->ins_table, load_vm_, G_IN_ORDER, (gpointer)vm);  mix_vm_set_start_addr (vm, parser->start);  return parser->status;}/*------------ xmiparser.h functions -------------------------------------*//* functions to manipulate mix_parser_t during compilation *//* symbol table *//* Define a new symbol with value equal to the current loc_count * and update future refs to this symbol */mix_parser_err_tmix_parser_define_symbol_here (mix_parser_t *parser, const gchar *name){  mix_word_t value = mix_short_to_word_fast (parser->loc_count);  return mix_parser_define_symbol_value (parser, name, value);}mix_parser_err_tmix_parser_define_symbol_value (mix_parser_t *parser, const gchar *name,				mix_word_t value){  g_assert (parser != NULL && name != NULL);      switch (mix_symbol_table_add (parser->symbol_table, name, value))    {    case MIX_SYM_OK:       if ( parser->status == MIX_PERR_NOCOMP ) 	update_future_refs_value_ (parser, name, value);      return MIX_PERR_OK;    case MIX_SYM_LONG: return MIX_PERR_LONG_SYMBOL;    case MIX_SYM_DUP: return MIX_PERR_DUP_SYMBOL;    default: return MIX_PERR_INTERNAL;    }}/* Obtain the value of a symbol */voidmix_parser_set_future_ref (mix_parser_t *parser, const gchar *name){  const gchar *nname = name;  GSList *list;  g_assert (parser != NULL && name != NULL);  if ( parser->status == MIX_PERR_NOCOMP )    {      list =  g_hash_table_lookup (parser->future_refs, name);      if ( list == NULL ) nname = g_strdup (name);      list = g_slist_prepend (list, (gpointer)((guint)parser->loc_count));      g_hash_table_insert (parser->future_refs, (gpointer)nname, list);    }}/* Redefine the value of a local symbol as the current loc_count */voidmix_parser_manage_local_symbol (mix_parser_t *parser, const gchar *name,				mix_short_t value){  gchar ref[3];  ref[2] = 0;      g_assert (parser != NULL && name != NULL);  g_assert (strlen(name) == 2);    switch (name[1])    {    case 'f': case 'F':      mix_parser_set_future_ref (parser, name);      break;    case 'h': case 'H':      ref[0] = name[0];      ref[1] = 'F';      if ( parser->status == MIX_PERR_NOCOMP ) 	update_future_refs_value_ (parser, ref, value);      ref[1] = 'B';      mix_symbol_table_insert (parser->symbol_table, ref, 			       mix_short_to_word_fast (value));      break;    default:      return;    }}/* Literal strings symbols */voidmix_parser_define_ls (mix_parser_t *parser, mix_word_t value){  gchar *name = g_strdup_printf ("%05d", parser->cur_ls++);  mix_symbol_table_add (parser->ls_table, name, value);  mix_parser_set_future_ref (parser, name);  g_free (name);}/* Compilation */voidmix_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);}voidmix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno){  g_assert (parser != NULL);  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);    }}/* Error handling */void mix_parser_log_error (mix_parser_t *parser, mix_parser_err_t error,		      gint lineno, const gchar *comment, gboolean warn){  g_assert (parser != NULL);  if ( warn )    parser->warn_count += 1;  else    {      parser->err_count += 1;      parser->err_line = lineno;      parser->status = error;    }      fprintf (stderr, "%s%s:%d: %s: %s",	   mix_file_base_name (parser->in_file), 	   mix_file_extension (parser->in_file),	   lineno, warn ? _("warning"):_("error"), _(ERR_MESSAGE_[error]));  if (comment != NULL)    fprintf (stderr, ": %s\n", comment);  else    fputs ("\n", stderr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -