aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--parser.cpp12
-rw-r--r--qbuffers.cpp93
-rw-r--r--qbuffers.h35
3 files changed, 129 insertions, 11 deletions
diff --git a/parser.cpp b/parser.cpp
index 870a611..e37722e 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -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;
+}
diff --git a/qbuffers.h b/qbuffers.h
index a901e01..afabfee 100644
--- a/qbuffers.h
+++ b/qbuffers.h
@@ -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;
}
/*