/** * @file args.c * @brief Implements the shared positional-argument collector. */ #include #include #include #include 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); }