diff options
Diffstat (limited to 'mixlib')
-rw-r--r-- | mixlib/mix_vm_command.c | 100 | ||||
-rw-r--r-- | mixlib/mix_vm_command.h | 12 |
2 files changed, 111 insertions, 1 deletions
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c index 677b5f8..19c4695 100644 --- a/mixlib/mix_vm_command.c +++ b/mixlib/mix_vm_command.c @@ -50,6 +50,8 @@ struct mix_vm_cmd_dispatcher_t mix_vm_t *vm; /* the virtual machine */ gboolean result; /* last command's outcome */ gchar *program; /* the name of the last loaded program */ + gchar *editor; /* edit command line template */ + gchar *assembler; /* compile command line template */ FILE *out; /* message output file */ FILE *err; /* error output file */ mix_dump_context_t *dump; /* dump context for output */ @@ -94,6 +96,8 @@ DEC_FUN (weval_); DEC_FUN (w2d_); DEC_FUN (tron_); DEC_FUN (troff_); +DEC_FUN (edit_); +DEC_FUN (compile_); /* internal command info struct */ typedef struct { @@ -108,6 +112,9 @@ typedef struct { command_ commands_[] = { { "help", cmd_help_, N_("Display this text"), "help [COMMAND]"}, { "load", cmd_load_, N_("Load a MIX code file"), "load FILENAME"}, + { "edit", cmd_edit_, N_("Edit a MIXAL source file"), "edit [FILENAME]"}, + { "compile", cmd_compile_, N_("Compile a MIXAL source file"), + "compile [FILENAME]"}, { "run", cmd_run_, N_("Run loaded or given MIX code file"), "run [FILENAME]"}, { "next", cmd_next_, N_("Execute next instruction(s)"), @@ -197,6 +204,8 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */ result->printtime = TRUE; result->trace = FALSE; result->program = NULL; + result->editor = NULL; + result->assembler = NULL; result->eval = mix_eval_new (); result->dump = mix_dump_context_new (out_fd, MIX_SHORT_ZERO, MIX_SHORT_ZERO, @@ -214,16 +223,37 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */ } /* delete (does not close the fds in the constructor) */ -extern void +void mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis) { g_return_if_fail (dis != NULL); mix_eval_delete (dis->eval); mix_dump_context_delete (dis->dump); mix_vm_delete (dis->vm); + if (dis->editor) g_free (dis->editor); + if (dis->editor) g_free (dis->assembler); g_free (dis); } +/* set editor and compiler templates */ +void +mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis, + const gchar *edit_tplt) +{ + g_return_if_fail (dis != NULL); + if (dis->editor) g_free (dis->editor); + dis->editor = (edit_tplt) ? g_strdup (edit_tplt) : NULL; +} + +void +mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis, + const gchar *asm_tplt) +{ + g_return_if_fail (dis != NULL); + if (dis->assembler) g_free (dis->assembler); + dis->assembler = (asm_tplt) ? g_strdup (asm_tplt) : NULL; +} + /* install hooks */ void mix_vm_cmd_dispatcher_pre_hook (mix_vm_cmd_dispatcher_t *dis, @@ -508,6 +538,74 @@ cmd_load_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) return TRUE; } +static const gchar * +get_src_file_path_ (mix_vm_cmd_dispatcher_t *dis) +{ + static gchar *PATH = NULL; + + const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis); + const mix_src_file_t *f = mix_vm_get_src_file (vm); + + if (PATH) + { + g_free (PATH); + PATH = NULL; + } + + if (f) + PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT); + + return PATH; +} + + +static gboolean +cmd_edit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + if (dis->editor == NULL) + { + fputs (_("Editor not specified (set MDK_EDITOR)\n"), dis->err); + return FALSE; + } + if (!arg || *arg == '\0') arg = get_src_file_path_ (dis); + if (!arg) + { + fputs (_("MIXAL source file path not found\n"), dis->err); + return FALSE; + } + else + { + gchar *cmd = g_strdup_printf (dis->editor, arg); + system (cmd); + g_free (cmd); + return TRUE; + } +} + +static gboolean +cmd_compile_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + if (dis->assembler == NULL) + { + fputs (_("MIX assembler not specified\n"), dis->err); + return FALSE; + } + if (!arg || *arg == '\0') arg = get_src_file_path_ (dis); + if (!arg) + { + fputs (_("MIXAL source file path not found\n"), dis->err); + return FALSE; + } + else + { + gchar *cmd = g_strdup_printf (dis->assembler, arg); + system (cmd); + g_free (cmd); + return TRUE; + } +} + + static gboolean cmd_run_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h index 856c2d5..ad73064 100644 --- a/mixlib/mix_vm_command.h +++ b/mixlib/mix_vm_command.h @@ -39,6 +39,8 @@ typedef struct mix_vm_cmd_dispatcher_t mix_vm_cmd_dispatcher_t; typedef enum { MIX_CMD_HELP = 0, /* echo help message */ MIX_CMD_LOAD, /* load a mix program */ + MIX_CMD_EDIT, /* edit mixal source */ + MIX_CMD_COMPILE, /* compile mixal source */ MIX_CMD_RUN, /* run a loaded program */ MIX_CMD_NEXT, /* run next instruction */ MIX_CMD_LOC, /* print location pointer */ @@ -97,6 +99,16 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */ extern void mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis); + +/* set editor and compiler templates */ +extern void +mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis, + const gchar *edit_tplt); + +extern void +mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis, + const gchar *asm_tplt); + /* dispatch a command */ extern gboolean /* TRUE if success, FALSE otherwise */ mix_vm_cmd_dispatcher_dispatch (mix_vm_cmd_dispatcher_t *dis, |