fix+feat: compile/int64 fixes, coverage (visual no-ops, lookahead, unknown-var), multi-line lexer, UDT, inputs#26
Merged
Conversation
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>
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.
Validated against the 81-strategy scraped TV corpus; 1312 codegen tests pass.
Compile-error + int64 correctness
ta.*()[n]history materialization; request.security tuple-result member decl; array index paren-wrap ([[); user-var vs builtin-accessor collision.input.time/input.color→ int64_t;var int = na→na<int>();time/bar_indexhistory series int64 + per-bar push.Coverage (a batch backtest must accept any public script)
color.from_gradient, barecolor(),chart.*_color) → no-op warnings, not hard errors.request.security lookahead_onallowed (engine already supports it end-to-end).var T[]postfix arrays).var T x = na(na-sentinel__pf_na+is_naoverload, type from analyzer annotation).input(<source>)rendered as the source series.Mismatch resolved
/no longer splitsavgPrice=(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