/vqdr/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/vqdr/trunk
1 by Gustav Hartvigsson
* Initial code - far from done
1
using VQDR.Common;
2
using GLib;
3
4
namespace VQDR.Expression {
5
  
6
  public abstract class Token : GLib.Object {
7
    /** Precision used to perform evaluation */
8
    public const int VALUES_PRECISION_DIGITS = 3;
9
    /** Precision factor used to convert raw values to actual ones */
10
    public const int VALUES_PRECISION_FACTOR = 1000;
11
    //public static int VALUES_PRECISION_FACTOR = (int)Math.pow(10, VALUES_PRECISION_DIGITS);
12
    
13
    /** Precision used to output values */
14
    public const int VALUES_OUTPUT_PRECISION_DIGITS = 2;
15
    /** Precision factor used to evaluate output */
16
    public const int VALUES_OUTPUT_PRECISION_FACTOR = 100;
17
    //public static int VALUES_OUTPUT_PRECISION_FACTOR = (int)Math.pow(10, VALUES_OUTPUT_PRECISION_DIGITS);
18
    
19
    
20
    /** Max size of a single token */
21
    public const int MAX_TOKEN_STRING_LENGTH = 64;
22
    /** Max size of an expression */
23
    public const int MAX_TOTAL_STRING_LENGTH = 200;
24
25
    /** Max iteration number for a token (function) */
26
    public const int MAX_TOKEN_ITERATIONS = 500;
27
    /** Max iteration number for the expression */
28
    public const int MAX_TOTAL_ITERATIONS = 5000;
29
30
    /* ************************************* */
31
    /* Operator precedence and associativity */
32
    /* ************************************* */
33
    /** Priority for assignment "=" operator */
34
    public const int PRIO_ASSIGNMENT = 0;
35
    /** Priority for conditional OR "||" operator */
36
    public const int PRIO_CONDITIONAL_OR = 2;
37
    /** Priority for conditional AND "&&" operator */
38
    public const int PRIO_CONDITIONAL_AND = 3;
39
    /** Priority for equality "==" and "!=" operators */
40
    public const int PRIO_EQUALITY = 4;
41
    /** Priority for comparison ">", "<", ">=", etc operators */
42
    public const int PRIO_COMPARISON = 5;
43
    /** Priority for addictive "+" and "-" operators */
44
    public const int PRIO_ADDICTIVE = 6;
45
    /** Priority for multiplicative "*" and "/" operators */
46
    public const int PRIO_MULTIPLICATIVE = 7;
47
    /** Priority for unary "+" and "-" and "!" operators */
48
    public const int PRIO_UNARY = 8;
49
    /** Priority for label assignment ":" operator */
50
    public const int PRIO_LABEL = 9;
51
    /** Priority for dice "d" operator */
52
    public const int PRIO_DICE = 10;
53
    /** Priority for functions */
54
    public const int PRIO_FUNCTION = 11;
55
    /** Priority for values */
56
    public const int PRIO_VALUE = 12;
57
58
    /** Generation to use to get the root with {@link #getParent} */
59
    protected const int ROOT_GENERATION = int.MAX;
60
    
61
    /* ********************************************************************** */
62
    
63
    /**
64
     * tells weather the token is right associative or not.
65
     */
66
    public bool right_assosiative {get;set; default = false;}
67
    
68
    
69
    private int real_priority;
70
    
71
    /** The parent token of this token*/
72
    protected unowned Token? parent {protected get; protected set;}
73
    
74
    public virtual int priority {public get {
75
      return __get_priority ();
76
     } protected construct set {
77
       __set_priority (value);
78
     }}
79
    
80
    /** Starting position of the token in the expression */
81
    protected int position;
82
    
83
    /** The index of the next child */
84
    private int next_child;
85
    
86
    /** 
87
     * The optional that this child represents.
88
     * 
89
     * 
90
     */
91
    public int optional_num_child {public get; protected construct set;}
92
    
93
    /** The mandatory number of child this token can have */
94
    public int mandatory_num_child {public get; protected construct set;}
95
    
96
    /** 
97
     * The maximum number of chidren 
98
     * 
99
     * This is calculated at runtime as
100
     * ''optional_num_child + mandatory_num_child''.
101
     * 
102
     * Can not be set.
103
     */
104
    public int max_num_child {get {
105
      return optional_num_child + mandatory_num_child;
106
     }}
107
     
108
    /** all children of this token */
109
    private (unowned Token?)[] children;
110
    
111
    
112
    public long result_value {public get; protected set; default = 0;}
113
    public long result_max_value {public get; protected set; default = 0;}
114
    public long result_min_value {public get; protected set; default = 0;}
115
    public string result_string {public get; protected set; default = "";}
116
    
117
    construct {
118
      // Valgrind says there is a memory leak here... But it's actually
119
      // GObject's constructor that is leaking.
120
      children = new Token[max_num_child];
121
      next_child = 0;
122
    }
123
    
124
    
125
    protected Token (int position) {
126
      this.position = position;
127
    }
128
    
129
    /**
130
     * Reorders result_min_value and result_max_value, so that
131
     * result_max varue is the bigger of the two, and
132
     * result_min_value is the smaller.
133
     */
134
    protected void reorder_max_min_values () {
135
      if (result_max_value < result_min_value) {
136
        long tmp = result_max_value;
137
        result_max_value = result_min_value;
138
        result_min_value = tmp;
139
      }
140
    }
141
    
142
    /**
143
     * Get a child token to this token.
144
     * 
145
     * Child positions are between 1 and max_num_child.
146
     * 
147
     * and index of 0 is illegal.
148
     */
149
    public unowned Token? get_child (int index) requires (index > 0 && index <= max_num_child) {
150
      
151
      return children[index -1 ];
152
    }
153
    
154
    
155
    /**
156
     * Set a child token to this this token.
157
     * 
158
     * Child positions are between 1 and max_num_child.
159
     * 
160
     * and index of 0 is illegal.
161
     */
162
    public void set_child (int index, Token? child) requires (index > 0 && index <= max_num_child) {
163
      
164
      children[index - 1] = child;
165
      
166
      if (children[index - 1] != null) {
167
        children[index -1].parent = this;
168
        
169
      }
170
    }
171
    
172
    /**
173
     * is functionally equal to get_child (1);
174
     */
175
    public Token get_left_child () {
176
      return get_child (1);
177
    }
178
    
179
    /**
180
     * is functionally equal to get_child (2);
181
     */
182
    public Token get_right_child () {
183
      return get_child (2);
184
    }
185
    
186
    /**
187
     * is functionally equal to set_child (1, token);
188
     */
189
    public void set_left_child (Token token)  {
190
      set_child (1, token);
191
    }
192
    
193
    /**
194
     * is functionally equal to set_child (2, token);
195
     */
196
    public void set_right_child (Token token)  {
197
      set_child (2, token);
198
    }
199
    
200
    public void evaluate (Context instance) throws GLib.Error {
201
      evaluate_self (instance);
202
    }
203
    
204
    /**
205
     * Evalutates current token tree.
206
     * 
207
     * This Method must evaluate the token subtree, and assign proper values to
208
     * the following properties:
209
     * 
210
     *  * result_value
211
     *  * result_max_value
212
     *  * result_min_value
213
     *  * result_string
214
     * 
215
     * @param instance The context to be used valfor this tree.
216
     * @throws GLib.Error an error if an error has orrured in the evaluation of the tree.
217
     */
218
    protected abstract void evaluate_self (Context instance) throws GLib.Error;
219
    
220
    /* *********** IGNORE THE MESS I HAVE CREATED FRO MY SELF *************** */
221
    /** IGNORE ME */
222
    protected void __set_priority (int prio) {
223
      real_priority = prio;
224
    }
225
    
226
    /** IGNORE ME*/
227
    protected int __get_priority () {
228
      return real_priority;
229
    }
230
    
231
    
232
  }
233
  
234
}