1 /************************************************************
3 ** COPYRIGHT (C) 1993 UNIVERSITY OF PITTSBURGH
4 ** COPYRIGHT (C) 1996 GANNON UNIVERSITY
7 ** This software is distributed on an as-is basis
8 ** with no warranty implied or intended. No author
9 ** or distributor takes responsibility to anyone
10 ** regarding its use of or suitability.
12 ** The software may be distributed and modified
13 ** freely for academic and other non-commercial
14 ** use but may NOT be utilized or included in whole
15 ** or part within any commercial product.
17 ** This copyright notice must remain on all copies
18 ** and modified versions of this software.
20 ************************************************************/
24 * As part of MS Thesis Work, S T Frezza, UPitt Engineering
27 * This file contains the structure and union manipulation functions that
28 * operate on VAR types and the underlying structures. These are based on the
29 * following definitions:
31 * typedef union var_item_union varItem;
32 * typedef struct var_item_struct varStruct;
33 * typedef struct var_struct var;
34 * typedef struct var_list_struct varlist;
43 * struct var_item_struct
49 * union var_union_type
56 * struct var_struct_list
64 * These structures essentially create an evaluation tree for operations on ranges; It
65 * also implements a delayed evaluation mechanism. This means
66 * that there is an entire algebra being implemented (at least partially) within the following
67 * code. What is here is not that smart, and only has for operations { +, -, /, * }.
69 * For example, the sum of two ranges (caused by the evaluation of a _var_ structure with
70 * the operation ADD, and having two _varStruct_s which are both ranges yeilds a single
71 * range, which is the first range having both it's min and max fields augmented by the
72 * (integer) result of evaluating the second range. Note that the second range is altered
73 * (reduced) during this operation.
79 /* ---- Local Variables ---------------------------------------------------------------*/
81 /*-------------------------------------------------------------------------------------*/
83 /*-------------------------------------------------------------------------------------*/
84 varStruct
*create_int_varStruct(i
)
88 vs
= (varStruct
*)calloc(1, sizeof(varStruct
));
90 vs
->this = (varItem
*)i
;
93 /*-------------------------------------------------------------------------------------*/
94 varStruct
*create_rng_varStruct(sr
)
98 vs
= (varStruct
*)calloc(1, sizeof(varStruct
));
100 vs
->this = (varItem
*)sr
;
103 /*-------------------------------------------------------------------------------------*/
104 varStruct
*create_var_varStruct(v
)
108 vs
= (varStruct
*)calloc(1, sizeof(varStruct
));
110 vs
->this = (varItem
*)v
;
114 /*-------------------------------------------------------------------------------------*/
115 var
*create_var_struct(a
, i1
, i2
)
119 /* Creates a var structure, with the given action and the two item pointers set. */
121 v
= (var
*)calloc(1, sizeof(var
));
127 /*-------------------------------------------------------------------------------------*/
128 /*-------------------------------------------------------------------------------------*/
129 srange
*create_srange(q1
, q2
, or)
132 srange
*r
= (srange
*)calloc(1, sizeof(srange
));
140 /*-------------------------------------------------------------------------------------*/
141 varStruct
*reduce_var_struct(vs
)
144 /* NOTE: - this does not change <vs>, but if it is made up of vars, then it will
145 evaluate all of the lower var structures. */
153 case RNG
: return(vs
);
156 case VAR
: v
= (var
*)vs
->this;
157 temp
= eval_var_struct(v
->item2
);
158 return(eval_action(v
->action
,
159 v
->item1
, v
->item2
));
161 default: fprintf(stderr
, "screwy varStruct passed to REDUCE_VAR_STRUCT\n");
164 /*-------------------------------------------------------------------------------------*/
168 /* This returns an integer equivalent to the center of the given range: */
173 r
->q1
= r
->q2
= sum
/2;
178 /*-------------------------------------------------------------------------------------*/
179 int eval_var_struct(vs
)
182 /* NOTE: - this changes <vs> */
187 case INT
: temp
= (vs
->this == NULL
) ? 0 : *(int *)vs
->this;
189 case RNG
: temp
= eval_srange((srange
*)vs
->this);
191 case VAR
: temp
= eval_var((var
*)vs
->this);
193 default: fprintf(stderr
, "screwy varStruct passed to EVAL_VAR_struct\n");
195 vs
->this = (varItem
*)&temp
;
199 /*-------------------------------------------------------------------------------------*/
200 varStruct
*add_var_structs(i1
,i2
)
203 /* adds <i1> to <i2>. <i2> MUST (or will be coerced)resolve to an integer.
204 * This modifies the internal values within <i1> and <i2>. <i1>'s union remains
205 * of the same type as it starts; i2 is reduced to an integer, if it is not one
208 int addend
= eval_var_struct(i2
), t
, *temp
;
214 case INT
: t
= *(int *)i1
->this + addend
;
216 i1
->this = (varItem
*)&temp
;
218 case RNG
: sr
= (srange
*)i1
->this;
219 sr
->q1
= sr
->q1
+ addend
;
220 sr
->q2
= sr
->q2
+ addend
;
222 case VAR
: v
= (var
*)i1
->this;
223 /* Recursively distribute the denom throughout the entire
224 nested var structure */
225 v
->item1
= add_var_structs(v
->item1
, i2
);
226 v
->item2
= add_var_structs(v
->item2
, i2
);
228 default: fprintf(stderr
, "screwy varStruct passed to ADD_VAR_structS\n");
233 /*-------------------------------------------------------------------------------------*/
234 varStruct
*subtract_var_structs(i1
,i2
)
237 /* subtracts <i2> from <i1>. <i2> MUST resolve (or will be coerced) to an integer.
238 * This modifies the internal values within <i1> and <i2>. <i1>'s union remains
239 * of the same type as it starts; i2 is reduced to an integer, if it is not one
242 int subtrahend
= eval_var_struct(i2
), t
, *temp
;
248 case INT
: t
= *(int *)i1
->this - subtrahend
;
249 i1
->this = (varItem
*)&t
;
251 case RNG
: sr
= (srange
*)i1
->this;
252 sr
->q1
= sr
->q1
- subtrahend
;
253 sr
->q2
= sr
->q2
- subtrahend
;
255 case VAR
: v
= (var
*)i1
->this;
256 /* Recursively distribute the denom throughout the entire
257 nested var structure */
258 v
->item1
= subtract_var_structs(v
->item1
, i2
);
259 v
->item2
= subtract_var_structs(v
->item2
, i2
);
261 default: fprintf(stderr
, "screwy varStruct passed to SUBTRACT_VAR_structS\n");
266 /*-------------------------------------------------------------------------------------*/
267 varStruct
*multiply_var_structs(i1
,i2
)
270 /* multiply <i1> by <i2>. <i2> MUST resolve (or will be coerced) to an integer.
271 * This modifies the internal values within <i1> and <i2>. <i1>'s union remains
272 * of the same type as it starts; i2 is reduced to an integer, if it is not one
275 int multiplicand
= eval_var_struct(i2
), t
, *temp
;
281 case INT
: t
= *(int *)i1
->this * multiplicand
;
282 i1
->this = (varItem
*)&t
;
284 case RNG
: sr
= (srange
*)i1
->this;
285 sr
->q1
= sr
->q1
* multiplicand
;
286 sr
->q2
= sr
->q2
* multiplicand
;
288 case VAR
: v
= (var
*)i1
->this;
289 /* Recursively distribute the denom throughout the entire
290 nested var structure */
291 v
->item1
= multiply_var_structs(v
->item1
, i2
);
292 v
->item2
= multiply_var_structs(v
->item2
, i2
);
294 default: fprintf(stderr
, "screwy varStruct passed to MULTIPLY_VAR_structS\n");
299 /*-------------------------------------------------------------------------------------*/
300 varStruct
*divide_var_structs(i1
,i2
)
303 /* divide <i1> by <i2>. <i2> MUST resolve (or will be coerced) to an integer.
304 * This modifies the internal values within <i1> and <i2>. <i1>'s union remains
305 * of the same type as it starts; i2 is reduced to an integer, if it is not one
308 int denom
= eval_var_struct(i2
), t
, *temp
;
314 case INT
: t
= *(int *)i1
->this / denom
;
315 i1
->this = (varItem
*)&t
;
317 case RNG
: sr
= (srange
*)i1
->this;
318 sr
->q1
= sr
->q1
/ denom
;
319 sr
->q2
= sr
->q2
/ denom
;
321 case VAR
: v
= (var
*)i1
->this;
322 /* Recursively distribute the denom throughout the entire
323 nested var structure */
324 v
->item1
= divide_var_structs(v
->item1
, i2
);
325 v
->item2
= divide_var_structs(v
->item2
, i2
);
327 default: fprintf(stderr
, "screwy varStruct passed to DIVIDE_VAR_STRUCTS\n");
332 /*-------------------------------------------------------------------------------------*/
333 varStruct
*eval_action(a
,i1
,i2
)
337 /* This takes an action and a pair of items and performs the intended action */
340 case ADD
: return(add_var_structs(i1
, i2
));
342 case SUBTRACT
: return(subtract_var_structs(i1
, i2
));
344 case MULTIPLY
: return(multiply_var_structs(i1
, i2
));
346 case DIVIDE
: return(divide_var_structs(i1
, i2
));
348 default : fprintf(stderr
, "screwed up call to EVAL_ACTION\n");
352 /*-------------------------------------------------------------------------------------*/
356 /* This reduces a complex var structure to a simplified one, that is where only
357 ->item1 is active, and the action is ADD. */
358 varStruct
*vt
= reduce_var_struct(v
->item1
);
361 case ADD
: vt
= add_var_structs(vt
, v
->item2
);
363 case SUBTRACT
: vt
= subtract_var_structs(vt
, v
->item2
);
365 case MULTIPLY
: vt
= multiply_var_structs(vt
, v
->item2
);
367 case DIVIDE
: vt
= divide_var_structs(vt
, v
->item2
);
369 default : fprintf(stderr
, "screwed up call to REDUCE_VAR\n");
379 /*-------------------------------------------------------------------------------------*/
383 /* This reduces a complex var structure to a simplified one, and then performs the
384 * operation. All open range structures are replaced by fixed, arbitrary, legal
388 varStruct
*vt
= eval_action(v
->action
, v
->item1
, v
->item2
);
389 int *temp
= (int *)vt
->this;
394 /*-------------------------------------------------------------------------------------*/
395 /*-------------------------------------------------------------------------------------*/
396 /*-------------------------------------------------------------------------------------*/
397 /* end of file "var.c" */