Skip to content

move profile tests to other directory and allocate more memory#1

Merged
borisbat merged 1 commit into
masterfrom
more_profile_tests
Dec 31, 2018
Merged

move profile tests to other directory and allocate more memory#1
borisbat merged 1 commit into
masterfrom
more_profile_tests

Conversation

@AntonYudintsev
Copy link
Copy Markdown
Collaborator

No description provided.

@borisbat borisbat merged commit ef9b412 into master Dec 31, 2018
@borisbat borisbat deleted the more_profile_tests branch May 20, 2020 00:05
borisbat pushed a commit that referenced this pull request Dec 19, 2020
fixed warning C5208: unnamed class used in typedef name cannot declar…
borisbat added a commit that referenced this pull request Dec 9, 2025
fix compilation errors
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@borisbat borisbat mentioned this pull request Mar 28, 2026
8 tasks
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Mar 28, 2026
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator
evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch
wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source
multiplication, absolute value transform. All 10 default modulators from SF2
spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve.

Parsing:
- SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry)
- Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type
- Modulators stored on SF2Zone alongside generators

Evaluation:
- sf2_concave/sf2_convex: SF2 spec page 73 transform curves
- sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity
- sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types
- sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform
- sf2_apply_modulators: accumulate per-generator offsets from zone modulators

Default modulators:
- SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib,
  CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune)
- sf2_mod_identity_match + sf2_apply_default_modulators with override logic
- Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1)

Application in sf2_create_c_voice:
- Compute gen_offsets[64] from zone + global + preset modulators + defaults
- Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing

Also: midi_init_reverb() public function for offline rendering with reverb

20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746,
TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Apr 27, 2026
Fixes 7 review comments in one push:

* MCP stdio safety (#1, #5): read_import and compile_and_collect both
  print warnings/failures to stdout, which corrupts the JSON-RPC
  protocol stream when called from the MCP server. Add `quiet : bool
  = false` to both helpers (default preserves CLI behavior); MCP
  find_duplicates passes true and surfaces failure counts via the
  returned envelope.

* Test portability (#2, #3): replace hard-coded /tmp/... corpus path in
  test_find_duplicates_corpus_not_found with create_temp_file_result +
  immediate remove() — guaranteed-nonexistent path that works on
  Windows runners.

* Newline-delimited paths (#4): MCP do_find_duplicates now normalizes
  \n to , before parse_file_list, matching the README's
  documented "git diff --name-only | …" pipeline use case.

* Project (.das_project) plumbing (#6): add `project` to the
  find_duplicates schema, dispatch, and handler signature; thread
  through to compile_and_collect, which now takes
  `project : string = ""` and uses make_file_access(project) instead of
  the previous hardcoded "" — matching the convention used by
  compile_check / lint / find_symbol.

* Deterministic compile order (#7): both the MCP tool and CLI main.das
  build a sorted array<string> from `keys(against_files)` and iterate
  that, instead of the unspecified-order table-key iteration. Makes
  per-candidate report ordering and --check exit behavior reproducible
  across runs.

Drive-by: PERF006 fix in resolve_against_files (reserve before push
loop).

All test suites still green: 6987 in tests/, 54 find_dupes, 181 MCP
(includes 5 updated find_duplicates tests for new signature). MCP
end-to-end smoke confirms newline-delimited paths and project
parameter both reach the handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 5, 2026
PR #2575 review round 3 — three intertwined Option<T> bugs surfaced by Copilot.

1. Generic `sql_bind($Option<auto(TT)>)` fallback in sqlite_boost mirrors
   the existing `sql_storage_enum_for(type<$Option<auto(TT)>>)` pattern.
   Uses `_::sql_bind(default<TT>)` so caller-module adapters resolve;
   without `_::`, recursion runs in sqlite_boost's module and misses
   `@sql_json`/`@sql_blob`-generated overloads.

2. `emit_json_blob_adapters_for_struct` now unwraps Option<T> before
   adapter codegen. Runtime `sql_bind_to_stmt(Option<T>)` strips the
   Option BEFORE calling user `sql_bind`; registering the adapter for
   `Option<NoteData>` was dead code — actual call lands on `sql_bind(NoteData)`.
   Adapter dedup now naturally collapses bare T and Option<T> in the
   same struct (both key as T).

3. Drop the macro-time Option unwrap in `apply_schema_from` from the
   prior round; the witness is back to `_::sql_bind(default<field_type>)`,
   with rail #1 handling the unwrap uniformly.

Tests:
- test_96_schema_from_partial_body: @sql_json + Option, @sql_blob + Option
  via schema_from path (contract + roundtrip).
- test_64_json_columns: standalone @sql_json + Option, plus dedup edge
  case (bare X + Option<X> in same struct).
- test_65_blob_struct: standalone @sql_blob + Option.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 10, 2026
- New skills/mouse.md: practitioner manual behind the MOUSE FIRST rule
  (triggers, asking, adding, editing, carve-outs, dupe-on-add gate).
  Bakes in two telemetry-derived lessons: skip the meta-ask
  ("when-to-consult-mouse" was the #1 hit by 2x and almost all noise);
  symbol-shaped misses go to daslang MCP, not new cards.
- CLAUDE.md: trim "Asking blind-mouse" prose (operational detail moved
  to the skill); add skills-table row.
- install/CLAUDE.md: skills-table row, add utils/mouse/ to SDK Directory
  Layout, add "Personal Q&A Cache (blind-mouse)" section parallel to the
  MCP Server one.
- install/skills.list: add mouse.md (alphabetical).
- No CMake changes — skills.list is read dynamically via file(STRINGS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 12, 2026
#1 DasGlfw_ChainClear restores prev callbacks before erasing the map
entry. Without this, the dispatcher stays installed but early-returns
on every real event, silently disconnecting ImGui_ImplGlfw and any
other prior listener.

#2 ApngWriter::enqueue validates stride_bytes >= row_bytes and
rejects null pixels. Negative or too-small stride was being cast to
size_t and underflowing into OOB reads.

#3 stbi_apng_frame docstring now matches the implementation: positive
stride only, always returns 1 on success, drops oldest on overflow
(visible via stbi_apng_dropped). The prior copy claimed negative
stride and a 0-return-on-full contract, neither of which exists.

#4 mouse_click validates `action` and returns a structured error on
anything other than "press" / "release". Typos like "pressed" no
longer silently flip to release.

#5 mouse_play sorts the wire timeline by t_ms before building the
internal queue, so out-of-order input no longer drops earlier events.
Extracted MouseEventWire + sort_play_events into a small standalone
module (live/mouse_events) so the regression test under
tests/dasglfw/test_mouse_play_sort.das can require only the
algorithm, not glfw_live's full GLFW/OpenGL chain. The module is
marked options no_aot to keep the test interpreter-friendly under
test_aot. tests/aot/CMakeLists.txt registers tests/dasglfw/ alongside
the other test directories.

#6 record_start clamps `fps` to >= 1.0 and stores/reports the
effective value, instead of accepting a sub-1 fps in status output
while running the scheduler at the clamped rate.

#7 record_tick resyncs next_capture_t to `now + frame_interval_s`
after a stall instead of catch-up bursting. delay_ms now reflects
the actual elapsed time between captures so playback timing matches
the real spacing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 13, 2026
Five fixes from the round-1 review on PR #2645.

Copilot #1 — Leak on glGenBuffers id==0 early return:
  The `id == 0u` early return path now glDeleteBuffers the partial
  allocation and `delete pbos` before returning the error, so a
  pathological driver doesn't leak GL buffers + the local array.

Copilot #2 — stbi_write_set_png_compression_level was global mutation:
  RecorderState gains `prev_png_level`. record_start captures the
  current level via `stbi_write_get_png_compression_level()` before
  setting it to 4, then record_stop restores it. The writer-open-failure
  cleanup path also restores. Screenshot and any unrelated PNG writes
  are no longer permanently throttled to the tutorial-friendly level.

Copilot #3 — glUnmapBuffer return value ignored:
  harvest_one_pbo now captures glUnmapBuffer's return; GL_FALSE means
  the driver invalidated the buffer contents while it was mapped, so
  treat it as a harvest failure rather than letting potentially junk
  pixels into the apng stream.

Copilot #4 — record_stop drain comment was wrong:
  The previous comment claimed failures were "logged via the dropped
  counter", but `stbi_apng_dropped()` only reports encoder queue
  overflows inside the writer — not GL-side harvest failures. Comment
  now states behaviour accurately: a failed drain breaks the loop and
  the resulting `frames` count reflects what actually made it to disk.

aleksisch — unsafe audit + narrowing:
  Several `unsafe { ... }` blocks wrapped calls that don't actually
  need unsafe in daslang (int-only arg lists, GLenum-only arg lists,
  null-data variants of GL buffer functions). Drops:
    - stbi_write_set_png_compression_level (int arg only)
    - stbi_apng_dropped / stbi_apng_end (void? writer, no raw ptr exposed)
    - glBufferData(target, size, null, usage) (null data variant)
    - glUnmapBuffer (GLenum arg, GLboolean return)
    - glReadPixels(..., null) into bound PBO (null data variant)
  Remaining unsafe is narrowed from `unsafe { ... }` to `unsafe(expr)`
  on the bare expressions that genuinely need it (every `addr(pbos[0])`
  call returning a raw pointer, and `stbi_apng_frame` which takes a
  raw `void*` pixel pointer). A general lint rule for redundant
  `unsafe` is out of scope for this PR — separate followup.

While there, two STYLE005 lint hits fixed by switching to postfix
`break if`/`return if`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 20, 2026
…owings

Round 4 of Copilot review + a broader audit (2 subagents) of the
runtime_array / runtime_table families turned up several silent
narrowings that survived Phase 2's widening. All fixed here.

Copilot comments (9, all accepted):

- runtime_table.h grow(): guard `tab.capacity*2` against uint64 overflow,
  mirror the 2^62 cap already in `reserve(size,at)`. Otherwise a capacity
  past 2^63 doubled to 0 and tripped the pow2 check / underflowed `mask`.
- runtime_table.h reserveInternal: assert newCapacity != 0 alongside the
  pow2 check (0 & -1 trivially satisfies pow2). Belt-and-braces after #1.
- runtime_array.cpp array_resize: enforce `newSize <= INT64_MAX` up front.
  `long_length()` returns int64, so sizes wider than that wrap negative
  on the way out — refuse to put the array there.
- aot_builtin.h array_grow: same INT64_MAX cap, AOT-side mirror.
- builtin_array_long_size / long_capacity (module_builtin_array.cpp):
  DAS_VERIFYF before the uint64→int64 cast so a corrupted/embedder-set
  size > INT64_MAX panics instead of returning negative.
- builtin_table_long_size / long_capacity: same for tables.
- runtime_table_nodes.h: drop stale "index==-1, so safe to do" comment on
  `thh.reserve` — reserve returns a valid slot or throws; -1 is only the
  not-found sentinel from find/erase.
- dw_common.das + test_walk_filtering.das: stop narrowing the now-uint64
  walker count/index params via `int(...)` in test logs; use int64(...).
- tutorials/language/47_data_walker.das: same int→int64 swap in the
  ContainerPrinter and JsonWalker print strings I just touched in the
  override widening commit.

Audit findings beyond the Copilot list:

- aot.h das_delete<TArray>/<TTable>::clear: `uint32_t oldSize =
  capacity * sizeof(...)` silently truncated for capacities past
  UINT32_MAX/stride. The free accountant then mis-tracked the heap.
  Widened to uint64_t — mirrors the interpreter paths in runtime_array
  .cpp / runtime_table.cpp that already used uint64.
- runtime_array.h SimNode_ForGoodArray: 12 sites declared
  `int szz = INT_MAX` / `int szz = int(pha->size)` then iterated `for
  (int i = 0; i!=szz; ++i)`. For arrays > INT_MAX the truncated szz
  short-circuits the loop or wraps negative. Widened szz, the
  per-source min(), and the loop counters all to uint64_t.
- module_builtin_runtime_sort.cpp: 6 array-side sort wrappers
  (sort/partial_sort/nth_element × cblock+ref_cblock) silently
  narrowed `arr.size` (uint64) to int32_t when passing to the inner
  byte-pointer routines. Now panic up-front with a "use long_sort()
  instead" hint (long_sort surface is Phase 4 follow-up).
- aot.h pscblk_array (partial_sort templates): clamp `n =
  int32_t(arr.size)` wrapped for sizes > INT_MAX. Panic before the
  clamp now.
- module_builtin_runtime.cpp builtin_temp_array (block-form, int
  size): negative size wrapped to huge uint capacity via
  `uint32_t(size)`. Clamped to 0 like the already-fixed
  builtin_make_temp_array.

8932/8932 interpreter tests pass locally. Format + lint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
borisbat added a commit that referenced this pull request May 20, 2026
…ins+take + take-limit hoist

Three correctness fixes flagged in Copilot review of PR #2770:

1. **Early-exit boolean confusion when take present (review #1).** When `takeExpr != null`,
   `any`/`all`/`contains` now route their answer through explicit `decs_found` state
   instead of `for_each_archetype_find`'s return value. Take-cap exits also emit
   `return true` (to stop the archetype walk), so the find result was ambiguous:
   `take(3).any(_>100)` on a 7-element source where no element matches would
   return true (the take-cap hit, not a match). Same trap for `contains` (false
   positive) and `all` (false negative — take-cap looks like "counterexample
   found"). Fix: in the takeExpr-present branch, set explicit `decs_found = true`
   on the actual match path; tail returns `decs_found` (or `!decs_found` for
   `all`); the find call's result is used only as iteration control.

2. **Take limit re-evaluated per element (review #2).** `wrap_inner_for_with_decs_ranges`
   embedded `clone_expression(rangeInfo.takeExpr)` directly in the per-element
   guard, so the take expression evaluated on every iteration. `take(src, total:int)`
   semantics evaluate `total` once at call time. Fix: hoist take limit into a
   `let decs_takel = $e(takeExpr)` in `decs_range_prelude` (alongside the
   existing skip hoist); per-element guard compares against the hoisted local.

3. **Missing coverage (review #3).** 7 new behavioral tests + 1 hoist regression
   test in tests/linq/test_linq_from_decs.das:
   - `take(0).any()` returns false on non-empty source
   - `take(3).any(_ > 100)` returns false when no prefix match (catches review-1 bug)
   - `take(3).any(_ == 1)` returns true when match in prefix
   - `take(3).all(_ >= 0)` returns true when prefix passes (catches review-1 bug)
   - `take(3).all(_ <= 1)` returns false when prefix has counterexample
   - `take(5).contains(2)` returns true on hit
   - `take(2).contains(100)` returns false on miss (catches review-1 bug)
   - `take(side_effect_fn())` evaluates the take expression exactly once (catches review-2 bug)

Verification:
- format clean, lint clean
- interp: 60/60 in test_linq_from_decs.das (was 52, +8 new)
- AOT: 1247/1247 via bin/test_aot (was 1239, +8)
- ast_dump on target_unroll_take_all_fail_fold confirms explicit-state shape:
  `var decs_found = false; ... if (!pred) { decs_found = true; return true } ...
  return !decs_found` with the for_each_archetype_find result discarded

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

2 participants