Repository navigation
det: a float zero divisor is libcob's NaN; a phrase binds to the innermost open statement (#4675, #4676) - #4686
Merged
Merged
Conversation
…SVS does (#4287) The det translator replays cobc -std=ibm's compile-time ARITHMETIC-OSVS decision (det/osvs.py, from GnuCOBOL 3.1.2 typeck.c / tree.c): dmax from receivers and cb_walk_cond, the expr_decp stack with its pushes, pending aligns flushed on the next load, constant folding, conditions built right to left, the state an EVALUATE leaves to its sentence. It emits Cobol.align (libcob's cob_decimal_align, its downward shift included) where cobc emits cob_decimal_align, and a literal on the right of an operation as a Cobol.Dc (libcob's decimal constant, whose scale its uses change). Cobol.divide keeps cob_decimal_div's places and Cobol.power cob_decimal_pow's trimming. Register C2 rewritten: the det runtime matches the oracle; the oracle's departures from IBM's rule are listed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The oracle (GnuCOBOL 3.1.2 -std=ibm) leaves every receiver unchanged on a zero divisor, with or without ON SIZE ERROR; the det port threw ArithmeticException. Cobol.divide now returns libcob's NaN (scale -32768) and raises the statement's size error; add/subtract/multiply/negate/power carry it where the translator sees a division or exponent below; store/storeChecked leave the receiver (lifted receivers guarded with isNan); Cobol.align truncates a NaN to 0 as libcob does. A division in a function argument is 0 (cob_intr_binop); FUNCTION MOD/REM by zero are 0. 0 ** 0 raises the size error; a non-finite exponent is NaN. Statements with ON SIZE ERROR clear and read the size-error state. DIVIDE REMAINDER now uses the quotient truncated to the receiver's places (cob_div_quotient), not the stored quotient. Register entry oracle_assumptions C14 (IBM: undefined / S0CB on z/OS). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…4655) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
expr imported det.cics (for DFHRESP) and det.cvda lazily, and det.cics imported det.gen, which imports det.osvs, which imports expr. expr now imports DFHRESP from gitgalaxy.standards.cics.resp (its home) and CVDA from det.cvda (no imports) at module level, so expr no longer reaches gen. Also one import form for test_det_programs in test_det_osvs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
# Conflicts: # gitgalaxy/tools/cobol_to_java/det/expr.py
…CodeQL) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
…test_det_size_error.py) _java_ok imports test_det_programs as a module, as the e2e test below it does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
Conflicts in oracle_assumptions.md, Cobol.java and gen.py came from #4654's pre-squash commits: main's side taken, then this PR's own changes (6e1de82..f6da8e4) re-applied on top. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
…e-error gen.py COMPUTE: this PR's float_statement(targets) kept with main's p_scaled_expr refusal (#4685). test_det_size_error.py: both branches already use the one `import test_det_programs as T` form (CodeQL). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
oracle_assumptions.md: both register entries kept, C13 (#4668) then C14 (this PR), in the table and the sections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
…/4675-4676-size-error Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
…merged) The conflicts were #4677's pre-squash commits against its squash (identical trees): this branch's side kept; #4683's stmt.py / test_det_conditions.py merged as main has them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4675, Fixes #4676
Stacked on #4677 (-> #4654): merge those first.
Measured (GnuCOBOL 3.1.2
-std=ibm, 2026-10-08)COMPUTE G = F / FZ,DIVIDE FZ INTO G,DIVIDE F BY FZ GIVING Gor a decimal receiver): every receiver unchanged and the size error raised, with or without ON SIZE ERROR. Same as the decimal NaN (det runtime: a zero divisor without ON SIZE ERROR throws in the port; the oracle leaves the receiver unchanged #4655): the oracle converts floats to decimals. ON SIZE ERROR also fires for a decimal receiver too small for a float result.(F/FZ) * 3unchanged, but(F/FZ) * C,FM * (F/FZ)store 0 and2 - (F/FZ)stores 2.Changes
cobolrt/Hfp.divide: a zero divisor is the NaN (raises the size error) instead of an ArithmeticException; newHfp.divideNestedrefuses by name a zero divisor inside a larger float expression (not replayed, C14).gen.py: float COMPUTE / ARITH take ON SIZE ERROR phrases (storeCheckedon the value field), lifted receivers guarded against the NaN, phrase bodies generated in their own arithmetic mode (phrase_block; they inherited the statement's float mode before).det/stmt.py:_phrase_owner/_end_ownerbind a phrase to the innermost unterminated statement that can take it and an END-verb to the innermost open statement of its verb. I did not touchstmt.parse's NOT rewriting (det parse: abbreviated 'OR NOT = x' relation; pin conditions holes 1-2 (#4681) #4683); my edit is the PHRASES / STATEMENT_ENDS branches of the node loop (the same function body, different branches: expect a textual merge at most).Cobol.nan/Cobol.raiseSize(private -> package, no behaviour change). Not touched: layout,Cobol.store/move(P-scaling det translator: a PIC SVPP99 COMP-3 item crashes with ValueError instead of a refusal by name #4669/det runtime: MOVE 1200 into a 99PP item throws in Cobol.store #4670).Evidence
tests/cobol_mainframe/test_det_size_error.py: float shapes H1..HB and nested shapes U1..U6 added to the end-to-end program (cobc vs port, both modes) plus a parse-level test. Before the change the end-to-end test fails (float phrases refused; nested shapes B2/B3/B7 differ), after it passes./tmp/gitgalaxy-scratch/claude/det-4675/fuzz3.py: float items, zero divisors, nested size-error phrases 2 deep, terminated and not): 140 seeds, 104 comparable programs, 0 differences, the rest are tree-sitter "does not parse" holes on the nested shapes. The earlier det runtime: a zero divisor without ON SIZE ERROR throws in the port; the oracle leaves the receiver unchanged #4655 decimal fuzz (18 seeds) still equal.det_port.py checkvs det runtime: a zero divisor leaves the receivers unchanged, as the oracle (#4655) #4677: all 68 ports "changed" only in the shipped runtime (Cobol.java modifiers, Hfp.java); no service differs. Re-proved mortgage-nbrvl and carddemo-acctview PROVED; mortgage-mpmt DIFFERS as on the base (C6 exponent hole).evidence_report.py --checkclean.pr_gates.py --fast5/5;--ratchets7 pass, 0 fail, 0 skipped.Not covered
🤖 Generated with Claude Code