44 lines
1.4 KiB
C
44 lines
1.4 KiB
C
|
|
/**
|
||
|
|
* @file args.c
|
||
|
|
* @brief Implements the shared positional-argument collector.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <akerror.h>
|
||
|
|
|
||
|
|
#include <akbasic/args.h>
|
||
|
|
#include <akbasic/error.h>
|
||
|
|
#include <akbasic/runtime.h>
|
||
|
|
|
||
|
|
akerr_ErrorContext *akbasic_args_numbers(akbasic_Runtime *obj, akbasic_ASTLeaf *expr, const char *verb, double *values, int max, int *count)
|
||
|
|
{
|
||
|
|
PREPARE_ERROR(errctx);
|
||
|
|
akbasic_ASTLeaf *arg = NULL;
|
||
|
|
akbasic_Value *value = NULL;
|
||
|
|
|
||
|
|
FAIL_ZERO_RETURN(errctx, (obj != NULL && expr != NULL && values != NULL && count != NULL),
|
||
|
|
AKERR_NULLPOINTER, "NULL argument in args_numbers");
|
||
|
|
*count = 0;
|
||
|
|
arg = akbasic_leaf_first_argument(expr);
|
||
|
|
/*
|
||
|
|
* A loop, so CATCH and the _BREAK macros are banned in here -- they expand to
|
||
|
|
* a C break and would leave the loop with an error still pending. PASS and
|
||
|
|
* the _RETURN forms only.
|
||
|
|
*/
|
||
|
|
while ( arg != NULL ) {
|
||
|
|
FAIL_NONZERO_RETURN(errctx, (*count >= max), AKBASIC_ERR_SYNTAX,
|
||
|
|
"%s takes at most %d arguments", verb, max);
|
||
|
|
PASS(errctx, akbasic_runtime_evaluate(obj, arg, &value));
|
||
|
|
FAIL_NONZERO_RETURN(errctx, (value->valuetype == AKBASIC_TYPE_STRING),
|
||
|
|
AKBASIC_ERR_TYPE,
|
||
|
|
"%s expected a number in argument %d", verb, *count + 1);
|
||
|
|
if ( value->valuetype == AKBASIC_TYPE_FLOAT ) {
|
||
|
|
values[*count] = value->floatval;
|
||
|
|
} else {
|
||
|
|
values[*count] = (double)value->intval;
|
||
|
|
}
|
||
|
|
*count += 1;
|
||
|
|
arg = arg->next;
|
||
|
|
}
|
||
|
|
SUCCEED_RETURN(errctx);
|
||
|
|
}
|