#ifndef __GOTO_H #define __GOTO_H #include #include #include "sciteco.h" #include "parser.h" #include "undo.h" #include "rbtree.h" 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); } }; /* * whether to generate UndoTokens (unnecessary in macro invocations) */ bool must_undo; public: GotoTable(bool _undo = true) : RBTree(), must_undo(_undo) {} gint remove(gchar *name); gint find(gchar *name); gint set(gchar *name, gint pc); inline void undo_set(gchar *name, gint pc = -1) { if (must_undo) undo.push(new UndoTokenSet(this, name, pc)); } #ifdef DEBUG void dump(void); #endif }; namespace Goto { extern GotoTable *table; extern gchar *skip_label; } /* * Command states */ class StateLabel : public State { public: StateLabel(); private: State *custom(gchar chr) throw (Error); }; class StateGotoCmd : public StateExpectString { private: State *done(const gchar *str) throw (Error); }; namespace States { extern StateLabel label; extern StateGotoCmd gotocmd; } #endif