/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 Vee;
 
1
using VQDR.Common;
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
    
7
19
    
8
20
    /** Max size of a single token */
9
 
    public const int32 MAX_TOKEN_STRING_LENGTH = 64;
 
21
    public const int MAX_TOKEN_STRING_LENGTH = 64;
10
22
    /** Max size of an expression */
11
 
    public const int32 MAX_TOTAL_STRING_LENGTH = 200;
 
23
    public const int MAX_TOTAL_STRING_LENGTH = 200;
12
24
 
13
25
    /** Max iteration number for a token (function) */
14
 
    public const int32 MAX_TOKEN_ITERATIONS = 500;
 
26
    public const int MAX_TOKEN_ITERATIONS = 500;
15
27
    /** Max iteration number for the expression */
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;
 
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;
126
60
    
127
61
    /* ********************************************************************** */
128
62
    
129
63
    /**
130
 
     * tells whether the token is right associative or not.
 
64
     * tells weather the token is right associative or not.
131
65
     */
132
66
    public bool right_assosiative {get;set; default = false;}
133
67
    
 
68
    
 
69
    private int real_priority;
 
70
    
134
71
    /** The parent token of this token*/
135
72
    protected unowned Token? parent {protected get; protected set;}
136
73
    
137
 
    public virtual Prio priority {public get; protected construct set;}
 
74
    public virtual int priority {public get {
 
75
      return __get_priority ();
 
76
     } protected construct set {
 
77
       __set_priority (value);
 
78
     }}
138
79
    
139
80
    /** Starting position of the token in the expression */
140
 
    public int32 position {public get; protected set;}
 
81
    protected int position;
141
82
    
142
 
    private int internal_next_child_num;
143
83
    /** The index of the next child */
144
 
    public int next_child_num {get {return internal_next_child_num;}
145
 
                 protected set{internal_next_child_num = value;}}
 
84
    private int next_child;
146
85
    
147
86
    /** 
148
87
     * The optional that this child represents.
149
88
     * 
150
89
     * 
151
90
     */
152
 
    public int32 optional_num_child {public get; protected construct set;}
 
91
    public int optional_num_child {public get; protected construct set;}
153
92
    
154
93
    /** The mandatory number of child this token can have */
155
 
    public int32 mandatory_num_child {public get; protected construct set;}
 
94
    public int mandatory_num_child {public get; protected construct set;}
156
95
    
157
96
    /** 
158
97
     * The maximum number of chidren 
162
101
     * 
163
102
     * Can not be set.
164
103
     */
165
 
    public int32 max_num_child {get {
 
104
    public int max_num_child {get {
166
105
      return optional_num_child + mandatory_num_child;
167
106
     }}
168
107
     
169
108
    /** all children of this token */
170
109
    private (unowned Token?)[] children;
171
110
    
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;
 
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;}
179
115
    public string result_string {public get; protected set; default = "";}
180
116
    
181
117
    construct {
 
118
      // Valgrind says there is a memory leak here... But it's actually
 
119
      // GObject's constructor that is leaking.
182
120
      children = new Token[max_num_child];
183
 
      next_child_num = 0;
184
 
      
185
 
      result_value = FastNumber ();
186
 
      result_max_value = FastNumber ();
187
 
      result_min_value = FastNumber ();
 
121
      next_child = 0;
188
122
    }
189
123
    
190
124
    
191
 
    protected Token (int32 position) {
 
125
    protected Token (int position) {
192
126
      this.position = position;
193
127
    }
194
128
    
195
 
    
196
129
    /**
197
130
     * Reorders result_min_value and result_max_value, so that
198
 
     * result_max_value is the bigger of the two, and
 
131
     * result_max varue is the bigger of the two, and
199
132
     * result_min_value is the smaller.
200
133
     */
201
134
    protected void reorder_max_min_values () {
202
 
      if (result_max_value.compare (result_min_value) <= 0) {
203
 
        FastNumber tmp = result_max_value;
 
135
      if (result_max_value < result_min_value) {
 
136
        long tmp = result_max_value;
204
137
        result_max_value = result_min_value;
205
138
        result_min_value = tmp;
206
139
      }
213
146
     * 
214
147
     * and index of 0 is illegal.
215
148
     */
216
 
    public unowned Token? get_child (int32 index)
217
 
                          requires (index > 0 && index <= max_num_child) {
 
149
    public unowned Token? get_child (int index) requires (index > 0 && index <= max_num_child) {
218
150
      
219
151
      return children[index -1 ];
220
152
    }
221
153
    
222
 
    public void set_next_child (Token child) throws ArgError {
223
 
      next_child_num++;
224
 
      set_child (next_child_num, child);
225
 
    }
226
154
    
227
155
    /**
228
156
     * Set a child token to this this token.
231
159
     * 
232
160
     * and index of 0 is illegal.
233
161
     */
234
 
    public void set_child (int32 index, Token? child)
235
 
                requires (index > 0 && index <= max_num_child) {
 
162
    public void set_child (int index, Token? child) requires (index > 0 && index <= max_num_child) {
236
163
      
237
164
      children[index - 1] = child;
238
165
      
289
216
     * @throws GLib.Error an error if an error has orrured in the evaluation of the tree.
290
217
     */
291
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
    
292
232
  }
293
233
  
294
234
}