Acme-ExtUtils-XSOne-Test-Calculator

 view release on metacpan or  search on metacpan

Calculator.xs  view on Meta::CPAN


    if (dst_gv) {
        SvREFCNT_inc((SV*)cv);
        GvCV_set(dst_gv, cv);
    }
}

/*
 * do_import - Generic import handler
 * pkg: the package being imported from
 * exports: array of exportable function names
 * export_count: number of exports
 * items: number of arguments to import()
 * ax: argument stack offset
 *
 * Call from import() like:
 *   static const char *basic_exports[] = {"add", "subtract", ...};
 *   do_import(aTHX_ "...::Basic", basic_exports, 10, items, ax);
 */
static void do_import(pTHX_ const char *pkg, const char **exports, int export_count, I32 items, I32 ax) {
    const char *caller;
    int i, j;

    /* Get caller's package name */
    caller = CopSTASHPV(PL_curcop);
    if (!caller || !*caller) {
        caller = "main";
    }

    /* Process import list (skip first arg which is the package name) */
    for (i = 1; i < items; i++) {
        SV *arg = ST(i);
        const char *name;
        STRLEN name_len;
        int found = 0;

        name = SvPV(arg, name_len);

        /* Find the export */
        for (j = 0; j < export_count; j++) {
            if (strcmp(name, exports[j]) == 0) {
                export_sub(aTHX_ pkg, name, caller);
                found = 1;
                break;
            }
        }

        if (!found) {
            croak("\"%s\" is not exported by the %s module", name, pkg);
        }
    }
}
/* C code from: Calculator/Basic.xs */
#line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Basic.xs"
/*
 * Acme::ExtUtils::XSOne::Test::Calculator::Basic - Basic arithmetic operations
 */


/* C helper functions for Basic package */
static double basic_safe_divide(double a, double b, int *error) {
    if (b == 0.0) {
        *error = 1;
        return 0.0;
    }
    *error = 0;
    return a / b;
}

static double basic_clamp(double value, double min_val, double max_val) {
    if (value < min_val) return min_val;
    if (value > max_val) return max_val;
    return value;
}

static double basic_percent(double value, double percent) {
    return value * percent / 100.0;
}
/* C code from: Calculator/Memory.xs */
#line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Memory.xs"
/*
 * Acme::ExtUtils::XSOne::Test::Calculator::Memory - Memory and history functions
 *
 * This module accesses the shared state defined in _header.xs
 */

/* Memory package helpers - need access to memory_slots */
static int mem_is_valid_slot(int slot) {
    return (slot >= 0 && slot < MAX_MEMORY_SLOTS);
}

static int mem_get_used_slots(void) {
    int count = 0;
    for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
        if (memory_slots[i] != 0.0) count++;
    }
    return count;
}

static double mem_sum_all(void) {
    double sum = 0.0;
    for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
        sum += memory_slots[i];
    }
    return sum;
}

static void mem_add_to_slot(int slot, double value) {
    if (mem_is_valid_slot(slot)) {
        memory_slots[slot] += value;
    }
}
/* C code from: Calculator/Scientific.xs */
#line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Scientific.xs"
/*
 * Acme::ExtUtils::XSOne::Test::Calculator::Scientific - Scientific/advanced operations
 */


/* C helper functions for Scientific package */
static double sci_safe_log(double a, int *error) {
    if (a <= 0.0) {
        *error = 1;
        return 0.0;
    }
    *error = 0;
    return log(a);
}

static double sci_safe_sqrt(double a, int *error) {
    if (a < 0.0) {
        *error = 1;
        return 0.0;
    }
    *error = 0;
    return sqrt(a);
}

static double sci_ipow(double base, int exp) {
    /* Integer power - faster than pow() for integer exponents */
    if (exp == 0) return 1.0;
    int neg = 0;
    if (exp < 0) {
        neg = 1;
        exp = -exp;
    }
    double result = 1.0;
    while (exp > 0) {
        if (exp & 1) result *= base;
        base *= base;
        exp >>= 1;
    }
    return neg ? 1.0 / result : result;
}

static double sci_combination(int n, int r) {
    if (r > n || r < 0) return 0.0;
    if (r == 0 || r == n) return 1.0;
    double result = 1.0;
    for (int i = 0; i < r; i++) {
        result = result * (n - i) / (i + 1);
    }
    return result;
}
/* C code from: Calculator/Trig.xs */
#line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.xs"
/*
 * Acme::ExtUtils::XSOne::Test::Calculator::Trig - Trigonometric functions
 */


/* C helper functions for Trig package */
static double trig_normalize_angle(double radians) {
    /* Normalize angle to [-PI, PI] */
    while (radians > M_PI) radians -= 2.0 * M_PI;
    while (radians < -M_PI) radians += 2.0 * M_PI;
    return radians;
}

static int trig_is_valid_asin_arg(double x) {
    return (x >= -1.0 && x <= 1.0);
}

static double trig_sec(double x) {
    return 1.0 / cos(x);
}

static double trig_csc(double x) {
    return 1.0 / sin(x);
}

static double trig_cot(double x) {
    return cos(x) / sin(x);
}
/* C code from: _footer.xs */

Calculator.xs  view on Meta::CPAN


double
multiply(a, b)
    double a
    double b
CODE:
    RETVAL = a * b;
    add_to_history('*', a, b, RETVAL);
OUTPUT:
    RETVAL

double
divide(a, b)
    double a
    double b
CODE:
    if (b == 0.0) {
        croak("Division by zero");
    }
    RETVAL = a / b;
    add_to_history('/', a, b, RETVAL);
OUTPUT:
    RETVAL

double
modulo(a, b)
    double a
    double b
CODE:
    if (b == 0.0) {
        croak("Modulo by zero");
    }
    RETVAL = fmod(a, b);
    add_to_history('%', a, b, RETVAL);
OUTPUT:
    RETVAL

double
negate(a)
    double a
CODE:
    RETVAL = -a;
    add_to_history('n', a, 0, RETVAL);
OUTPUT:
    RETVAL

double
absolute(a)
    double a
CODE:
    RETVAL = fabs(a);
    add_to_history('a', a, 0, RETVAL);
OUTPUT:
    RETVAL

double
safe_divide(a, b)
    double a
    double b
CODE:
    int error;
    RETVAL = basic_safe_divide(a, b, &error);
    if (error) {
        RETVAL = 0.0;  /* Return 0 instead of croak */
    }
    add_to_history('/', a, b, RETVAL);
OUTPUT:
    RETVAL

double
clamp(value, min_val, max_val)
    double value
    double min_val
    double max_val
CODE:
    RETVAL = basic_clamp(value, min_val, max_val);
OUTPUT:
    RETVAL

double
percent(value, pct)
    double value
    double pct
CODE:
    RETVAL = basic_percent(value, pct);
    add_to_history('%', value, pct, RETVAL);
OUTPUT:
    RETVAL

void
import(...)
CODE:
{
    static const char *basic_exports[] = {
        "add", "subtract", "multiply", "divide", "modulo",
        "negate", "absolute", "safe_divide", "clamp", "percent"
    };
    do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Basic",
              basic_exports, 10, items, ax);
}


MODULE = Acme::ExtUtils::XSOne::Test::Calculator    PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Memory

PROTOTYPES: DISABLE

int
store(slot, value)
    int slot
    double value
CODE:
    RETVAL = store_memory(slot, value);
    if (!RETVAL) {
        warn("Invalid memory slot %d (valid: 0-%d)", slot, MAX_MEMORY_SLOTS - 1);
    }
OUTPUT:
    RETVAL

double
recall(slot)
    int slot
CODE:
    if (slot < 0 || slot >= MAX_MEMORY_SLOTS) {

Calculator.xs  view on Meta::CPAN

    }
    RETVAL = log10(a);
    add_to_history('L', a, 10, RETVAL);
OUTPUT:
    RETVAL

double
log_base(a, base)
    double a
    double base
CODE:
    if (a <= 0.0 || base <= 0.0 || base == 1.0) {
        croak("Invalid logarithm arguments");
    }
    RETVAL = log(a) / log(base);
    add_to_history('L', a, base, RETVAL);
OUTPUT:
    RETVAL

double
exp_val(a)
    double a
CODE:
    RETVAL = exp(a);
    add_to_history('e', a, 0, RETVAL);
OUTPUT:
    RETVAL

double
factorial(n)
    int n
CODE:
    if (n < 0) {
        croak("Cannot take factorial of negative number");
    }
    if (n > 170) {
        croak("Factorial overflow (max 170)");
    }
    RETVAL = 1.0;
    for (int i = 2; i <= n; i++) {
        RETVAL *= i;
    }
    add_to_history('!', (double)n, 0, RETVAL);
OUTPUT:
    RETVAL

double
ipow(base, exp)
    double base
    int exp
CODE:
    RETVAL = sci_ipow(base, exp);
    add_to_history('^', base, (double)exp, RETVAL);
OUTPUT:
    RETVAL

double
safe_sqrt(a)
    double a
CODE:
    int error;
    RETVAL = sci_safe_sqrt(a, &error);
    if (!error) {
        add_to_history('r', a, 0.5, RETVAL);
    }
OUTPUT:
    RETVAL

double
safe_log(a)
    double a
CODE:
    int error;
    RETVAL = sci_safe_log(a, &error);
    if (!error) {
        add_to_history('l', a, M_E, RETVAL);
    }
OUTPUT:
    RETVAL

double
combination(n, r)
    int n
    int r
CODE:
    RETVAL = sci_combination(n, r);
    add_to_history('C', (double)n, (double)r, RETVAL);
OUTPUT:
    RETVAL

double
permutation(n, r)
    int n
    int r
CODE:
    if (r > n || r < 0 || n < 0) {
        RETVAL = 0.0;
    } else {
        RETVAL = sci_combination(n, r);
        for (int i = 2; i <= r; i++) {
            RETVAL *= i;
        }
    }
    add_to_history('P', (double)n, (double)r, RETVAL);
OUTPUT:
    RETVAL

void
import(...)
CODE:
{
    static const char *scientific_exports[] = {
        "power", "sqrt_val", "cbrt_val", "nth_root",
        "log_natural", "log10_val", "log_base", "exp_val",
        "factorial", "ipow", "safe_sqrt", "safe_log",
        "combination", "permutation"
    };
    do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Scientific",
              scientific_exports, 14, items, ax);
}


MODULE = Acme::ExtUtils::XSOne::Test::Calculator    PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Trig

PROTOTYPES: DISABLE

double
sin_val(a)
    double a
CODE:
    RETVAL = sin(a);
    add_to_history('s', a, 0, RETVAL);
OUTPUT:
    RETVAL



( run in 0.736 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )