Skip to content

fix+feat: compile/int64 fixes, coverage (visual no-ops, lookahead, unknown-var), multi-line lexer, UDT, inputs#26

Merged
luisleo526 merged 4 commits into
mainfrom
fix/codegen-int64-and-compile-bugs
Jun 28, 2026
Merged

fix+feat: compile/int64 fixes, coverage (visual no-ops, lookahead, unknown-var), multi-line lexer, UDT, inputs#26
luisleo526 merged 4 commits into
mainfrom
fix/codegen-int64-and-compile-bugs

Conversation

@luisleo526

Copy link
Copy Markdown
Contributor

Validated against the 81-strategy scraped TV corpus; 1312 codegen tests pass.

Compile-error + int64 correctness

  • tuple-destructured TA series history push; inline ta.*()[n] history materialization; request.security tuple-result member decl; array index paren-wrap ([[); user-var vs builtin-accessor collision.
  • int64 cluster: input.time/input.color → int64_t; var int = nana<int>(); time/bar_index history series int64 + per-bar push.

Coverage (a batch backtest must accept any public script)

  • Cosmetic/chart calls (color.from_gradient, bare color(), chart.*_color) → no-op warnings, not hard errors.
  • request.security lookahead_on allowed (engine already supports it end-to-end).
  • Spurious "Unknown variable" fixed (operator-first line continuation, var T[] postfix arrays).
  • UDT var T x = na (na-sentinel __pf_na + is_na overload, type from analyzer annotation).
  • Bare input(<source>) rendered as the source series.

Mismatch resolved

  • Multi-line lexer: a paren-close ending in a trailing / no longer splits avgPrice=(a*x+b*y)/(x+y) → fixes a DCA average→TP miscompute. dr-ziuber 21%→100% trade match. 260 corpus strategies byte-identical.

Scraped corpus: ok 39→63, transpile-errors 23→16, compile-errors 6→1, canonical excellent 31→40.

🤖 Generated with Claude Code

luisleo526 and others added 4 commits June 28, 2026 17:30
Two classes of codegen defects found by verifying 81 scraped TV
strategies against the local engine.

Compile-errors (strategy failed to build):
- visit_stmt.py: push tuple-destructured TA-call elements into their
  Series member when history-referenced (`[v,dir]=ta.supertrend()`;
  `dir[1]`) instead of shadowing the member with a scalar local.
- visit_expr.py: materialize an inline `ta.*()[n]` result into a
  per-bar history buffer (was subscripting a freshly-computed scalar).
- security.py: request.security with a tuple body now assigns the
  per-element `_req_sec_{id}_{i}` members instead of an undeclared
  aggregate `_req_sec_{id}`.
- tables.py: paren-wrap array get/set/remove/percentrank subscript
  indices so a lambda-leading index can't form `[[` (parsed as a
  C++11 attribute).
- helpers.py: escape user identifiers that collide with builtin
  read-only accessor names (`gross_profit` etc.) so a user var no
  longer shadows the `gross_profit()` accessor call.

int64-correctness (compiled but silently produced 0/wrong trades):
- types.py: input.time / input.color are typed int64_t (their getter
  is get_input_int64); int32 truncated epoch-ms date-window bounds to
  negative, leaving the window guard permanently false.
- emit_top.py + ta.py: a `var int x = na` initializes to na<int>()
  (INT_MIN sentinel) not na<double>() (NaN->int is UB and defeats
  is_na<int>()).
- types.py + emit_top.py: bare `time`/`bar_index` history series are
  declared Series<int64_t> (for time) and pushed every bar, so
  `time[1]`/`bar_index[n]` read real prior-bar values instead of an
  unfed na sentinel.

Corpus: OK 39->49, compile-errors 6->0, no-trades 5->1, 19 perfect.
Full codegen test suite: 1311 passed. Golden updated for the
intentional array-subscript paren-wrap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ti-line lexer fix

Applicability + one mismatch resolved, all guarded by the 1312-test suite.

Coverage (strategies a batch backtest should accept, not reject):
- support_checker.py: cosmetic/chart-only calls are WARNINGS, not hard errors —
  color.from_gradient, bare color() cast, chart.fg_color/bg_color/
  *_visible_bar_time. Codegen emits a benign default (0 / na color) so the C++
  still compiles. A backtest must not be thrown out for drawing or theming.
- support_checker.py: stop hard-rejecting request.security(..., lookahead=
  barmerge.lookahead_on) — codegen + engine already implement it end-to-end;
  only the strict gate rejected it.
- lexer.py / parser.py: fix spurious "Unknown variable" rejections of valid
  Pine — operator-first line continuation (`: na`, `? x`, `+ y`) and
  `var T[] name` postfix-array declarations were mis-tokenized.

Mismatch resolved:
- lexer.py: a paren-close that ends with a trailing binary operator (`/`, `+`,
  …) no longer force-terminates the logical line. A multi-line
  `avgPrice = (a*x + b*y) / (x + y)` was being split, miscomputing the DCA
  average-price and thus the take-profit level. dr-ziuber-bb-short-dca:
  21% -> 100% trade match (px 100%). Re-transpiled 260 corpus strategies:
  byte-identical C++ (zero parity impact).

Scraped corpus: transpile-errors 23->16, ok 49->53, excellent 31->32.
Tests: 1312 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two more coverage fixes, guarded by the 1312-test suite.

UDT vars (briancurry SDZone): `var SDZone z = na` declared the member as
`double` (NA->double) because UDT detection only matched a `T.new(...)`
initializer, not the analyzer's recorded type annotation — so a later
`z := SDZone.new(...)` was "assigning to double from incompatible type
SDZone". Now: type UDT var members from ctx._udt_var_types; every generated
UDT struct carries a trailing `bool __pf_na` sentinel + an `is_na(const T&)`
overload (so `na(udtVar)` compiles), `T.new(...)` sets it false, and the ctor
skips UDT members (they default-construct to na). briancurry: compile-error ->
358 trades, entry/exit p90 0.0000%.

Bare input() (jayentriken): a bare `input(<source>)` for a price-source input
was mis-rendered, gating every entry off. Now rendered as the source series.
jayentriken-bbwp: no-trades -> 562 trades (88% matched, entry p90 0.0000%).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`chart.bg_color` (and the other chart/cosmetic reads) became warn+no-op
instead of a hard reject in this branch, so the gate fixture moves from the
expect-reject (err/) corpus to expect-accept (ok/). Only this one fixture
flips; the other err/ fixtures still reject.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@luisleo526 luisleo526 merged commit 4ad6f7a into main Jun 28, 2026
9 checks passed
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