diff options
-rw-r--r-- | parser.cpp | 12 | ||||
-rw-r--r-- | qbuffers.cpp | 93 | ||||
-rw-r--r-- | qbuffers.h | 35 |
3 files changed, 129 insertions, 11 deletions
@@ -10,6 +10,8 @@ #include "qbuffers.h" #include "parser.h" +//#define DEBUG + gint macro_pc = 0; namespace States { @@ -40,6 +42,12 @@ bool macro_execute(const gchar *macro) { while (macro[macro_pc]) { +#ifdef DEBUG + g_printf("EXEC(%d): input='%c'/%x, state=%p\n", + macro_pc, macro[macro_pc], macro[macro_pc], + States::current); +#endif + if (!State::input(macro[macro_pc])) { message_display(GTK_MESSAGE_ERROR, "Syntax error \"%c\"", @@ -193,6 +201,10 @@ StateStart::StateStart() : State() transitions['^'] = &States::control; transitions['E'] = &States::ecommand; transitions['I'] = &States::insert; + transitions['Q'] = &States::getqreginteger; + transitions['U'] = &States::setqreginteger; + transitions['%'] = &States::increaseqreg; + transitions['M'] = &States::macro; } void diff --git a/qbuffers.cpp b/qbuffers.cpp index be32c96..efcc48d 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -21,6 +21,10 @@ namespace States { StateLoadQReg loadqreg; StateCtlUCommand ctlucommand; StateSetQRegString setqregstring; + StateGetQRegInteger getqreginteger; + StateSetQRegInteger setqreginteger; + StateIncreaseQReg increaseqreg; + StateMacro macro; } Ring ring; @@ -44,6 +48,26 @@ QRegister::set_string(const gchar *str) qregisters.current->edit(); } +gchar * +QRegister::get_string(void) +{ + gint size; + gchar *str; + + edit(); + + size = editor_msg(SCI_GETLENGTH) + 1; + str = (gchar *)g_malloc(size); + editor_msg(SCI_GETTEXT, size, (sptr_t)str); + + if (ring.current) + ring.current->edit(); + else /* qregisters.current != NULL */ + qregisters.current->edit(); + + return str; +} + bool QRegister::load(const gchar *filename) { @@ -285,10 +309,7 @@ State * StateEQCommand::got_register(QRegister *reg) { BEGIN_EXEC(&States::loadqreg); - - undo.push_var<QRegister*>(register_argument); register_argument = reg; - return &States::loadqreg; } @@ -316,10 +337,7 @@ State * StateCtlUCommand::got_register(QRegister *reg) { BEGIN_EXEC(&States::setqregstring); - - undo.push_var<QRegister*>(register_argument); register_argument = reg; - return &States::setqregstring; } @@ -334,3 +352,66 @@ StateSetQRegString::done(const gchar *str) return &States::start; } + +State * +StateGetQRegInteger::got_register(QRegister *reg) +{ + BEGIN_EXEC(&States::start); + + expressions.eval(); + expressions.push(reg->integer); + + return &States::start; +} + +State * +StateSetQRegInteger::got_register(QRegister *reg) +{ + BEGIN_EXEC(&States::start); + + undo.push_var<gint64>(reg->integer); + reg->integer = expressions.pop_num_calc(); + + return &States::start; +} + +State * +StateIncreaseQReg::got_register(QRegister *reg) +{ + BEGIN_EXEC(&States::start); + + undo.push_var<gint64>(reg->integer); + reg->integer += expressions.pop_num_calc(); + expressions.push(reg->integer); + + return &States::start; +} + +State * +StateMacro::got_register(QRegister *reg) +{ + gint pc = macro_pc; + gchar *str; + bool rc; + + BEGIN_EXEC(&States::start); + + /* + * need this to fixup state on rubout: state machine emits undo token + * resetting state to StateMacro, but the macro executed also emitted + * undo tokens resetting the state to StateStart + */ + undo.push_var<State*>(States::current); + States::current = &States::start; + + macro_pc = 0; + str = reg->get_string(); + rc = macro_execute(str); + g_free(str); + macro_pc = pc; + States::current = this; + if (!rc) + return NULL; + + return &States::start; +} @@ -39,26 +39,28 @@ public: return g_strcmp0(name, ((QRegister &)entry).name); } - void set_string(const gchar *str); inline document * - get_string(void) + get_document(void) { if (!string) string = (document *)editor_msg(SCI_CREATEDOCUMENT); return string; } + void set_string(const gchar *str); + gchar *get_string(void); + inline void edit(void) { - editor_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_string()); + editor_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_document()); editor_msg(SCI_GOTOPOS, dot); } inline void undo_edit(void) { undo.push_msg(SCI_GOTOPOS, dot); - undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_string()); + undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_document()); } bool load(const gchar *filename); @@ -71,7 +73,7 @@ extern class QRegisterTable : public RBTree { QRegister *reg = new QRegister(name); insert(reg); /* make sure document is initialized */ - reg->get_string(); + reg->get_document(); } public: @@ -252,6 +254,25 @@ private: State *done(const gchar *str); }; +class StateGetQRegInteger : public StateExpectQReg { +private: + State *got_register(QRegister *reg); +}; + +class StateSetQRegInteger : public StateExpectQReg { +private: + State *got_register(QRegister *reg); +}; + +class StateIncreaseQReg : public StateExpectQReg { +private: + State *got_register(QRegister *reg); +}; + +class StateMacro : public StateExpectQReg { +private: + State *got_register(QRegister *reg); +}; namespace States { extern StateFile file; @@ -259,6 +280,10 @@ namespace States { extern StateLoadQReg loadqreg; extern StateCtlUCommand ctlucommand; extern StateSetQRegString setqregstring; + extern StateGetQRegInteger getqreginteger; + extern StateSetQRegInteger setqreginteger; + extern StateIncreaseQReg increaseqreg; + extern StateMacro macro; } /* |