aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--parser.cpp70
-rw-r--r--parser.h12
-rw-r--r--sciteco.h2
-rw-r--r--undo.h9
4 files changed, 79 insertions, 14 deletions
diff --git a/parser.cpp b/parser.cpp
index 7c10445..2c15da7 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -9,12 +9,27 @@
gint macro_pc = 0;
static struct {
- StateStart start;
+ StateStart start;
} states;
static State *current_state = &states.start;
-gboolean
+static struct {
+ bool colon;
+ bool at;
+} modifiers = {false, false};
+
+static enum {
+ MODE_NORMAL = 0,
+ MODE_PARSE_ONLY
+} mode = MODE_NORMAL;
+
+#define BEGIN_EXEC(STATE) G_STMT_START { \
+ if (mode != MODE_NORMAL) \
+ return STATE; \
+} G_STMT_END
+
+bool
macro_execute(const gchar *macro)
{
while (macro[macro_pc]) {
@@ -22,13 +37,13 @@ macro_execute(const gchar *macro)
message_display(GTK_MESSAGE_ERROR,
"Syntax error \"%c\"",
macro[macro_pc]);
- return FALSE;
+ return false;
}
macro_pc++;
}
- return TRUE;
+ return true;
}
State::State()
@@ -37,7 +52,18 @@ State::State()
transitions[i] = NULL;
}
-gboolean
+bool
+State::eval_colon(void)
+{
+ if (!modifiers.colon)
+ return false;
+
+ undo.push_var<bool>(modifiers.colon);
+ modifiers.colon = false;
+ return true;
+}
+
+bool
State::input(gchar chr)
{
State *state = current_state;
@@ -47,7 +73,7 @@ State::input(gchar chr)
if (!next)
/* Syntax error */
- return FALSE;
+ return false;
if (next == state)
break;
@@ -61,7 +87,7 @@ State::input(gchar chr)
current_state = state;
}
- return TRUE;
+ return true;
}
State *
@@ -107,33 +133,41 @@ StateStart::custom(gchar chr)
* arithmetics
*/
if (g_ascii_isdigit(chr)) {
+ BEGIN_EXEC(this);
expressions.add_digit(chr);
return this;
}
switch (g_ascii_toupper(chr)) {
case '/':
+ BEGIN_EXEC(this);
expressions.push_calc(Expressions::OP_DIV);
break;
case '*':
+ BEGIN_EXEC(this);
expressions.push_calc(Expressions::OP_MUL);
break;
case '+':
+ BEGIN_EXEC(this);
expressions.push_calc(Expressions::OP_ADD);
break;
case '-':
+ BEGIN_EXEC(this);
if (!expressions.args())
expressions.set_num_sign(-expressions.num_sign);
else
expressions.push_calc(Expressions::OP_SUB);
break;
case '&':
+ BEGIN_EXEC(this);
expressions.push_calc(Expressions::OP_AND);
break;
case '#':
+ BEGIN_EXEC(this);
expressions.push_calc(Expressions::OP_OR);
break;
case '(':
+ BEGIN_EXEC(this);
if (expressions.num_sign < 0) {
expressions.push(-1);
expressions.push_calc(Expressions::OP_MUL);
@@ -141,22 +175,43 @@ StateStart::custom(gchar chr)
expressions.push(Expressions::OP_BRACE);
break;
case ')':
+ BEGIN_EXEC(this);
expressions.eval(true);
break;
case ',':
+ BEGIN_EXEC(this);
expressions.eval();
expressions.push(Expressions::OP_NEW);
break;
+ case '.':
+ BEGIN_EXEC(this);
+ expressions.eval();
+ expressions.push(editor_msg(SCI_GETCURRENTPOS));
+ break;
+ case 'Z':
+ BEGIN_EXEC(this);
+ expressions.eval();
+ expressions.push(editor_msg(SCI_GETLENGTH));
+ break;
+ case 'H':
+ BEGIN_EXEC(this);
+ expressions.eval();
+ expressions.push(0);
+ expressions.push(editor_msg(SCI_GETLENGTH));
+ break;
/*
* commands
*/
case 'C':
+ BEGIN_EXEC(this);
move(expressions.pop_num_calc());
break;
case 'R':
+ BEGIN_EXEC(this);
move(-expressions.pop_num_calc());
break;
case '=':
+ BEGIN_EXEC(this);
message_display(GTK_MESSAGE_OTHER, "%" G_GINT64_FORMAT,
expressions.pop_num_calc());
break;
@@ -166,3 +221,4 @@ StateStart::custom(gchar chr)
return this;
}
+
diff --git a/parser.h b/parser.h
index 3c4f543..40a8c9f 100644
--- a/parser.h
+++ b/parser.h
@@ -12,23 +12,26 @@ protected:
State *transitions[MAX_TRANSITIONS];
inline void
- init(const gchar *chars, State *state)
+ init(const gchar *chars, State &state)
{
while (*chars)
- transitions[(int)*chars++] = state;
+ transitions[(int)*chars++] = &state;
}
inline void
init(const gchar *chars)
{
- init(chars, this);
+ init(chars, *this);
}
public:
State();
- static gboolean input(gchar chr);
+ static bool input(gchar chr);
State *get_next_state(gchar chr);
+protected:
+ static bool eval_colon(void);
+
virtual State *
custom(gchar chr)
{
@@ -40,6 +43,7 @@ class StateStart : public State {
public:
StateStart();
+private:
void move(gint64 n);
State *custom(gchar chr);
diff --git a/sciteco.h b/sciteco.h
index f0425d6..b0c2c84 100644
--- a/sciteco.h
+++ b/sciteco.h
@@ -21,7 +21,7 @@ void cmdline_display(const gchar *cmdline);
sptr_t editor_msg(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0);
-gboolean macro_execute(const gchar *macro);
+bool macro_execute(const gchar *macro);
#define IS_CTL(C) ((C) < ' ')
#define CTL_ECHO(C) ((C) | 0x40)
diff --git a/undo.h b/undo.h
index 9c7ac5f..17a8ba8 100644
--- a/undo.h
+++ b/undo.h
@@ -52,7 +52,9 @@ extern class UndoStack {
SLIST_HEAD(undo_head, UndoToken) head;
public:
- UndoStack()
+ bool enabled;
+
+ UndoStack(bool _enabled = true) : enabled(_enabled)
{
SLIST_INIT(&head);
}
@@ -61,7 +63,10 @@ public:
inline void
push(UndoToken *token)
{
- SLIST_INSERT_HEAD(&head, token, tokens);
+ if (enabled)
+ SLIST_INSERT_HEAD(&head, token, tokens);
+ else
+ delete token;
}
void push_msg(unsigned int iMessage,