Skip to content

feat(interp): Addition of math intrinsic functions#218

Open
matburnx wants to merge 3 commits into
mathiasbourgoin:mainfrom
matburnx:math-intrinsic
Open

feat(interp): Addition of math intrinsic functions#218
matburnx wants to merge 3 commits into
mathiasbourgoin:mainfrom
matburnx:math-intrinsic

Conversation

@matburnx

@matburnx matburnx commented Jul 8, 2026

Copy link
Copy Markdown

Overview

This PR introduces support for mathematical intrinsic operations within the interpreter. It adds mappings for mathematical trigonometric primitives (such as atan, cosh, sinh, atan2...) as well as additional mathematical primitives in float64 (min, max, floor, ceil, pow).

Such primitives can be used in signal processing or spatial simulations.

Summary by CodeRabbit

  • New Features
    • Expanded math support for floating-point values, including inverse trig, hyperbolic, and additional common math operations.
    • Added more built-in handling for Float32 and Float64 calculations, with support for both single- and two-argument forms where applicable.
  • Bug Fixes
    • Improved error reporting when math functions are called with the wrong number of arguments, making unsupported cases clearer.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This change extends the intrinsic evaluator with additional math functions for Float32 and Float64 types, including inverse trigonometric functions (asin, acos, atan, atan2), hyperbolic functions (sinh, cosh, tanh), tan, floor, ceil, pow, min, and max, each with arity validation.

Changes

Math Intrinsics Extension

Layer / File(s) Summary
Float32 inverse-trig and hyperbolic intrinsics
sarek/interp/Sarek_ir_interp_intrinsics.ml
Adds asin, acos, atan, atan2, sinh, cosh, tanh handlers to eval_float32_math_intrinsic, raising Unsupported_operation on missing arguments.
Float64 trig and hyperbolic intrinsics
sarek/interp/Sarek_ir_interp_intrinsics.ml
Adds tan, asin, acos, atan, atan2, sinh, cosh, tanh handlers to eval_float64_math_intrinsic with float64-specific arity errors.
Float64 additional numeric operations
sarek/interp/Sarek_ir_interp_intrinsics.ml
Adds floor, ceil, pow, min, max handlers to eval_float64_math_intrinsic, each validating 1 or 2 arguments before computing.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A rabbit hops through sines and cosines bright,
Tangents, hyperbolics, all set right,
Float32 and Float64 now compute with ease,
Arity checks guard against the breeze,
Hop, hop, hooray for math done tight! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding math intrinsic functions to the interpreter.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
sarek/interp/Sarek_ir_interp_intrinsics.ml (2)

361-398: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor: inconsistent use of Float. module qualifier in Float64 handlers.

floor, ceil, min, max use bare stdlib names while Float.abs (line 356), Float.pow (line 378), and Float.of_int (line 401) use the Float. prefix. Consider qualifying consistently (e.g., Float.floor, Float.ceil, Float.min, Float.max) for clarity and to avoid subtle polymorphic-dispatch surprises with min/max.

♻️ Optional consistency fix
- | arg :: _ -> Some (VFloat64 (floor (to_float64 arg)))
+ | arg :: _ -> Some (VFloat64 (Float.floor (to_float64 arg)))
- | arg :: _ -> Some (VFloat64 (ceil (to_float64 arg)))
+ | arg :: _ -> Some (VFloat64 (Float.ceil (to_float64 arg)))
- | arg1 :: arg2 :: _ ->
-     Some (VFloat64 (min (to_float64 arg1) (to_float64 arg2)))
+ | arg1 :: arg2 :: _ ->
+     Some (VFloat64 (Float.min (to_float64 arg1) (to_float64 arg2)))
- | arg1 :: arg2 :: _ ->
-     Some (VFloat64 (max (to_float64 arg1) (to_float64 arg2)))
+ | arg1 :: arg2 :: _ ->
+     Some (VFloat64 (Float.max (to_float64 arg1) (to_float64 arg2)))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sarek/interp/Sarek_ir_interp_intrinsics.ml` around lines 361 - 398, The
Float64 intrinsic handlers in Sarek_ir_interp_intrinsics.ml use an inconsistent
mix of bare stdlib functions and Float.qualified calls. Update the "floor",
"ceil", "min", and "max" branches in the intrinsic dispatch to use the Float
module consistently, matching the surrounding Float.abs, Float.pow, and
Float.of_int usage in the same function, and keep the existing argument
validation and error paths unchanged.

136-184: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider extracting a helper to reduce repetitive arity-validation boilerplate.

Each handler follows the same pattern: match args, extract N arguments, apply function, wrap in VFloatXX, or raise Unsupported_operation. A pair of helpers would eliminate ~40 near-identical blocks:

let unary_float32 name f args =
  match args with
  | arg :: _ -> Some (VFloat32 (f (to_float32 arg)))
  | [] -> Interp_error.raise_error
            (Unsupported_operation {operation = name; reason = "requires 1 argument"})

let binary_float32 name f args =
  match args with
  | arg1 :: arg2 :: _ -> Some (VFloat32 (f (to_float32 arg1) (to_float32 arg2)))
  | _ -> Interp_error.raise_error
           (Unsupported_operation {operation = name; reason = "requires 2 arguments"})

Then each case becomes a one-liner: | "asin" -> unary_float32 "asin" F32.asin args.

Also applies to: 277-332, 361-398

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sarek/interp/Sarek_ir_interp_intrinsics.ml` around lines 136 - 184, The
intrinsic handlers in Sarek_ir_interp_intrinsics.ml repeat the same arity-check
and wrapping logic across many cases, so refactor the repeated pattern into
reusable helpers. Add unary and binary helpers near the dispatcher that accept
the operation name and F32 function, perform the arg matching, and raise
Unsupported_operation with the correct arity when needed; then update each
matching branch such as "asin", "acos", "atan2", "sinh", "cosh", and "tanh" to
call those helpers instead of duplicating the match logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@sarek/interp/Sarek_ir_interp_intrinsics.ml`:
- Around line 361-398: The Float64 intrinsic handlers in
Sarek_ir_interp_intrinsics.ml use an inconsistent mix of bare stdlib functions
and Float.qualified calls. Update the "floor", "ceil", "min", and "max" branches
in the intrinsic dispatch to use the Float module consistently, matching the
surrounding Float.abs, Float.pow, and Float.of_int usage in the same function,
and keep the existing argument validation and error paths unchanged.
- Around line 136-184: The intrinsic handlers in Sarek_ir_interp_intrinsics.ml
repeat the same arity-check and wrapping logic across many cases, so refactor
the repeated pattern into reusable helpers. Add unary and binary helpers near
the dispatcher that accept the operation name and F32 function, perform the arg
matching, and raise Unsupported_operation with the correct arity when needed;
then update each matching branch such as "asin", "acos", "atan2", "sinh",
"cosh", and "tanh" to call those helpers instead of duplicating the match logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b5dc7b14-d1d4-4fed-82a4-31b7ed229933

📥 Commits

Reviewing files that changed from the base of the PR and between 39c9159 and 69bdb58.

📒 Files selected for processing (1)
  • sarek/interp/Sarek_ir_interp_intrinsics.ml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant