diff options
Diffstat (limited to 'goto.cpp')
-rw-r--r-- | goto.cpp | 183 |
1 files changed, 55 insertions, 128 deletions
@@ -1,5 +1,3 @@ -#include <bsd/sys/tree.h> - #include <glib.h> #include <glib/gprintf.h> @@ -7,7 +5,6 @@ #include "expressions.h" #include "parser.h" #include "undo.h" -#include "rbtree.h" #include "goto.h" namespace States { @@ -17,146 +14,75 @@ namespace States { static gchar *skip_label = NULL; -class GotoTable : public RBTree { - class UndoTokenSet : public UndoToken { - GotoTable *table; - - gchar *name; - gint pc; - - public: - UndoTokenSet(GotoTable *_table, gchar *_name, gint _pc = -1) - : table(_table), name(g_strdup(_name)), pc(_pc) {} - ~UndoTokenSet() - { - g_free(name); - } - - void - run(void) - { - table->set(name, pc); -#ifdef DEBUG - table->dump(); -#endif - } - }; - - class Label : public RBEntry { - public: - gchar *name; - gint pc; - - Label(gchar *_name, gint _pc = -1) - : name(g_strdup(_name)), pc(_pc) {} - ~Label() - { - g_free(name); - } - - int - operator <(RBEntry &l2) - { - return g_strcmp0(name, ((Label &)l2).name); - } - }; - -public: - GotoTable() : RBTree() {} - - gint - remove(gchar *name) - { - gint existing_pc = -1; - - Label label(name); - Label *existing = (Label *)RBTree::find(&label); +GotoTable *goto_table = NULL; - if (existing) { - existing_pc = existing->pc; - RBTree::remove(existing); - delete existing; - } - - return existing_pc; - } +gint +GotoTable::remove(gchar *name) +{ + gint existing_pc = -1; - gint - find(gchar *name) - { - Label label(name); - Label *existing = (Label *)RBTree::find(&label); + Label label(name); + Label *existing = (Label *)RBTree::find(&label); - return existing ? existing->pc : -1; + if (existing) { + existing_pc = existing->pc; + RBTree::remove(existing); + delete existing; } - gint - set(gchar *name, gint pc) - { - if (pc < 0) - return remove(name); - - Label *label = new Label(name, pc); - Label *existing; - gint existing_pc = -1; - - existing = (Label *)RBTree::find(label); - if (existing) { - existing_pc = existing->pc; - g_free(existing->name); - existing->name = label->name; - existing->pc = label->pc; - - label->name = NULL; - delete label; - } else { - RBTree::insert(label); - } - -#ifdef DEBUG - dump(); -#endif - - return existing_pc; - } + return existing_pc; +} - inline void - undo_set(gchar *name, gint pc = -1) - { - undo.push(new UndoTokenSet(this, name, pc)); - } +gint +GotoTable::find(gchar *name) +{ + Label label(name); + Label *existing = (Label *)RBTree::find(&label); - void - clear(void) - { - Label *cur; + return existing ? existing->pc : -1; +} - while ((cur = (Label *)RBTree::min())) { - RBTree::remove(cur); - delete cur; - } +gint +GotoTable::set(gchar *name, gint pc) +{ + if (pc < 0) + return remove(name); + + Label *label = new Label(name, pc); + Label *existing; + gint existing_pc = -1; + + existing = (Label *)RBTree::find(label); + if (existing) { + existing_pc = existing->pc; + g_free(existing->name); + existing->name = label->name; + existing->pc = label->pc; + + label->name = NULL; + delete label; + } else { + RBTree::insert(label); } #ifdef DEBUG - void - dump(void) - { - for (Label *cur = (Label *)RBTree::min(); - cur != NULL; - cur = (Label *)cur->next()) - g_printf("table[\"%s\"] = %d\n", cur->name, cur->pc); - g_printf("---END---\n"); - } + dump(); #endif -}; -static GotoTable table; + return existing_pc; +} +#ifdef DEBUG void -goto_table_clear(void) +GotoTable::dump(void) { - table.clear(); + for (Label *cur = (Label *)RBTree::min(); + cur != NULL; + cur = (Label *)cur->next()) + g_printf("table[\"%s\"] = %d\n", cur->name, cur->pc); + g_printf("---END---\n"); } +#endif /* * Command states @@ -173,7 +99,8 @@ StateLabel::custom(gchar chr) throw (Error) gchar *new_str; if (chr == '!') { - table.undo_set(strings[0], table.set(strings[0], macro_pc)); + goto_table->undo_set(strings[0], + goto_table->set(strings[0], macro_pc)); if (!g_strcmp0(strings[0], skip_label)) { undo.push_str(skip_label); @@ -211,7 +138,7 @@ StateGotoCmd::done(const gchar *str) throw (Error) labels = g_strsplit(str, ",", -1); if (value > 0 && value <= g_strv_length(labels) && *labels[value-1]) { - gint pc = table.find(labels[value-1]); + gint pc = goto_table->find(labels[value-1]); if (pc >= 0) { macro_pc = pc; |