/* @@@HEAD@@@
// Miscellaneous operations.
*/
#include "config.h"
#include <stdlib.h>
#include "defs.h"
#include "y.tab.h"
#include "operators.h"
#include "execute.h"
#include "cdc_types.h"
#include "util.h"
internal void find_extreme(int which);
void op_random(void) {
data_t *args;
/* Take one integer argument. */
if (!func_init_1(&args, INTEGER))
return;
/* Replace argument on stack with a random number. */
args[0].u.val = random_number(args[0].u.val) + 1;
}
/* which is 1 for max, -1 for min. */
internal void find_extreme(int which) {
int arg_start, num_args, i, type;
data_t *args, *extreme, d;
arg_start = arg_starts[--arg_pos];
args = &stack[arg_start];
num_args = stack_pos - arg_start;
if (!num_args) {
cthrow(numargs_id, "Called with no arguments, requires at least one.");
return;
}
type = args[0].type;
if (type != INTEGER && type != STRING && type != FLOAT) {
cthrow(type_id, "First argument (%D) not an integer, float or string.",
&args[0]);
return;
}
extreme = &args[0];
for (i = 1; i < num_args; i++) {
if (args[i].type != type) {
cthrow(type_id, "Arguments are not all of same type.");
return;
}
if (data_cmp(&args[i], extreme) * which > 0)
extreme = &args[i];
}
/* Replace args[0] with extreme, and pop other arguments. */
data_dup(&d, extreme);
data_discard(&args[0]);
args[0] = d;
pop(num_args - 1);
}
void op_max(void) {
find_extreme(1);
}
void op_min(void) {
find_extreme(-1);
}
void op_abs(void) {
data_t *args;
if (!func_init_1(&args, INTEGER))
return;
if (args[0].u.val < 0)
args[0].u.val = -args[0].u.val;
}