aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--parser.cpp82
-rw-r--r--parser.h14
2 files changed, 88 insertions, 8 deletions
diff --git a/parser.cpp b/parser.cpp
index 4519c75..60c2c49 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -22,11 +22,6 @@ enum Mode mode = MODE_NORMAL;
/* FIXME: perhaps integrate into Mode */
static bool skip_else = false;
-#define BEGIN_EXEC(STATE) G_STMT_START { \
- if (mode != MODE_NORMAL) \
- return STATE; \
-} G_STMT_END
-
static gint nest_level = 0;
gchar *strings[2] = {NULL, NULL};
@@ -112,6 +107,7 @@ StateStart::StateStart() : State()
init(" \r\n\v");
transitions['!'] = &states.label;
+ transitions['^'] = &states.control;
}
void
@@ -134,13 +130,11 @@ StateStart::move_lines(gint64 n)
State *
StateStart::custom(gchar chr)
{
-#if 0
/*
* <CTRL/x> commands implemented in StateCtrlCmd
*/
if (IS_CTL(chr))
- return states.ctl.get_next_state(CTL_ECHO(chr));
-#endif
+ return states.control.get_next_state(CTL_ECHO(chr));
/*
* arithmetics
@@ -425,3 +419,75 @@ StateStart::custom(gchar chr)
return this;
}
+
+StateControl::StateControl() : State()
+{
+ transitions['\0'] = this;
+}
+
+State *
+StateControl::custom(gchar chr)
+{
+ switch (g_ascii_toupper(chr)) {
+ case 'O':
+ BEGIN_EXEC(&states.start);
+ expressions.set_radix(8);
+ break;
+
+ case 'D':
+ BEGIN_EXEC(&states.start);
+ expressions.set_radix(10);
+ break;
+
+ case 'R':
+ BEGIN_EXEC(&states.start);
+ expressions.eval();
+ if (!expressions.args())
+ expressions.push(expressions.radix);
+ else
+ expressions.set_radix(expressions.pop_num_calc());
+ break;
+
+#if 0
+ /*
+ * Alternatives: ^i, ^I, <CTRL/I>, <TAB>
+ */
+ case 'I':
+ BEGIN_EXEC(&states.insert);
+ expressions.eval();
+ expressions.push('\t');
+ return &states.insert;
+#endif
+
+ /*
+ * Alternatives: ^[, <CTRL/[> (cannot be typed), <ESC>
+ */
+ case '[':
+ BEGIN_EXEC(&states.start);
+ expressions.discard_args();
+ break;
+
+ /*
+ * Additional numeric operations
+ */
+ case '_':
+ BEGIN_EXEC(&states.start);
+ expressions.push(~expressions.pop_num_calc());
+ break;
+
+ case '*':
+ BEGIN_EXEC(&states.start);
+ expressions.push_calc(Expressions::OP_POW);
+ break;
+
+ case '/':
+ BEGIN_EXEC(&states.start);
+ expressions.push_calc(Expressions::OP_MOD);
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return &states.start;
+}
diff --git a/parser.h b/parser.h
index 3eba297..8ceb3e2 100644
--- a/parser.h
+++ b/parser.h
@@ -50,6 +50,14 @@ private:
State *custom(gchar chr);
};
+class StateControl : public State {
+public:
+ StateControl();
+
+private:
+ State *custom(gchar chr);
+};
+
#include "goto.h"
extern gint macro_pc;
@@ -57,6 +65,7 @@ extern gint macro_pc;
extern struct States {
StateStart start;
StateLabel label;
+ StateControl control;
} states;
extern enum Mode {
@@ -64,6 +73,11 @@ extern enum Mode {
MODE_PARSE_ONLY
} mode;
+#define BEGIN_EXEC(STATE) G_STMT_START { \
+ if (mode != MODE_NORMAL) \
+ return STATE; \
+} G_STMT_END
+
extern gchar *strings[2];
bool macro_execute(const gchar *macro);