diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-04 17:29:01 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-04 22:07:08 +0100 |
commit | d8a316514c03d85b771a9dce4a8a51b875d955b3 (patch) | |
tree | 8966c29db767a155848f6d90f76771ce5b9de32e /src/expressions.h | |
parent | b120616b6da52e951097f69ad267de06081d218a (diff) | |
download | sciteco-d8a316514c03d85b771a9dce4a8a51b875d955b3.tar.gz |
autoconf preparation: move everything into src/ subdir
Diffstat (limited to 'src/expressions.h')
-rw-r--r-- | src/expressions.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/expressions.h b/src/expressions.h new file mode 100644 index 0000000..a441e90 --- /dev/null +++ b/src/expressions.h @@ -0,0 +1,194 @@ +#ifndef __EXPRESSIONS_H +#define __EXPRESSIONS_H + +#include <glib.h> + +#include "undo.h" + +template <typename Type> +class ValueStack { + class UndoTokenPush : public UndoToken { + ValueStack<Type> *stack; + + Type value; + int index; + + public: + UndoTokenPush(ValueStack<Type> *_stack, + Type _value, int _index = 1) + : stack(_stack), value(_value), index(_index) {} + + void + run(void) + { + stack->push(value, index); + } + }; + + class UndoTokenPop : public UndoToken { + ValueStack<Type> *stack; + + int index; + + public: + UndoTokenPop(ValueStack<Type> *_stack, int _index = 1) + : stack(_stack), index(_index) {} + + void + run(void) + { + stack->pop(index); + } + }; + + int size; + + Type *stack; + Type *top; + +public: + ValueStack(int _size = 1024) : size(_size) + { + top = stack = new Type[size]; + } + + ~ValueStack() + { + delete stack; + } + + inline int + items(void) + { + return top - stack; + } + + inline Type & + push(Type value, int index = 1) + { + for (int i = -index + 1; i; i++) + top[i+1] = top[i]; + + top++; + return peek(index) = value; + } + inline void + undo_push(Type value, int index = 1) + { + undo.push(new UndoTokenPush(this, value, index)); + } + + inline Type + pop(int index = 1) + { + Type v = peek(index); + + top--; + while (--index) + top[-index] = top[-index + 1]; + + return v; + } + inline void + undo_pop(int index = 1) + { + undo.push(new UndoTokenPop(this, index)); + } + + inline Type & + peek(int index = 1) + { + return top[-index]; + } + + inline void + clear(void) + { + top = stack; + } +}; + +/* + * Arithmetic expression stacks + */ +extern class Expressions { +public: + /* reflects also operator precedence */ + enum Operator { + OP_NIL = 0, + OP_POW, // ^* + OP_MUL, // * + OP_DIV, // / + OP_MOD, // ^/ + OP_SUB, // - + OP_ADD, // + + OP_AND, // & + OP_OR, // # + // pseudo operators: + OP_NEW, + OP_BRACE, + OP_LOOP, + OP_NUMBER + }; + +private: + ValueStack<gint64> numbers; + ValueStack<Operator> operators; + +public: + Expressions() : num_sign(1), radix(10) {} + + gint num_sign; + void set_num_sign(gint sign); + + gint radix; + void set_radix(gint r); + + gint64 push(gint64 number); + + inline gint64 + peek_num(int index = 1) + { + return numbers.peek(index); + } + gint64 pop_num(int index = 1); + gint64 pop_num_calc(int index, gint64 imply); + inline gint64 + pop_num_calc(int index = 1) + { + return pop_num_calc(index, num_sign); + } + + gint64 add_digit(gchar digit); + + Operator push(Operator op); + Operator push_calc(Operator op); + inline Operator + peek_op(int index = 1) + { + return operators.peek(index); + } + Operator pop_op(int index = 1); + + void eval(bool pop_brace = false); + + int args(void); + + void discard_args(void); + + int find_op(Operator op); + + inline void + clear(void) + { + numbers.clear(); + operators.clear(); + } + +private: + void calc(void); + + int first_op(void); +} expressions; + +#endif |