Neptune supports named macros, though they are only lists of kind commands.
define MAX_KIND_MACRO_LENGTH 20 /* maximum number of commands in any one macro */
classdef kind_macro_definition {
struct text_stream *kind_macro_name; /* including the sharp, e.g., "#UNIT" */
int kind_macro_line_count;
struct single_kind_command kind_macro_line[MAX_KIND_MACRO_LENGTH];
}
kind_macro_definition *current_km = NULL; /* the one now being recorded */
kind_macro_definition *NeptuneMacros::new(text_stream *name) {
kind_macro_definition *tmd = CREATE(kind_macro_definition);
tmd->kind_macro_line_count = 0;
tmd->kind_macro_name = Str::duplicate(name);
return tmd;
}
kind_macro_definition *NeptuneMacros::parse_name(text_stream *name) {
kind_macro_definition *tmd;
LOOP_OVER(tmd, kind_macro_definition)
if (Str::eq(name, tmd->kind_macro_name))
return tmd;
return NULL;
}
int NeptuneMacros::recording(void) {
if (current_km) return TRUE;
return FALSE;
}
void NeptuneMacros::begin(text_stream *name, text_file_position *tfp) {
if (NeptuneMacros::parse_name(name))
NeptuneFiles::error(name, I"duplicate definition of kind command macro", tfp);
else
current_km = NeptuneMacros::new(name);
}
void NeptuneMacros::record_into_macro(single_kind_command stc, text_file_position *tfp) {
if (current_km == NULL)
NeptuneFiles::error(NULL, I"kind macro not being recorded", tfp);
else if (current_km->kind_macro_line_count >= MAX_KIND_MACRO_LENGTH)
NeptuneFiles::error(current_km->kind_macro_name,
I"kind macro contains too many lines", tfp);
else current_km->kind_macro_line[current_km->kind_macro_line_count++] = stc;
}
void NeptuneMacros::end(text_file_position *tfp) {
if (current_km == NULL) NeptuneFiles::error(NULL,
I"ended kind macro outside one", tfp);
current_km = NULL;
}
- The structure kind_macro_definition is private to this section.
§2. Playing back is easier, since it's just a matter of despatching the stored commands in sequence to the relevant kind.
void NeptuneMacros::play_back(kind_macro_definition *macro, kind_constructor *con, text_file_position *tfp) { if (macro == NULL) NeptuneFiles::error(NULL, I"no such kind macro to play back", tfp); LOGIF(KIND_CREATIONS, "Macro %S on %S (%d lines)\n", macro->kind_macro_name, con->explicit_identifier, macro->kind_macro_line_count); LOG_INDENT; for (int i=0; i<macro->kind_macro_line_count; i++) KindCommands::apply(macro->kind_macro_line[i], con); LOG_OUTDENT; LOGIF(KIND_CREATIONS, "Macro %S ended\n", macro->kind_macro_name); }