diff options
-rw-r--r-- | src/parser.cpp | 69 | ||||
-rw-r--r-- | src/parser.h | 15 |
2 files changed, 39 insertions, 45 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 140a0a7..6fefe80 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -240,9 +240,20 @@ State::get_next_state(gchar chr) throw (Error, ReplaceCmdline) return next; } +void +StringBuildingMachine::reset(void) +{ + MicroStateMachine::reset(); + undo.push_obj(qregspec_machine) = NULL; + undo.push_var(mode) = MODE_NORMAL; + undo.push_var(toctl) = false; +} + gchar * StringBuildingMachine::input(gchar chr) throw (State::Error) { + QRegister *reg; + switch (mode) { case MODE_UPPER: chr = g_ascii_toupper(chr); @@ -299,8 +310,14 @@ StateUpper: StateCtlE: switch (g_ascii_toupper(chr)) { - case 'Q': set(&&StateCtlEQ); break; - case 'U': set(&&StateCtlEU); break; + case 'Q': + undo.push_obj(qregspec_machine) = new QRegSpecMachine; + set(&&StateCtlEQ); + break; + case 'U': + undo.push_obj(qregspec_machine) = new QRegSpecMachine; + set(&&StateCtlEU); + break; default: set(NULL); return g_strdup((gchar []){CTL_KEY('E'), chr, '\0'}); @@ -309,58 +326,34 @@ StateCtlE: return NULL; StateCtlEU: - if (chr == '.') { - set(&&StateCtlEULocal); + reg = qregspec_machine->input(chr); + if (!reg) return NULL; - } else { - QRegister *reg; - - reg = QRegisters::globals[g_ascii_toupper(chr)]; - if (!reg) - throw State::InvalidQRegError(chr); - set(NULL); - return g_strdup(CHR2STR(reg->get_integer())); - } - -StateCtlEULocal: { - QRegister *reg; - reg = (*QRegisters::locals)[g_ascii_toupper(chr)]; - if (!reg) - throw State::InvalidQRegError(chr, true); + undo.push_obj(qregspec_machine) = NULL; set(NULL); return g_strdup(CHR2STR(reg->get_integer())); -} StateCtlEQ: - if (chr == '.') { - set(&&StateCtlEQLocal); + reg = qregspec_machine->input(chr); + if (!reg) return NULL; - } else { - QRegister *reg; - - reg = QRegisters::globals[g_ascii_toupper(chr)]; - if (!reg) - throw State::InvalidQRegError(chr); - set(NULL); - return reg->get_string(); - } -StateCtlEQLocal: { - QRegister *reg; - - reg = (*QRegisters::locals)[g_ascii_toupper(chr)]; - if (!reg) - throw State::InvalidQRegError(chr, true); + undo.push_obj(qregspec_machine) = NULL; set(NULL); return reg->get_string(); -} StateEscaped: set(NULL); return g_strdup(CHR2STR(chr)); } +StringBuildingMachine::~StringBuildingMachine() +{ + if (qregspec_machine) + delete qregspec_machine; +} + State * StateExpectString::custom(gchar chr) throw (Error) { diff --git a/src/parser.h b/src/parser.h index 26cd064..7ef6329 100644 --- a/src/parser.h +++ b/src/parser.h @@ -135,7 +135,12 @@ public: virtual Type input(gchar chr) throw (State::Error) = 0; }; +/* avoid circular dependency on qregisters.h */ +class QRegSpecMachine; + class StringBuildingMachine : public MicroStateMachine<gchar *> { + QRegSpecMachine *qregspec_machine; + enum Mode { MODE_NORMAL, MODE_UPPER, @@ -146,15 +151,11 @@ class StringBuildingMachine : public MicroStateMachine<gchar *> { public: StringBuildingMachine() : MicroStateMachine(), + qregspec_machine(NULL), mode(MODE_NORMAL), toctl(false) {} + ~StringBuildingMachine(); - void - reset(void) - { - MicroStateMachine::reset(); - undo.push_var(mode) = MODE_NORMAL; - undo.push_var(toctl) = false; - } + void reset(void); gchar *input(gchar chr) throw (State::Error); }; |