Add the missing built-in constant-expression functions (#390) - #407
Add the missing built-in constant-expression functions (#390)#407TheGupta2012 wants to merge 1 commit into
Conversation
Adds ceiling, floor, exp, log, mod, popcount, rotl, and rotr to FUNCTION_MAP, each usable in a const initializer and as a gate argument. FUNCTION_MAP now carries an arity alongside each implementation, so the evaluator can dispatch multi-argument calls and reject a wrong argument count. rotl and rotr preserve the operand's declared width by resolving it from a BitValue, a bitstring literal, or the declaration of a bit[n] / uint[n] identifier; a widthless operand is rejected rather than given a guessed width. An unknown function name, a wrong arity, or a wrong argument type now raises a FunctionCallError, which raise_qasm3_error merges into the statement-level message so the offending function is named instead of only reporting "Invalid initialization value". pow is excluded: it is ambiguous with the gate modifier of the same name, and upstream removed it from the spec in openqasm/openqasm#635. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Argus reviewAuto-review is off for this repo. Tick the box below to run a review on this PR.
Estimated cost
Tip: you can also comment |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Closes #390.
Problem
FUNCTION_MAPprovided only 10 of the spec's built-in constant expression functions.ceiling,floor,exp,log,mod,popcount,rotl, androtrall failed with the genericInvalid initialization value for constant 'c', in aconstinitializer and as a gate argument alike. The evaluator also passed onlyarguments[0], so no multi-argument function could work andsqrt(2.0, 3.0)was silently accepted.Approach
FUNCTION_MAPnow maps each name to(implementation, arity). The evaluator dispatches through a single_evaluate_builtin_function, which checks arity, evaluates every argument, and turns aTypeError/ValueErrorfrom the implementation into a located error.rotl/rotrpreserve the operand's declared width. The width comes from aBitValue, a bitstring literal, or the declaration of abit[n]/uint[n]identifier. A widthless operand (rotl(37, 3)) is rejected rather than given a guessed width.FunctionCallError(ValidationError)covers an unknown name, a wrong arity, and a wrong argument type.raise_qasm3_errormerges it into the statement-level message, so the user gets both the context and the function name:Invalid initialization value for constant 'c': Function 'sqrt' expects 1 argument(s), but 2 were given. One change site instead of one per wrapper, and no existing message is altered._handle_function_init_expressionemits aBitstringLiteralfor aBitValueassigned to abit[n], and anIntegerLiteralfor an integral result.np.modreturnsnp.int64, which the oldisinstancecheck missed, leavingmod(7, 2)un-unrolled in the output.Tests
tests/qasm3/test_expressions.py, 22 new cases: every function in both aconstinitializer and a gate argument;rotl(a, n) == rotr(a, -n)and width preservation across rotations of 0, 1, 3, 8, 11, and -3; width recovery from auint[8]declaration; arity errors for 1-, 2-, and 0-argument mistakes; type errors forceiling("01"),rotl("1010", 1.5),popcount(1.5), androtl(37, 3); and the unknown-name message.powconst int c = pow(2, 3);still fails at parse time inopenqasm31.0.1, verified against the installed version —powis also the gate-modifier keyword, so the grammar cannot tell the two apart.No upstream issue should be filed. Upstream already removed
powfrom the spec for exactly this reason: openqasm/openqasm#627 proposed the deprecation, and openqasm/openqasm#635 landed it on 2025-10-15.**is the supported spelling and pyqasm already handles it. A test pins both halves of that:pow(2, 3)raises a parse error,2 ** 3validates.Stacked on #404 (
feature-385-391-bit-repr-negative-indices); rebases ontomainonce #404 merges.🤖 Generated with Claude Code