/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: 2022-06-01 20:45:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20220601204527-o3iajykp1okm8ylt
Added section on development guidelines.

TODO: add more?

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
using VQDR.Common;
 
1
using Utils;
2
2
using GLib;
3
3
 
4
4
namespace VQDR.Expression {
5
5
  
6
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
7
    
20
8
    /** Max size of a single token */
21
 
    public const int MAX_TOKEN_STRING_LENGTH = 64;
 
9
    public const int32 MAX_TOKEN_STRING_LENGTH = 64;
22
10
    /** Max size of an expression */
23
 
    public const int MAX_TOTAL_STRING_LENGTH = 200;
 
11
    public const int32 MAX_TOTAL_STRING_LENGTH = 200;
24
12
 
25
13
    /** Max iteration number for a token (function) */
26
 
    public const int MAX_TOKEN_ITERATIONS = 500;
 
14
    public const int32 MAX_TOKEN_ITERATIONS = 500;
27
15
    /** 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;
 
16
    public const int32 MAX_TOTAL_ITERATIONS = 5000;
 
17
    
 
18
    
 
19
    /**
 
20
     * Operator precedence and associativity
 
21
     * 
 
22
     * higher number is higher priority, and is to be done befroe those
 
23
     * with lower number.
 
24
     */
 
25
    public enum Prio {
 
26
      /** invalid case. Prevents null-trap. */
 
27
      INVALID = 0,
 
28
      /** Priority for assignment "=" operator */
 
29
      ASSIGNMENT = 1,
 
30
      /** Priority for conditional OR "||" operator */
 
31
      CONDITIONAL_OR,
 
32
      /** Priority for conditional AND "&&" operator */
 
33
      CONDITIONAL_AND,
 
34
      /** Priority for equality "==" and "!=" operators */
 
35
      EQUALITY,
 
36
      /** Priority for comparison ">", "<", ">=", etc operators */
 
37
      COMPARISON,
 
38
      /** Priority for addictive "+" and "-" operators */
 
39
      ADDICTIVE,
 
40
      /** Priority for multiplicative "*" and "/" operators */
 
41
      MULTIPLICATIVE,
 
42
      /** Priority for unary "+" and "-" and "!" operators */
 
43
      UNARY,
 
44
      /** Priority for label assignment ":" operator */
 
45
      LABEL,
 
46
      /** Priority for dice "d" operator */
 
47
      DICE,
 
48
      /** Priority for functions */
 
49
      FUNCTION,
 
50
      /** Priority for values */
 
51
      VALUE,
 
52
      /** The number of values. */
 
53
      _NUM_VAL;
 
54
      
 
55
      /** get the name of the priority */
 
56
      public string to_string () {
 
57
        // We have to add 1 as we have an invalid case at zero.
 
58
        static_assert (_NUM_VAL == 12 + 1);
 
59
        switch (this) {
 
60
          case ASSIGNMENT:
 
61
            return "ASSIGNMENT";
 
62
          case CONDITIONAL_OR:
 
63
            return "CONDITIONAL_OR";
 
64
          case CONDITIONAL_AND:
 
65
            return "CONDITIONAL_AND";
 
66
          case EQUALITY:
 
67
            return "EQUALITY";
 
68
          case COMPARISON:
 
69
            return "COMPARISON";
 
70
          case ADDICTIVE:
 
71
            return "ADDICTIVE";
 
72
          case MULTIPLICATIVE:
 
73
            return "MULTIPLICATIVE";
 
74
          case UNARY:
 
75
            return "UNARY";
 
76
          case LABEL:
 
77
            return "LABEL";
 
78
          case DICE:
 
79
            return "DICE";
 
80
          case FUNCTION:
 
81
            return "FUNCTION";
 
82
          case VALUE:
 
83
            return "VALUE";
 
84
          default:
 
85
            assert_not_reached ();
 
86
        }
 
87
      }
 
88
 
 
89
      public Prio from_string (string name) {
 
90
        // We have to add 1 as we have an invalid case at zero.
 
91
        static_assert (_NUM_VAL == 12 + 1);
 
92
        var collected = name.up ();
 
93
        switch (collected) {
 
94
          case "ASSIGMENT":
 
95
            return ASSIGNMENT;
 
96
          case "CONDITIONAL_OR":
 
97
            return CONDITIONAL_OR;
 
98
          case "CONDITIONAL_AND":
 
99
            return CONDITIONAL_AND;
 
100
          case "EQUALITY":
 
101
            return EQUALITY;
 
102
          case "COMPARISON":
 
103
            return COMPARISON;
 
104
          case "ADDICTIVE":
 
105
            return ADDICTIVE;
 
106
          case "MULTIPLICATIVE":
 
107
            return MULTIPLICATIVE;
 
108
          case "UNARY":
 
109
            return UNARY;
 
110
          case "LABEL":
 
111
            return LABEL;
 
112
          case "DICE":
 
113
            return DICE;
 
114
          case "FUNCTON":
 
115
            return FUNCTION;
 
116
          case "VALUE":
 
117
            return VALUE;
 
118
          default:
 
119
            assert_not_reached ();
 
120
        }
 
121
      }
 
122
    }
 
123
 
 
124
    /** Generation to use to get the root with @link parent */
 
125
    protected const int32 ROOT_GENERATION = int.MAX;
60
126
    
61
127
    /* ********************************************************************** */
62
128
    
63
129
    /**
64
 
     * tells weather the token is right associative or not.
 
130
     * tells whether the token is right associative or not.
65
131
     */
66
132
    public bool right_assosiative {get;set; default = false;}
67
133
    
68
 
    
69
 
    private int real_priority;
70
 
    
71
134
    /** The parent token of this token*/
72
135
    protected unowned Token? parent {protected get; protected set;}
73
136
    
74
 
    public virtual int priority {public get {
75
 
      return __get_priority ();
76
 
     } protected construct set {
77
 
       __set_priority (value);
78
 
     }}
 
137
    public virtual Prio priority {public get; protected construct set;}
79
138
    
80
139
    /** Starting position of the token in the expression */
81
 
    protected int position;
 
140
    public int32 position {public get; protected set;}
82
141
    
 
142
    private int internal_next_child_num;
83
143
    /** The index of the next child */
84
 
    private int next_child;
 
144
    public int next_child_num {get {return internal_next_child_num;}
 
145
                 protected set{internal_next_child_num = value;}}
85
146
    
86
147
    /** 
87
148
     * The optional that this child represents.
88
149
     * 
89
150
     * 
90
151
     */
91
 
    public int optional_num_child {public get; protected construct set;}
 
152
    public int32 optional_num_child {public get; protected construct set;}
92
153
    
93
154
    /** The mandatory number of child this token can have */
94
 
    public int mandatory_num_child {public get; protected construct set;}
 
155
    public int32 mandatory_num_child {public get; protected construct set;}
95
156
    
96
157
    /** 
97
158
     * The maximum number of chidren 
101
162
     * 
102
163
     * Can not be set.
103
164
     */
104
 
    public int max_num_child {get {
 
165
    public int32 max_num_child {get {
105
166
      return optional_num_child + mandatory_num_child;
106
167
     }}
107
168
     
108
169
    /** all children of this token */
109
170
    private (unowned Token?)[] children;
110
171
    
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;}
 
172
    /*
 
173
     * These values should have a protected setter, but I could not get it to
 
174
     * work. So we will have to live with this.
 
175
     */
 
176
    public FastNumber result_value;
 
177
    public FastNumber result_max_value;
 
178
    public FastNumber result_min_value;
115
179
    public string result_string {public get; protected set; default = "";}
116
180
    
117
181
    construct {
118
 
      // Valgrind says there is a memory leak here... But it's actually
119
 
      // GObject's constructor that is leaking.
120
182
      children = new Token[max_num_child];
121
 
      next_child = 0;
 
183
      next_child_num = 0;
 
184
      
 
185
      result_value = FastNumber ();
 
186
      result_max_value = FastNumber ();
 
187
      result_min_value = FastNumber ();
122
188
    }
123
189
    
124
190
    
125
 
    protected Token (int position) {
 
191
    protected Token (int32 position) {
126
192
      this.position = position;
127
193
    }
128
194
    
 
195
    
129
196
    /**
130
197
     * Reorders result_min_value and result_max_value, so that
131
 
     * result_max varue is the bigger of the two, and
 
198
     * result_max_value is the bigger of the two, and
132
199
     * result_min_value is the smaller.
133
200
     */
134
201
    protected void reorder_max_min_values () {
135
 
      if (result_max_value < result_min_value) {
136
 
        long tmp = result_max_value;
 
202
      if (result_max_value.compare (result_min_value) <= 0) {
 
203
        FastNumber tmp = result_max_value;
137
204
        result_max_value = result_min_value;
138
205
        result_min_value = tmp;
139
206
      }
146
213
     * 
147
214
     * and index of 0 is illegal.
148
215
     */
149
 
    public unowned Token? get_child (int index) requires (index > 0 && index <= max_num_child) {
 
216
    public unowned Token? get_child (int32 index)
 
217
                          requires (index > 0 && index <= max_num_child) {
150
218
      
151
219
      return children[index -1 ];
152
220
    }
153
221
    
 
222
    public void set_next_child (Token child) throws ArgError {
 
223
      next_child_num++;
 
224
      set_child (next_child_num, child);
 
225
    }
154
226
    
155
227
    /**
156
228
     * Set a child token to this this token.
159
231
     * 
160
232
     * and index of 0 is illegal.
161
233
     */
162
 
    public void set_child (int index, Token? child) requires (index > 0 && index <= max_num_child) {
 
234
    public void set_child (int32 index, Token? child)
 
235
                requires (index > 0 && index <= max_num_child) {
163
236
      
164
237
      children[index - 1] = child;
165
238
      
216
289
     * @throws GLib.Error an error if an error has orrured in the evaluation of the tree.
217
290
     */
218
291
    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
292
  }
233
293
  
234
294
}