📄 mix_parser.c
字号:
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 + -