summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/mix_vm_command.c100
-rw-r--r--mixlib/mix_vm_command.h12
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,