diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-11 04:03:14 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-11 04:03:14 +0100 |
commit | 46316ece115c100a8146303957a3bec07a1d2dde (patch) | |
tree | 9486c8e0a2b623a7db36af8840cfce5a489e2b90 | |
parent | d6593762d97bf44f3a398dc4fae714a9e20a24b2 (diff) | |
download | sciteco-46316ece115c100a8146303957a3bec07a1d2dde.tar.gz |
Q-Register table and EQx command
-rw-r--r-- | main.cpp | 1 | ||||
-rw-r--r-- | parser.cpp | 17 | ||||
-rw-r--r-- | parser.h | 22 | ||||
-rw-r--r-- | qbuffers.cpp | 49 | ||||
-rw-r--r-- | qbuffers.h | 101 | ||||
-rw-r--r-- | rbtree.h | 4 |
6 files changed, 188 insertions, 6 deletions
@@ -152,6 +152,7 @@ main(int argc, char **argv) editor_msg(SCI_STYLESETFORE, SCE_C_STRING, 0x800080); editor_msg(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1); + qregisters.initialize(); ring.edit(NULL); undo.enabled = true; @@ -168,6 +168,22 @@ StateExpectString::custom(gchar chr) return this; } +StateExpectQReg::StateExpectQReg() : State() +{ + transitions['\0'] = this; +} + +State * +StateExpectQReg::custom(gchar chr) +{ + QRegister *reg = qregisters[(gchar []){g_ascii_toupper(chr), '\0'}]; + + if (!reg) + return NULL; + + return got_register(reg); +} + StateStart::StateStart() : State() { transitions['\0'] = this; @@ -563,6 +579,7 @@ StateECommand::StateECommand() : State() { transitions['\0'] = this; transitions['B'] = &States::file; + transitions['Q'] = &States::eqcommand; } State * @@ -49,7 +49,7 @@ public: StateExpectString() : State() {} private: - virtual State *custom(gchar chr); + State *custom(gchar chr); protected: virtual void initial(void) {} @@ -57,6 +57,26 @@ protected: virtual State *done(const gchar *str) = 0; }; +class QRegister; + +/* + * Super class for states accepting Q-Register specifications + */ +class StateExpectQReg : public State { +public: + StateExpectQReg(); + +private: + State *custom(gchar chr); + +protected: + /* + * FIXME: would be nice to pass reg as reference, but there are + * circular header dependencies... + */ + virtual State *got_register(QRegister *reg) = 0; +}; + class StateStart : public State { public: StateStart(); diff --git a/qbuffers.cpp b/qbuffers.cpp index d9eba9f..c907330 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -16,10 +16,34 @@ #include "qbuffers.h" namespace States { - StateFile file; + StateFile file; + StateEQCommand eqcommand; } Ring ring; +QRegisterTable qregisters; + +void +QRegisterTable::initialize(void) +{ + /* general purpose registers */ + for (gchar q = 'A'; q <= 'Z'; q++) + initialize_register((gchar []){q, '\0'}); + for (gchar q = '0'; q <= '9'; q++) + initialize_register((gchar []){q, '\0'}); +} + +void +QRegisterTable::edit(QRegister *reg) +{ + if (current) + current->dot = editor_msg(SCI_GETCURRENTPOS); + + reg->edit(); + + ring.current = NULL; + current = reg; +} bool Buffer::load(const gchar *filename) @@ -106,6 +130,7 @@ Ring::edit(const gchar *filename) } } + qregisters.current = NULL; current = buffer; return new_in_ring; @@ -139,7 +164,10 @@ Ring::~Ring() void StateFile::do_edit(const gchar *filename) { - ring.undo_edit(); + if (ring.current) + ring.undo_edit(); + else /* qregisters.current != NULL */ + qregisters.undo_edit(); if (ring.edit(filename)) ring.undo_close(); } @@ -203,3 +231,20 @@ StateFile::done(const gchar *str) return &States::start; } + +/* + * TODO: expect filename to read into Q-register + */ +State * +StateEQCommand::got_register(QRegister *reg) +{ + BEGIN_EXEC(&States::start); + + if (ring.current) + ring.undo_edit(); + else /* qregisters.current != NULL */ + qregisters.undo_edit(); + qregisters.edit(reg); + + return &States::start; +} @@ -11,8 +11,101 @@ #include "sciteco.h" #include "undo.h" +#include "rbtree.h" #include "parser.h" +class QRegister : public RBTree::RBEntry { +public: + gchar *name; + + gint64 integer; + + typedef void document; + document *string; + gint dot; + + QRegister(const gchar *_name) + : name(g_strdup(_name)), integer(0), string(NULL), dot(0) {} + ~QRegister() + { + if (string) + editor_msg(SCI_RELEASEDOCUMENT, 0, (sptr_t)string); + g_free(name); + } + + int + operator <(RBEntry &entry) + { + return g_strcmp0(name, ((QRegister &)entry).name); + } + + inline document * + get_string(void) + { + if (!string) + string = (document *)editor_msg(SCI_CREATEDOCUMENT); + return string; + } + + inline void + edit(void) + { + editor_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_string()); + 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()); + } +}; + +extern class QRegisterTable : public RBTree { + inline void + initialize_register(const gchar *name) + { + QRegister *reg = new QRegister(name); + insert(reg); + /* make sure document is initialized */ + reg->get_string(); + } + +public: + QRegister *current; + + QRegisterTable() : RBTree(), current(NULL) {} + + void initialize(void); + + inline QRegister * + operator [](const gchar *name) + { + QRegister reg(name); + return (QRegister *)find(®); + } + + void edit(QRegister *reg); + inline QRegister * + edit(const gchar *name) + { + QRegister *reg = operator [](name); + + if (!reg) + return NULL; + edit(reg); + return reg; + } + inline void + undo_edit(void) + { + current->dot = editor_msg(SCI_GETCURRENTPOS); + + undo.push_var<QRegister*>(current); + current->undo_edit(); + } +} qregisters; + class Buffer { class UndoTokenClose : public UndoToken { Buffer *buffer; @@ -136,8 +229,14 @@ private: State *done(const gchar *str); }; +class StateEQCommand : public StateExpectQReg { +private: + State *got_register(QRegister *reg); +}; + namespace States { - extern StateFile file; + extern StateFile file; + extern StateEQCommand eqcommand; } /* @@ -8,7 +8,7 @@ #include "undo.h" class RBTree { -protected: +public: class RBEntry; private: @@ -16,7 +16,7 @@ private: RB_PROTOTYPE_INTERNAL(Tree, RBEntry, nodes, /* unused */, static); -protected: +public: class RBEntry { public: RB_ENTRY(RBEntry) nodes; |