/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 12:14:52 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20220601121452-ntu94w67q3dhhfeq
More work torwards inperementing the parser.

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
7
    
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
8
    //public static int VALUES_OUTPUT_PRECISION_FACTOR = (int)Math.pow(10, VALUES_OUTPUT_PRECISION_DIGITS);
18
9
    
19
10
    
26
17
    public const int MAX_TOKEN_ITERATIONS = 500;
27
18
    /** Max iteration number for the expression */
28
19
    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} */
 
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 */
59
128
    protected const int ROOT_GENERATION = int.MAX;
60
129
    
61
130
    /* ********************************************************************** */
62
131
    
63
132
    /**
64
 
     * tells weather the token is right associative or not.
 
133
     * tells whether the token is right associative or not.
65
134
     */
66
135
    public bool right_assosiative {get;set; default = false;}
67
136
    
68
 
    
69
 
    private int real_priority;
70
 
    
71
137
    /** The parent token of this token*/
72
138
    protected unowned Token? parent {protected get; protected set;}
73
139
    
74
 
    public virtual int priority {public get {
75
 
      return __get_priority ();
76
 
     } protected construct set {
77
 
       __set_priority (value);
78
 
     }}
 
140
    public virtual Prio priority {public get; protected construct set;}
79
141
    
80
142
    /** Starting position of the token in the expression */
81
 
    protected int position;
 
143
    public int position {get; protected set;}
82
144
    
 
145
    private int internal_next_child_num;
83
146
    /** The index of the next child */
84
 
    private int next_child;
 
147
    public int next_child_num {get {return internal_next_child_num;}
 
148
                 protected set{internal_next_child_num = value;}}
85
149
    
86
150
    /** 
87
151
     * The optional that this child represents.
108
172
    /** all children of this token */
109
173
    private (unowned Token?)[] children;
110
174
    
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;}
 
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;
115
182
    public string result_string {public get; protected set; default = "";}
116
183
    
117
184
    construct {
118
 
      // Valgrind says there is a memory leak here... But it's actually
119
 
      // GObject's constructor that is leaking.
120
185
      children = new Token[max_num_child];
121
 
      next_child = 0;
 
186
      next_child_num = 0;
 
187
      
 
188
      result_value = FastNumber ();
 
189
      result_max_value = FastNumber ();
 
190
      result_min_value = FastNumber ();
122
191
    }
123
192
    
124
193
    
126
195
      this.position = position;
127
196
    }
128
197
    
 
198
    
129
199
    /**
130
200
     * Reorders result_min_value and result_max_value, so that
131
 
     * result_max varue is the bigger of the two, and
 
201
     * result_max_value is the bigger of the two, and
132
202
     * result_min_value is the smaller.
133
203
     */
134
204
    protected void reorder_max_min_values () {
135
 
      if (result_max_value < result_min_value) {
136
 
        long tmp = result_max_value;
 
205
      if (result_max_value.compare (result_min_value) <= 0) {
 
206
        FastNumber tmp = result_max_value;
137
207
        result_max_value = result_min_value;
138
208
        result_min_value = tmp;
139
209
      }
151
221
      return children[index -1 ];
152
222
    }
153
223
    
 
224
    public void set_next_child (Token child) throws ArgError {
 
225
      next_child_num++;
 
226
      set_child (next_child_num, child);
 
227
    }
154
228
    
155
229
    /**
156
230
     * Set a child token to this this token.
216
290
     * @throws GLib.Error an error if an error has orrured in the evaluation of the tree.
217
291
     */
218
292
    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
293
  }
233
294
  
234
295
}