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