aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser.cpp33
-rw-r--r--src/parser.h44
2 files changed, 69 insertions, 8 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 67d8b73..4dbec88 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -72,6 +72,10 @@ static gint nest_level = 0;
gchar *strings[2] = {NULL, NULL};
gchar escape_char = '\x1B';
+/*
+ * handles all expected exceptions, converting them to
+ * State::Error and preparing them for stack frame insertion
+ */
void
Execute::step(const gchar *macro, gint stop_pos)
throw (State::Error, ReplaceCmdline)
@@ -104,9 +108,12 @@ Execute::step(const gchar *macro, gint stop_pos)
}
}
+/*
+ * may throw non State::Error exceptions which are not to be
+ * associated with the macro invocation stack frame
+ */
void
Execute::macro(const gchar *macro, bool locals)
- throw (State::Error, ReplaceCmdline)
{
GotoTable *parent_goto_table = Goto::table;
GotoTable macro_goto_table(false);
@@ -125,6 +132,7 @@ Execute::macro(const gchar *macro, bool locals)
macro_pc = 0;
Goto::table = &macro_goto_table;
+ /* locals are allocated so that we do not waste call stack space */
if (locals) {
parent_locals = QRegisters::locals;
QRegisters::locals = new QRegisterTable(false);
@@ -132,9 +140,14 @@ Execute::macro(const gchar *macro, bool locals)
try {
step(macro, strlen(macro));
- if (Goto::skip_label)
- throw State::Error("Label \"%s\" not found",
+ if (Goto::skip_label) {
+ State::Error error("Label \"%s\" not found",
Goto::skip_label);
+ error.pos = strlen(macro);
+ String::get_coord(macro, error.pos,
+ error.line, error.column);
+ throw error;
+ }
} catch (...) {
g_free(Goto::skip_label);
Goto::skip_label = NULL;
@@ -163,7 +176,6 @@ Execute::macro(const gchar *macro, bool locals)
void
Execute::file(const gchar *filename, bool locals)
- throw (State::Error, ReplaceCmdline)
{
gchar *macro_str, *p;
@@ -212,6 +224,19 @@ State::Error::Error(const gchar *fmt, ...)
va_end(ap);
}
+State::Error::Error(const Error &inst)
+ : description(g_strdup(inst.description)),
+ pos(inst.pos), line(inst.line), column(inst.column)
+{
+ /* shallow copy of the frames */
+ frames = g_slist_copy(inst.frames);
+
+ for (GSList *cur = frames; cur; cur = g_slist_next(cur)) {
+ Frame *frame = (Frame *)cur->data;
+ cur->data = frame->copy();
+ }
+}
+
void
State::Error::add_frame(Frame *frame)
{
diff --git a/src/parser.h b/src/parser.h
index 76cd7c7..f7c9bed 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -51,6 +51,7 @@ public:
gint pos;
gint line, column;
+ virtual Frame *copy() const = 0;
virtual ~Frame() {}
virtual void display(gint nr) = 0;
@@ -63,6 +64,18 @@ public:
QRegFrame(const gchar *_name)
: name(g_strdup(_name)) {}
+ Frame *
+ copy() const
+ {
+ Frame *frame = new QRegFrame(name);
+
+ frame->pos = pos;
+ frame->line = line;
+ frame->column = column;
+
+ return frame;
+ }
+
~QRegFrame()
{
g_free(name);
@@ -84,6 +97,18 @@ public:
FileFrame(const gchar *_name)
: name(g_strdup(_name)) {}
+ Frame *
+ copy() const
+ {
+ Frame *frame = new FileFrame(name);
+
+ frame->pos = pos;
+ frame->line = line;
+ frame->column = column;
+
+ return frame;
+ }
+
~FileFrame()
{
g_free(name);
@@ -100,6 +125,18 @@ public:
class ToplevelFrame : public Frame {
public:
+ Frame *
+ copy() const
+ {
+ Frame *frame = new ToplevelFrame;
+
+ frame->pos = pos;
+ frame->line = line;
+ frame->column = column;
+
+ return frame;
+ }
+
void
display(gint nr)
{
@@ -110,6 +147,7 @@ public:
};
Error(const gchar *fmt, ...) G_GNUC_PRINTF(2, 3);
+ Error(const Error &inst);
~Error();
void add_frame(Frame *frame);
@@ -407,10 +445,8 @@ extern gchar escape_char;
namespace Execute {
void step(const gchar *macro, gint stop_pos)
throw (State::Error, ReplaceCmdline);
- void macro(const gchar *macro, bool locals = true)
- throw (State::Error, ReplaceCmdline);
- void file(const gchar *filename, bool locals = true)
- throw (State::Error, ReplaceCmdline);
+ void macro(const gchar *macro, bool locals = true);
+ void file(const gchar *filename, bool locals = true);
}
#endif