/vqdr/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/vqdr/trunk

« back to all changes in this revision

Viewing changes to src/libvqdr/token.vala

  • Committer: Gustav Hartvigsson
  • Date: 2020-06-07 18:48:24 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20200607184824-jf14f7a1b1di2i2q
* Initial code - far from done

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}