aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/expressions.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/expressions.h')
-rw-r--r--src/expressions.h101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/expressions.h b/src/expressions.h
index 5c2aa7e..a0e2908 100644
--- a/src/expressions.h
+++ b/src/expressions.h
@@ -28,14 +28,18 @@ namespace SciTECO {
template <typename Type>
class ValueStack {
class UndoTokenPush : public UndoTokenWithSize<UndoTokenPush> {
+ /*
+ * FIXME: saving the UndoStack for each undo taken
+ * wastes a lot of memory
+ */
ValueStack<Type> *stack;
Type value;
- int index;
+ guint index;
public:
UndoTokenPush(ValueStack<Type> *_stack,
- Type _value, int _index = 1)
+ Type _value, guint _index = 0)
: stack(_stack), value(_value), index(_index) {}
void
@@ -48,10 +52,10 @@ class ValueStack {
class UndoTokenPop : public UndoTokenWithSize<UndoTokenPop> {
ValueStack<Type> *stack;
- int index;
+ guint index;
public:
- UndoTokenPop(ValueStack<Type> *_stack, int _index = 1)
+ UndoTokenPop(ValueStack<Type> *_stack, guint _index = 0)
: stack(_stack), index(_index) {}
void
@@ -61,15 +65,20 @@ class ValueStack {
}
};
- int size;
-
+ /** Beginning of stack area */
Type *stack;
- Type *top;
+ /** End of stack area */
+ Type *stack_top;
+
+ /** Pointer to top element on stack */
+ Type *sp;
public:
- ValueStack(int _size = 1024) : size(_size)
+ ValueStack(gsize size = 1024)
{
- top = stack = new Type[size];
+ stack = new Type[size];
+ /* stack grows to smaller addresses */
+ sp = stack_top = stack+size;
}
~ValueStack()
@@ -77,57 +86,67 @@ public:
delete[] stack;
}
- inline int
+ inline guint
items(void)
{
- return top - stack;
+ return stack_top - sp;
}
inline Type &
- push(Type value, int index = 1)
+ push(Type value, guint index = 0)
{
- if (items() == size)
+ if (G_UNLIKELY(sp == stack))
throw Error("Stack overflow");
- for (int i = -index + 1; i; i++)
- top[i+1] = top[i];
+ /* reserve space for new element */
+ sp--;
+ g_assert(items() > index);
+
+ /* move away elements after index (index > 0) */
+ for (guint i = 0; i < index; i++)
+ sp[i] = sp[i+1];
- top++;
- return peek(index) = value;
+ return sp[index] = value;
}
inline void
- undo_push(Type value, int index = 1)
+ undo_push(Type value, guint index = 0)
{
undo.push(new UndoTokenPush(this, value, index));
}
inline Type
- pop(int index = 1)
+ pop(guint index = 0)
{
+ /* peek() already asserts */
Type v = peek(index);
- top--;
- while (--index)
- top[-index] = top[-index + 1];
+ /* elements after index are moved to index (index > 0) */
+ while (index--)
+ sp[index+1] = sp[index];
+
+ /* free space of element to pop */
+ sp++;
return v;
}
inline void
- undo_pop(int index = 1)
+ undo_pop(guint index = 0)
{
undo.push(new UndoTokenPop(this, index));
}
inline Type &
- peek(int index = 1)
+ peek(guint index = 0)
{
- return top[-index];
+ g_assert(items() > index);
+
+ return sp[index];
}
inline void
clear(void)
{
- top = stack;
+ sp = stack_top;
}
};
@@ -163,10 +182,18 @@ public:
Expressions() : num_sign(1), radix(10) {}
gint num_sign;
- void set_num_sign(gint sign);
+ inline void
+ set_num_sign(gint sign)
+ {
+ undo.push_var(num_sign) = sign;
+ }
gint radix;
- void set_radix(gint r);
+ inline void
+ set_radix(gint r)
+ {
+ undo.push_var(radix) = r;
+ }
tecoInt push(tecoInt number);
@@ -183,14 +210,14 @@ public:
}
inline tecoInt
- peek_num(int index = 1)
+ peek_num(guint index = 0)
{
return numbers.peek(index);
}
- tecoInt pop_num(int index = 1);
- tecoInt pop_num_calc(int index, tecoInt imply);
+ tecoInt pop_num(guint index = 0);
+ tecoInt pop_num_calc(guint index, tecoInt imply);
inline tecoInt
- pop_num_calc(int index = 1)
+ pop_num_calc(guint index = 0)
{
return pop_num_calc(index, num_sign);
}
@@ -200,19 +227,19 @@ public:
Operator push(Operator op);
Operator push_calc(Operator op);
inline Operator
- peek_op(int index = 1)
+ peek_op(guint index = 0)
{
return operators.peek(index);
}
- Operator pop_op(int index = 1);
+ Operator pop_op(guint index = 0);
void eval(bool pop_brace = false);
- int args(void);
+ guint args(void);
void discard_args(void);
- int find_op(Operator op);
+ gint find_op(Operator op);
inline void
clear(void)
@@ -226,7 +253,7 @@ public:
private:
void calc(void);
- int first_op(void);
+ gint first_op(void);
} expressions;
} /* namespace SciTECO */