pineforge-codegen 0.8.1__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/CLAUDE.md +34 -24
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/PKG-INFO +1 -1
- pineforge_codegen-0.9.0/VERSION +1 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/base.py +350 -36
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/call_handlers.py +244 -133
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/contracts.py +29 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/diagnostics.py +18 -4
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/tables.py +20 -2
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/base.py +1147 -110
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/drawing.py +1 -1
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/emit_top.py +253 -21
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/input.py +17 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/security.py +506 -35
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/ta.py +87 -1
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/tables.py +56 -7
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/types.py +112 -30
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/visit_call.py +184 -53
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/visit_expr.py +62 -14
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/visit_stmt.py +74 -36
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/parser.py +73 -6
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/signatures.py +2 -2
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/support_checker.py +39 -2
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/golden/matrix_eigen_pca.cpp +102 -51
- pineforge_codegen-0.9.0/tests/test_calc_on_order_fills_codegen.py +435 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_audit_fixes.py +26 -13
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_determinism.py +37 -2
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_drawing_data.py +8 -8
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_new.py +257 -24
- pineforge_codegen-0.9.0/tests/test_codegen_ta_derived_length.py +598 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_validation_fixes.py +309 -1
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_compile_smoke.py +167 -5
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_parser.py +15 -0
- pineforge_codegen-0.9.0/tests/test_security_math_reducer.py +53 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_security_ohlc_hist_is_complete.py +49 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker.py +26 -2
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_udt_lvalue_alias.py +92 -0
- pineforge_codegen-0.8.1/VERSION +0 -1
- pineforge_codegen-0.8.1/tests/test_codegen_ta_derived_length.py +0 -183
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.github/dependabot.yml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.github/workflows/gate.yml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.github/workflows/publish-pyodide.yml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.github/workflows/release.yml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.github/workflows/test.yml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/.gitignore +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/LEGAL.md +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/LICENSE +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/PYODIDE_TARGET +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/README.md +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/docs/codegen-coverage-gaps.md +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/gate/compare.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/gate/glue.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/gate/oracle.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/gate/run-gate.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/gate/selftest.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/npm/README.md +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/npm/index.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/npm/package.json +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/package-lock.json +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/package.json +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/__init__.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/__init__.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/analyzer/types.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/ast_nodes.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/__init__.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/helpers.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/codegen/helpers_syminfo.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/errors.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/lexer.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/pragmas.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/symbols.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/tokens.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pineforge_codegen/tv_input_choices.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/pyproject.toml +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/scripts/build-npm-package.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/scripts/dump-tables.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/scripts/worker-template.mjs +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/__init__.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/_compile.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/const_ns_plot_style_free.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/const_ns_shape_free.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/divergent_last_bar_index.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/export_func.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/footprint_new.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/hard_reject_dividends.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/matrix_unknown_elem.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/multi_error_one_line.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/sec_tf_invalid.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_color.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_math.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_str.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_strategy_fn.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_syminfo.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/err/unknown_ta.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/chart_bg_color.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/tutorial__macd__strategy.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/tutorial__mtf__strategy_htf.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/tutorial__mtf__strategy_ltf.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-parity-choch-bos-isolator-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-parity-edge-margin-50-pct-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-parity-percent-of-equity-sizing-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-parity-small-equity-fraction-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-parity-stop-limit-timing-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__analyzer-self-test-multi-mode-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__anomaly-equity-mirror-strategy-equity-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-off-01b.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-on-01a.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-atr-trail-series-int-points-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-atr-trailing-stop-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-entry-exit-same-pass-attach-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-exit-stop-limit-trail-same-bar-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-exit-three-way-set-once-entry-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-exit-tp-sl-fixed-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-narrow-stop-limit-with-trail8-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-partial-exit-qty-percent-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-same-id-exit-replace-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-tp-sl-oca-reduce-isolate-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-trail-points-no-offset-explicit-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-trail-points-with-offset-only-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__bracket-trailing-activation-offset-path-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__cap-max-intraday-filled-orders-isolate-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__cap-risk-gates-allow-max-intraday-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-4emarsi-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-4emarsi-quad-ema-stack-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-4emarsi-rsi-pullback-latch-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-4emarsi-session-window-nbar-exit-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-boscurv-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-boscurv-linreg-slope-channel-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-boscurv-pivot-bos-trigger-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-bracket-cap-range-pending-stop-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-adx-regime-classify-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-bb-kc-squeeze-release-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-cooldown-daily-cap-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-equity-feedback-sizing-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-pivot-liquidity-sweep-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-pressure-gauge-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-rsi-macd-momentum-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-ies-three-ema-bias-score-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kanuck-calc-on-every-tick-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kanuck-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kanuck-kama-state-recurrence-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kanuck-max-bars-back-500-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kkb-ema-atr-breakout-band-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kkb-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kkb-kalman-filter-1d-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-kkb-margin-100-pct-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-liqsweep-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-liqsweep-pivot-hh-ll-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-liqsweep-wait-one-continuation-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-liqsweep-wick-pierce-close-back-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-marketshift-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-marketshift-pivot-state-machine-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-marketshift-rolling-highest-lowest-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-marketshift-state-edge-detector-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-scalping-fast-ma-cross-trigger-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-scalping-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-scalping-tight-tp-sl-points-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-trendmaster-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-trendmaster-line-new-projection-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-trendmaster-pivot-anchored-bracket-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-trendmaster-three-tier-ema-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-trendmaster-trend-momentum-structure-gate-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-cumulative-volume-delta-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-fvg-active-zones-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-manual-adx-regime-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-pivot-strength-5-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-rsi-smooth-divergence-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-session-tz-newyork-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-vcp-vol-zscore-anomaly-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-alert-templates-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-explicit-reverse-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-integration-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__input-source-runtime-override-high-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__input-source-subscript-hl2-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ltf-bool-array-bull-majority-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ltf-numeric-float-ratio15-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-rsi-cross-08a.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-volume-weighted-on-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-explicit-utc-tz-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-no-transpose-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-transpose-roundtrip-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-bool-regime-mask-24x7-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-covariance-eigen-pca-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__matrix-eigen-rank-deficient-cov-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__max-bars-back-function-call-deep-history-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-daily-array-median-percentrank-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-daily-ema26-warmup-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-daily-prev-high-break-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-dual-tf-60-240-rising-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-close-change-baseline-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-close-roll-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-gaps-on-roll-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-rsi14-inside-security-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-sma20-inside-security-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-60-volume-spike-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-confluence-manual-trail-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-confluence-static-bracket-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-htf-weekly-sma-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-roll-state-60-240-d-minimal-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-triple-tf-close-confluence-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__mtf-triple-tf-macd-hist-confluence-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__na-deep-history-int-na-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__na-nz-fixnan-history-chain-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__oca-exit-bracket-internal-cancel-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__oca-multi-bracket-isolation-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__oca-raw-strategy-order-reduce-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-close-all-cancel-all-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-close-immediate-vs-next-bar-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-cross-entry-cancel-same-pass-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-cross-entry-close-same-pass-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-cross-exit-close-same-pass-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-deferred-flip-guaranteed-gap-stops-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-deferred-flip-pooc-cross-bar-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-four-bar-stop-no-close-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-side-same-id-stop-no-cancel-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-both-touch-priority-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-cancel-rotation-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-far-only-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-near-only-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-high-first-path-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-low-first-path-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-tie-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-source-order-long-first-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-dual-stop-source-order-short-first-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-entry-implicit-reversal-exit-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-flip-stop-no-paired-close-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-market-close-fill-basis-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-one-side-four-bar-far-opposite-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-opposite-entry-close-same-pass-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-percent-equity-cash-commission-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-process-on-close-false-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-process-on-close-true-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-range-expansion-pending-stop-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-entry-close-same-bar-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-market-entry-repeat-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-after-flat-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-cross-before-modify-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-minute-zero-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-modification-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-raise-only-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-same-id-stop-window-four-bars-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-stale-stop-after-close-no-cancel-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-stop-cancel-no-regime-close-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-stop-entry-cancel-opposite-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-stop-entry-reversal-grouping-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__order-stop-entry-touch-boundary-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__pyramid-cash-fractional-commission-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__pyramid-close-id-grouping-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__pyramid-deferred-flip-close-all-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__pyramid-flip-stop-pyramiding-2-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__recompute-alma-sar-corr-magnifier-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__recompute-mtf-rsi-macd-bb-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__risk-max-contracts-held-gate-pyramid-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__session-hour-minute-pulse-filter-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__session-ny-spring-forward-dst-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__stats-eventrades-zero-pnl-count-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-accdist-ema-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-bb-kc-squeeze-breakout-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-bb-rsi-mean-reversion-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-cci-threshold-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-chandelier-exit-direction-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-closedtrades-risk-introspection-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-cmo-9-zero-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-cog-10-signal-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-dmi-adx-di-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-donchian-channel-breakout-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-dual-ma-switch-dispatch-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-dual-thrust-open-anchored-range-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-elder-ray-bull-bear-power-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-ema-ribbon-stack-transition-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-engulfing-candle-pattern-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-highestbars-lowestbars-breakout-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-hma-55-close-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-hma-fast-slow-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-inside-bar-engulfing-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-kama-style-efficiency-ratio-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-keltner-channel-break-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-linreg-stdev-channel-revert-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-macd-12-26-9-line-signal-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-macd-histogram-reversal-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-macd-line-gt-signal-continuous-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-map-regime-threshold-lookup-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-median-vs-ema-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-mfi-14-bands-20-80-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-momentum-roc-zero-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-multi-indicator-score-composite-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-nvi-pvi-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-obv-ema-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-percentrank-mean-reversion-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-pivot-array-unshift-pop-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-pivot-atr-stop-target-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-pivot-confirmed-break-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-pivot-point-levels-break-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-pvt-ema-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-range-filter-var-band-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rci-14-zero-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi-bb-self-bands-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi-ema-signal-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi-macd-and-continuous-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi14-bands-30-70-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi14-cross-50-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi14-gt-50-continuous-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-rsi14-gt60-lt45-no-matrix-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-sar-flip-entry-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-sma-152-close-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-sma-dual-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-stdev-sma-expansion-break-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-stoch-slow-k-d-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-stochastic-rsi-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-str-match-regex-filter-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-supertrend-adx-filter-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-supertrend-direction-flip-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-triple-sma-stack-latch-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-tsi-25-13-signal-cross-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-volume-spike-atr-breakout-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-vwma-vs-sma-divergence-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__ta-wpr-14-bands-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__timeframe-main-period-self-adaptive-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-calls-sibling-cumulative-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-default-param-kwargs-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-drives-strategy-entry-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-extra-primitive-args-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-feeds-strategy-exit-prices-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-in-for-loop-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-in-if-else-branch-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-in-switch-arms-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-in-while-loop-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-mutating-self-ref-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-on-array-element-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-reads-strategy-state-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-receives-ta-series-param-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-scalar-return-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-tuple-return-destructure-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-udt-return-from-func-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-uses-history-globals-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-uses-math-funcs-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-uses-na-nz-fixnan-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-var-instance-streak-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-method-windowed-method-chain-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__udt-regime-stack-stress-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__vwap-bands-breakout-1sigma-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/gate-corpus/ok/validation__vwap-bands-mean-reversion-2sigma-01.pine +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_analyzer.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_analyzer_matrix_inference.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_analyzer_ta_return_types.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_drawing_handles.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_fallthrough_guards.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_golden.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_input_getters.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_matrix_typed.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_codegen_string_escape.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_compile_corpus.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_errors.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_extract_inputs.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_glue_smoke.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_import_all.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_input_time_int64.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_int64_reassign_promotion.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_int64_time_storage.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_lexer.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_official_surface.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_security_tf_literal.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_signatures.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_chart_visible_bar_time.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_color_cast.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_const_namespaces.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_dividends_earnings.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_footprint.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_input_color.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_input_source.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_matrix.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_security_adjustment.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_syminfo_gap_fields.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_timeframe_from_seconds.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_varip.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_support_checker_volume_row.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_symbols.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_ta_official_surface.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_transpile_division.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_transpile_enum_order.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_transpile_pf_trace.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_transpile_tr_handle_na.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_transpiler_matrix_kwargs.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_typespec_matrix.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_udt_drawing_field_cleanup.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_unsupported_reporting.py +0 -0
- {pineforge_codegen-0.8.1 → pineforge_codegen-0.9.0}/tests/test_vwap_tuple_unpack.py +0 -0
|
@@ -206,14 +206,15 @@ strategy. The taxonomy:
|
|
|
206
206
|
| Bucket | What |
|
|
207
207
|
| -------------------------------- | -------------------------------------------------------------------- |
|
|
208
208
|
| `HARD_REJECT_FUNC` | Calls with no PineForge semantics at all (e.g. `request.financial`). |
|
|
209
|
-
| `HARD_REJECT_NAMESPACE` | Whole
|
|
210
|
-
| `DIVERGENT_VARS` (warning)
|
|
209
|
+
| `HARD_REJECT_NAMESPACE` | Whole-namespace rejects — currently EMPTY (the old `ticker.*` blanket reject became per-function `HARD_REJECT_FUNC` entries: `ticker.{renko,kagi,linebreak,pointfigure,new,modify}`; `ticker.inherit`/`ticker.standard` pass through, `ticker.heikinashi` allowed for the chart's own symbol). |
|
|
210
|
+
| `DIVERGENT_VARS` (warning) / `DIVERGENT_VARS_ERROR` (reject) | Built-in variables whose value diverges from TV (e.g. `bar_index` warns); the ERROR subset (`last_bar_index` — would silently mis-alias to the CURRENT bar index) is rejected because the backtest would be silently wrong. |
|
|
211
211
|
| `BARSTATE_APPROX_VARS` (warning) | Barstate flags PineForge approximates in batch mode. |
|
|
212
212
|
| `STRATEGY_UNSUPPORTED_PARAMS` | Per-strategy.* call kwargs that codegen drops silently. |
|
|
213
213
|
| `NOT_YET_FUNC` | Implementable but currently no codegen — reject loudly. |
|
|
214
214
|
| `SUPPORTED_*` frozensets | Per-namespace whitelist of names codegen knows how to emit. |
|
|
215
215
|
| `varip` VarDecl check | `varip` declarations rejected outright — batch backtests have no realtime tick state. |
|
|
216
216
|
| TF literal validation | `request.security` / `request.security_lower_tf` `timeframe` string literals validated against Pine v6 format at parse time. |
|
|
217
|
+
| syminfo na-gap warning | `SUPPORTED_SYMINFO` = every `SYMINFO_MEMBER_MAP` key, but members whose emission is `na<T>()` or a `get_syminfo_metadata(...)` lookup (root/pricescale/minmove/mincontract/current_contract/expiration_date/isin/sector/industry + fundamentals/recommendations/target_price_*) form `_SYMINFO_SILENT_GAP_FIELDS` (derived from the emission table, so new na-accept fields can't drift out): every read WARNS that the value is na until a data feed injects it. |
|
|
217
218
|
|
|
218
219
|
|
|
219
220
|
When extending codegen with a new Pine builtin: add to the corresponding
|
|
@@ -230,22 +231,23 @@ These bit us once and are now pinned by `test_compile_smoke.py`'s
|
|
|
230
231
|
you delete or weaken the special case, the test will tell you.
|
|
231
232
|
|
|
232
233
|
1. **`year(time)` / `month(time)` / `dayofmonth` / `dayofweek` /
|
|
233
|
-
`hour(time, tz)` / `minute` / `second` / `weekofyear
|
|
234
|
-
form
|
|
235
|
-
`
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
`
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
against TV exports for
|
|
248
|
-
the chart's TZ at
|
|
234
|
+
`hour(time, tz)` / `minute` / `second` / `weekofyear`** — BOTH the
|
|
235
|
+
function-call form and the bare variable form lower to the engine's
|
|
236
|
+
cached, timezone-aware `pine_<field>(ts_ms, tz)` helpers
|
|
237
|
+
(`session_time.hpp`): the variable form via `BAR_BUILTINS`
|
|
238
|
+
(`pine_year(current_bar_.timestamp, syminfo_.timezone)` …), the
|
|
239
|
+
function form via `visit_call.py` (`pine_hour((int64_t)(ts), tz)`),
|
|
240
|
+
so the two forms agree. The two-arg form uses the explicit tz; the
|
|
241
|
+
one-arg form defaults to `syminfo_.timezone` (engine
|
|
242
|
+
`SymInfo::timezone`, "UTC" by default). The old inline
|
|
243
|
+
`setenv("TZ")+localtime_r` lambda (`tz_time_field_lambda`,
|
|
244
|
+
codegen/tables.py) is no longer emitted — per-call tzset churn
|
|
245
|
+
caused a macOS notifyd IPC storm (KI-35) — and has zero call sites.
|
|
246
|
+
Chart display TZ is a separate engine slot (`chart_timezone_`,
|
|
247
|
+
`strategy_set_chart_timezone`) intentionally NOT consulted by these
|
|
248
|
+
builtins; harnesses validating metrics against TV exports for
|
|
249
|
+
non-UTC charts must still set chart_tz to match the chart's TZ at
|
|
250
|
+
export time.
|
|
249
251
|
2. **Matrix-returning methods** (`inv` / `pinv` / `transpose` / `copy` /
|
|
250
252
|
`submatrix` / `concat` / `diff` / `mult` / `pow` / `eigenvectors` /
|
|
251
253
|
`kron`) live in `MATRIX_RETURNING_METHODS` (`codegen/tables.py`).
|
|
@@ -276,13 +278,21 @@ you delete or weaken the special case, the test will tell you.
|
|
|
276
278
|
PREVIOUS bar's HLC (`_s_high[1]`, `_s_low[1]`, `_s_close[1]`) per
|
|
277
279
|
Pine v6 semantics with `developing=false`.
|
|
278
280
|
6. **`request.security` is strict.** Only `symbol`, `timeframe`,
|
|
279
|
-
`expression`, `gaps`, and `
|
|
280
|
-
|
|
281
|
-
|
|
281
|
+
`expression`, `gaps`, `lookahead`, and `ignore_invalid_symbol` are
|
|
282
|
+
allowed (`ignore_invalid_symbol` is accepted but inert — the symbol is
|
|
283
|
+
always the chart symbol, so no symbol can be invalid). Symbol must
|
|
284
|
+
resolve to the current chart symbol (`syminfo.tickerid` or
|
|
285
|
+
`syminfo.ticker`, incl. first-binding aliases and
|
|
286
|
+
`ticker.inherit/standard/heikinashi(<chart sym>)`). `gaps` and
|
|
287
|
+
`lookahead` must be the literal `barmerge.gaps_*` /
|
|
282
288
|
`barmerge.lookahead_*` member access (codegen does not parse other
|
|
283
|
-
shapes). `barmerge.lookahead_on` is
|
|
284
|
-
|
|
285
|
-
|
|
289
|
+
shapes). `barmerge.lookahead_on` is ACCEPTED with a repaint WARNING —
|
|
290
|
+
engine-supported (first-intrabar publication; script-tf publish gating
|
|
291
|
+
for finer-than-chart targets): see `_check_request_security`'s lookahead
|
|
292
|
+
branch and `test_request_security_lookahead_on_kwarg_warns`. The old
|
|
293
|
+
"hard-rejected" wording here was verified stale against the code on
|
|
294
|
+
2026-07-07 — do not restore it. The `timeframe` argument, when a string
|
|
295
|
+
literal, is validated against the Pine v6 TF format at parse time (PR #3).
|
|
286
296
|
7. `**SUPPORTED_LOG`** gates `log.{info,warning,error}`. Without it,
|
|
287
297
|
typos like `log.foo("x")` previously emitted a dead empty-string
|
|
288
298
|
statement. Don't remove the gate.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pineforge-codegen
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: PineScript v6 to C++ transpiler that targets the pineforge-engine runtime.
|
|
5
5
|
Project-URL: Homepage, https://github.com/pineforge-4pass/pineforge-codegen-oss
|
|
6
6
|
Project-URL: Issues, https://github.com/pineforge-4pass/pineforge-codegen-oss/issues
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.9.0
|
|
@@ -143,6 +143,13 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
143
143
|
self._block_var_seq = 0
|
|
144
144
|
self._ta_counter = 0
|
|
145
145
|
self._fixnan_counter = 0
|
|
146
|
+
# All fixnan member names minted so far (base + clones), for O(1)
|
|
147
|
+
# collision detection when minting a per-call-site fixnan clone.
|
|
148
|
+
self._fixnan_member_names: set[str] = set()
|
|
149
|
+
# Authoritative fixnan clone-name map for collisions: (func, cs_idx)
|
|
150
|
+
# -> {orig_member: cloned_member}. Consumed verbatim by the codegen
|
|
151
|
+
# when the default ``{base}_cs{cs_idx}`` formula would collide.
|
|
152
|
+
self._func_cs_fixnan_clone_names: dict[tuple[str, int], dict[str, str]] = {}
|
|
146
153
|
# Track user-defined function nodes for deferred analysis
|
|
147
154
|
self._func_defs: dict[str, FuncDef] = {}
|
|
148
155
|
# Track user-defined function return types
|
|
@@ -156,6 +163,7 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
156
163
|
# Probe: data/validation/udt-method-probe-20-udt-return-from-func.
|
|
157
164
|
self._func_udt_return_types: dict[str, str] = {}
|
|
158
165
|
self._func_return_type_specs: dict[str, "TypeSpec"] = {}
|
|
166
|
+
self._func_param_type_specs: dict[str, list] = {}
|
|
159
167
|
# Per-function var_members and series_vars (for call-site cloning)
|
|
160
168
|
self._func_var_members: dict[str, list] = {} # func_name -> [(name, PineType, init_str)]
|
|
161
169
|
self._func_series_vars: dict[str, set] = {} # func_name -> set[str]
|
|
@@ -163,9 +171,23 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
163
171
|
self._func_ta_ranges: dict[str, tuple[int, int]] = {} # func_name -> (start, end) indices
|
|
164
172
|
self._func_call_site_count: dict[str, int] = {} # func_name -> count
|
|
165
173
|
self._func_call_cs_map: dict[int, tuple[str, int]] = {} # call_node_id -> (func_name, cs_idx)
|
|
166
|
-
#
|
|
167
|
-
#
|
|
168
|
-
#
|
|
174
|
+
# Textual nested calls whose identity is inherited from the active
|
|
175
|
+
# parent clone rather than assigned a fixed source-level cs index.
|
|
176
|
+
# Kept separately so a second propagation pass (security TF cloning)
|
|
177
|
+
# does not accidentally backfill them as a new cs{N} call site.
|
|
178
|
+
self._func_inherited_call_nodes: set[int] = set()
|
|
179
|
+
# Per-function fixnan site ownership: func_name -> list of fixnan site
|
|
180
|
+
# indices in self._fixnan_sites owned by that function. Mirrors the
|
|
181
|
+
# TA-range slicing but for fixnan state, so per-call-site cloning can
|
|
182
|
+
# mint fresh fixnan members per variant and the codegen dead-code pass
|
|
183
|
+
# can skip fixnan state owned by dead functions.
|
|
184
|
+
self._func_fixnan_indices: dict[str, list[int]] = {}
|
|
185
|
+
# Functions that need per-call-site BODY cloning despite owning no
|
|
186
|
+
# TA/series/var state. The set originated for security-tf
|
|
187
|
+
# monomorphization; it is also the existing emitter contract used by
|
|
188
|
+
# pure wrappers around stateful callees and fixnan-only functions.
|
|
189
|
+
# Security evaluator identity remains independently tracked by each
|
|
190
|
+
# SecurityCallInfo.callsite_idx.
|
|
169
191
|
self._func_security_clone_only: set[str] = set()
|
|
170
192
|
# Authoritative clone-name map: (func_name, cs_idx) -> {orig_member_name:
|
|
171
193
|
# cloned_member_name}. The codegen rebuilds its TA remap from the
|
|
@@ -200,6 +222,13 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
200
222
|
# a TA ctor length with one of the OUTER function's params, so the outer
|
|
201
223
|
# call site can re-substitute (e.g. f_bbwp(_bbwLen) -> f_basisMa(_len)).
|
|
202
224
|
self._enclosing_func_params: list[set[str]] = []
|
|
225
|
+
# Parallel stack of the function NAMES whose param-sets are in
|
|
226
|
+
# ``_enclosing_func_params``. The top of stack (or None at global
|
|
227
|
+
# scope) is the owner of any ORIGINAL ``ta.*`` site minted right now
|
|
228
|
+
# -- recorded on ``TACallSite.owner_func`` so the codegen dead-code
|
|
229
|
+
# pass can tell borrowed clones apart from a dead function's own
|
|
230
|
+
# sites (see contracts.TACallSite.owner_func).
|
|
231
|
+
self._enclosing_func_names: list[str] = []
|
|
203
232
|
# Set of TA-site indices a nested user-func call rewrote in terms of the
|
|
204
233
|
# current enclosing function's params (None when not inside a FuncDef body).
|
|
205
234
|
self._nested_ta_touched: set | None = None
|
|
@@ -302,6 +331,8 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
302
331
|
var_members=self._var_members,
|
|
303
332
|
func_infos=self._func_infos,
|
|
304
333
|
fixnan_sites=self._fixnan_sites,
|
|
334
|
+
func_fixnan_indices=self._func_fixnan_indices,
|
|
335
|
+
func_cs_fixnan_clone_names=self._func_cs_fixnan_clone_names,
|
|
305
336
|
strategy_params=self._strategy_params,
|
|
306
337
|
diagnostics=self._diagnostics,
|
|
307
338
|
filename=self._filename,
|
|
@@ -440,40 +471,274 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
440
471
|
return out
|
|
441
472
|
|
|
442
473
|
def _propagate_call_site_counts(self) -> None:
|
|
443
|
-
"""Propagate
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
474
|
+
"""Propagate stateful UDF identity through complete call paths.
|
|
475
|
+
|
|
476
|
+
A UDF is stateful when it owns series/``var`` state, TA state, or
|
|
477
|
+
``fixnan`` state, and every pure wrapper that reaches such a UDF is
|
|
478
|
+
stateful transitively. Give each wrapper's textual calls stable cs
|
|
479
|
+
identities, then inherit a multi-call-site parent's count down to its
|
|
480
|
+
stateful callees. Any inherited TA/fixnan variants are materialized
|
|
481
|
+
immediately; exporting a count without the corresponding members would
|
|
482
|
+
make codegen reference undeclared or shared state.
|
|
449
483
|
"""
|
|
450
484
|
from pineforge_codegen.ast_nodes import FuncCall, FuncDef, Identifier
|
|
451
485
|
|
|
452
|
-
# Collect all user function definitions from AST
|
|
453
486
|
func_defs: dict[str, FuncDef] = {}
|
|
454
487
|
for stmt in self._ast.body:
|
|
455
488
|
if isinstance(stmt, FuncDef):
|
|
456
489
|
func_defs[stmt.name] = stmt
|
|
457
490
|
|
|
458
|
-
#
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
491
|
+
# UDT methods participate in the same stateful call graph as plain
|
|
492
|
+
# UDFs. Their analyzer identity is ``Type.method`` while FuncInfo.node
|
|
493
|
+
# carries the synthetic FuncDef used by codegen.
|
|
494
|
+
func_info_by_name = {fi.name: fi for fi in self._func_infos}
|
|
495
|
+
for fi in self._func_infos:
|
|
496
|
+
if getattr(fi, "is_udt_method", False) and fi.node is not None:
|
|
497
|
+
func_defs.setdefault(fi.name, fi.node)
|
|
498
|
+
|
|
499
|
+
# Preserve call-node identity as well as the callee name: late clone
|
|
500
|
+
# materialization needs the textual call's argument mapping to resolve
|
|
501
|
+
# parameterized TA constructor lengths.
|
|
502
|
+
def _resolved_user_call_name(call: FuncCall, owner: str | None) -> str | None:
|
|
503
|
+
if isinstance(call.callee, Identifier):
|
|
504
|
+
return call.callee.name if call.callee.name in func_defs else None
|
|
505
|
+
if not isinstance(call.callee, MemberAccess):
|
|
506
|
+
return None
|
|
507
|
+
|
|
508
|
+
recv = call.callee.object
|
|
509
|
+
method = call.callee.member
|
|
510
|
+
udt_name: str | None = None
|
|
511
|
+
if isinstance(recv, Identifier):
|
|
512
|
+
udt_name = self._udt_var_types.get(recv.name)
|
|
513
|
+
owner_info = func_info_by_name.get(owner or "")
|
|
514
|
+
if udt_name is None and owner_info is not None \
|
|
515
|
+
and owner_info.node is not None:
|
|
516
|
+
if (getattr(owner_info, "is_udt_method", False)
|
|
517
|
+
and owner_info.node.params
|
|
518
|
+
and recv.name == owner_info.node.params[0]):
|
|
519
|
+
udt_name = owner_info.udt_type_name
|
|
520
|
+
elif recv.name in owner_info.node.params:
|
|
521
|
+
param_idx = owner_info.node.params.index(recv.name)
|
|
522
|
+
specs = getattr(owner_info, "param_type_specs", []) or []
|
|
523
|
+
spec = specs[param_idx] if param_idx < len(specs) else None
|
|
524
|
+
if spec is not None and spec.kind == "udt":
|
|
525
|
+
udt_name = spec.name
|
|
526
|
+
if udt_name is None:
|
|
527
|
+
spec = self._type_spec_from_expr(recv)
|
|
528
|
+
if spec is not None and spec.kind == "udt":
|
|
529
|
+
udt_name = spec.name
|
|
530
|
+
key = f"{udt_name}.{method}" if udt_name else ""
|
|
531
|
+
return key if key in func_defs else None
|
|
532
|
+
|
|
533
|
+
def _find_calls(node, known_funcs: set[str],
|
|
534
|
+
owner: str | None = None,
|
|
535
|
+
seen: set[int] | None = None) -> list[tuple[str, FuncCall]]:
|
|
536
|
+
calls: list[tuple[str, FuncCall]] = []
|
|
537
|
+
if node is None:
|
|
538
|
+
return calls
|
|
539
|
+
if seen is None:
|
|
540
|
+
seen = set()
|
|
541
|
+
if isinstance(node, (list, tuple, dict)) or hasattr(node, "__dict__"):
|
|
542
|
+
node_id = id(node)
|
|
543
|
+
if node_id in seen:
|
|
544
|
+
return calls
|
|
545
|
+
seen.add(node_id)
|
|
546
|
+
if isinstance(node, (list, tuple)):
|
|
547
|
+
for item in node:
|
|
548
|
+
calls.extend(_find_calls(item, known_funcs, owner, seen))
|
|
549
|
+
return calls
|
|
550
|
+
if isinstance(node, dict):
|
|
551
|
+
for item in node.values():
|
|
552
|
+
calls.extend(_find_calls(item, known_funcs, owner, seen))
|
|
553
|
+
return calls
|
|
554
|
+
if not hasattr(node, "__dict__"):
|
|
555
|
+
return calls
|
|
556
|
+
if isinstance(node, FuncCall):
|
|
557
|
+
resolved = _resolved_user_call_name(node, owner)
|
|
558
|
+
if resolved in known_funcs:
|
|
559
|
+
calls.append((resolved, node))
|
|
464
560
|
for attr_val in vars(node).values():
|
|
465
|
-
|
|
466
|
-
for item in attr_val:
|
|
467
|
-
if hasattr(item, '__dict__'):
|
|
468
|
-
calls |= _find_calls(item, known_funcs)
|
|
469
|
-
elif hasattr(attr_val, '__dict__'):
|
|
470
|
-
calls |= _find_calls(attr_val, known_funcs)
|
|
561
|
+
calls.extend(_find_calls(attr_val, known_funcs, owner, seen))
|
|
471
562
|
return calls
|
|
472
563
|
|
|
473
564
|
known_func_names = set(func_defs.keys())
|
|
565
|
+
calls_by_parent = {
|
|
566
|
+
name: _find_calls(func_def, known_func_names, name)
|
|
567
|
+
for name, func_def in func_defs.items()
|
|
568
|
+
}
|
|
569
|
+
calls_by_callee: dict[str, list[FuncCall]] = {
|
|
570
|
+
name: [] for name in known_func_names
|
|
571
|
+
}
|
|
572
|
+
# Preserve source order across definitions and top-level statements.
|
|
573
|
+
# Method bodies use their ``Type.method`` owner so ``self.sibling()``
|
|
574
|
+
# resolves without relying on a now-exited symbol-table scope.
|
|
575
|
+
for stmt in self._ast.body:
|
|
576
|
+
if isinstance(stmt, FuncDef):
|
|
577
|
+
owner = stmt.name
|
|
578
|
+
elif isinstance(stmt, MethodDef):
|
|
579
|
+
owner = f"{stmt.type_name}.{stmt.name}"
|
|
580
|
+
else:
|
|
581
|
+
owner = None
|
|
582
|
+
for callee, call in _find_calls(stmt, known_func_names, owner):
|
|
583
|
+
calls_by_callee.setdefault(callee, []).append(call)
|
|
584
|
+
|
|
585
|
+
# Codegen synthesizes a Series buffer for two expression shapes that
|
|
586
|
+
# do not appear in ``_func_series_vars`` themselves:
|
|
587
|
+
#
|
|
588
|
+
# * a call result read through history, e.g. ``f()[1]``;
|
|
589
|
+
# * a scalar expression bridged into a UDF series parameter, e.g.
|
|
590
|
+
# ``history(close + open)`` where ``history(src) => src[1]``.
|
|
591
|
+
#
|
|
592
|
+
# A buffer is mutable per-call-site state just like TA/fixnan. Mark
|
|
593
|
+
# its lexical owner stateful before the normal call-path closure so a
|
|
594
|
+
# function invoked from two source sites receives two emitted bodies
|
|
595
|
+
# (and therefore two independent generated buffer members). Without
|
|
596
|
+
# this, moving the old function-local static into a class member would
|
|
597
|
+
# accidentally merge both Pine call sites into one history stream.
|
|
598
|
+
def _actual_arg(call: FuncCall, param_name: str, param_idx: int):
|
|
599
|
+
if param_idx < len(call.args):
|
|
600
|
+
return call.args[param_idx]
|
|
601
|
+
return call.kwargs.get(param_name)
|
|
602
|
+
|
|
603
|
+
def _needs_scalar_series_bridge(call: FuncCall) -> bool:
|
|
604
|
+
if not isinstance(call.callee, Identifier):
|
|
605
|
+
return False
|
|
606
|
+
callee = call.callee.name
|
|
607
|
+
fi = func_info_by_name.get(callee)
|
|
608
|
+
if fi is None or fi.node is None:
|
|
609
|
+
return False
|
|
610
|
+
series_params = self._func_series_vars.get(callee, set())
|
|
611
|
+
if not series_params:
|
|
612
|
+
return False
|
|
613
|
+
direct_bar_series = {
|
|
614
|
+
"open", "high", "low", "close", "volume",
|
|
615
|
+
"hl2", "hlc3", "ohlc4",
|
|
616
|
+
}
|
|
617
|
+
for idx, param_name in enumerate(fi.node.params):
|
|
618
|
+
if param_name not in series_params:
|
|
619
|
+
continue
|
|
620
|
+
arg = _actual_arg(call, param_name, idx)
|
|
621
|
+
if arg is None:
|
|
622
|
+
continue
|
|
623
|
+
if isinstance(arg, Identifier) and (
|
|
624
|
+
arg.name in direct_bar_series or arg.name in self._series_vars
|
|
625
|
+
):
|
|
626
|
+
continue
|
|
627
|
+
return True
|
|
628
|
+
return False
|
|
629
|
+
|
|
630
|
+
def _has_synthetic_history_state(
|
|
631
|
+
node, seen: set[int] | None = None) -> bool:
|
|
632
|
+
if node is None:
|
|
633
|
+
return False
|
|
634
|
+
if seen is None:
|
|
635
|
+
seen = set()
|
|
636
|
+
if isinstance(node, (list, tuple, dict)) or hasattr(node, "__dict__"):
|
|
637
|
+
node_id = id(node)
|
|
638
|
+
if node_id in seen:
|
|
639
|
+
return False
|
|
640
|
+
seen.add(node_id)
|
|
641
|
+
if isinstance(node, (list, tuple)):
|
|
642
|
+
return any(
|
|
643
|
+
_has_synthetic_history_state(item, seen) for item in node
|
|
644
|
+
)
|
|
645
|
+
if isinstance(node, dict):
|
|
646
|
+
return any(
|
|
647
|
+
_has_synthetic_history_state(item, seen)
|
|
648
|
+
for item in node.values()
|
|
649
|
+
)
|
|
650
|
+
if not hasattr(node, "__dict__"):
|
|
651
|
+
return False
|
|
652
|
+
if (isinstance(node, Subscript)
|
|
653
|
+
and isinstance(node.object, FuncCall)):
|
|
654
|
+
return True
|
|
655
|
+
if isinstance(node, FuncCall) and _needs_scalar_series_bridge(node):
|
|
656
|
+
return True
|
|
657
|
+
return any(
|
|
658
|
+
_has_synthetic_history_state(value, seen)
|
|
659
|
+
for value in vars(node).values()
|
|
660
|
+
)
|
|
474
661
|
|
|
475
|
-
|
|
476
|
-
|
|
662
|
+
synthetic_history_stateful = {
|
|
663
|
+
name for name, func_def in func_defs.items()
|
|
664
|
+
if _has_synthetic_history_state(func_def)
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
# request.security owns a separate evaluator context and already
|
|
668
|
+
# materializes/remaps its embedded TA state per SecurityCallInfo. Do
|
|
669
|
+
# not thread ordinary UDF clone indices through a function used as a
|
|
670
|
+
# security expression (or through the containing wrapper); doing so
|
|
671
|
+
# would double-clone evaluator state and disturb expression identity.
|
|
672
|
+
security_boundary_funcs: set[str] = set()
|
|
673
|
+
for sec in getattr(self, "_security_calls", []) or []:
|
|
674
|
+
containing = getattr(sec, "containing_func", "") or ""
|
|
675
|
+
if containing:
|
|
676
|
+
security_boundary_funcs.add(containing)
|
|
677
|
+
expression = getattr(sec, "expression", None)
|
|
678
|
+
if expression is not None:
|
|
679
|
+
security_boundary_funcs.update(
|
|
680
|
+
sub for sub, _ in _find_calls(
|
|
681
|
+
expression, known_func_names, containing or None
|
|
682
|
+
)
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
# Canonical direct-state predicate. TA-only and fixnan-only helpers
|
|
686
|
+
# are just as stateful as functions carrying an explicit series/var.
|
|
687
|
+
stateful = (
|
|
688
|
+
set(self._func_series_vars)
|
|
689
|
+
| set(self._func_var_members)
|
|
690
|
+
| set(self._func_ta_ranges)
|
|
691
|
+
| set(self._func_fixnan_indices)
|
|
692
|
+
| synthetic_history_stateful
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
# Close upward over the call graph so a pure A -> B -> stateful C chain
|
|
696
|
+
# receives variants at every level. The existing clone-only emitter
|
|
697
|
+
# marker is intentionally separate from request.security evaluator
|
|
698
|
+
# identity, so ordinary security calls remain shared unless the
|
|
699
|
+
# dedicated timeframe-monomorphization pass clones them.
|
|
700
|
+
changed = True
|
|
701
|
+
while changed:
|
|
702
|
+
changed = False
|
|
703
|
+
for fname, calls in calls_by_parent.items():
|
|
704
|
+
if fname in stateful:
|
|
705
|
+
continue
|
|
706
|
+
if any(sub in stateful for sub, _ in calls):
|
|
707
|
+
stateful.add(fname)
|
|
708
|
+
changed = True
|
|
709
|
+
|
|
710
|
+
# Direct fixnan-only functions and pure transitive wrappers own no
|
|
711
|
+
# TA/series member that would trip the emitter's ordinary body-clone
|
|
712
|
+
# gate. Reuse its established body-only clone marker; this does not
|
|
713
|
+
# create or renumber any SecurityCallInfo.
|
|
714
|
+
for fname in sorted(stateful):
|
|
715
|
+
if (fname not in self._func_ta_ranges
|
|
716
|
+
and fname not in self._func_series_vars
|
|
717
|
+
and fname not in self._func_var_members):
|
|
718
|
+
self._func_security_clone_only.add(fname)
|
|
719
|
+
|
|
720
|
+
# The initial visitor only numbers directly-stateful callees. Backfill
|
|
721
|
+
# stable identities for newly discovered pure wrappers without
|
|
722
|
+
# disturbing any indices already assigned by the visitor or security
|
|
723
|
+
# monomorphization.
|
|
724
|
+
for fname in sorted(stateful):
|
|
725
|
+
calls = calls_by_callee.get(fname, [])
|
|
726
|
+
current = self._func_call_site_count.get(fname, 0)
|
|
727
|
+
next_idx = current
|
|
728
|
+
for call in calls:
|
|
729
|
+
if id(call) in self._func_inherited_call_nodes:
|
|
730
|
+
continue
|
|
731
|
+
existing = self._func_call_cs_map.get(id(call))
|
|
732
|
+
if existing is not None and existing[0] == fname:
|
|
733
|
+
next_idx = max(next_idx, existing[1] + 1)
|
|
734
|
+
continue
|
|
735
|
+
self._func_call_cs_map[id(call)] = (fname, next_idx)
|
|
736
|
+
next_idx += 1
|
|
737
|
+
if next_idx > current:
|
|
738
|
+
self._func_call_site_count[fname] = next_idx
|
|
739
|
+
|
|
740
|
+
# Inherit each multi-call-site parent's index space down the full path.
|
|
741
|
+
# Re-run to a fixed point for A -> B -> C chains.
|
|
477
742
|
changed = True
|
|
478
743
|
while changed:
|
|
479
744
|
changed = False
|
|
@@ -482,14 +747,32 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
482
747
|
continue
|
|
483
748
|
if fname not in func_defs:
|
|
484
749
|
continue
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
if not has_state:
|
|
750
|
+
if fname in security_boundary_funcs:
|
|
751
|
+
continue
|
|
752
|
+
for sub, call_node in calls_by_parent.get(fname, []):
|
|
753
|
+
if sub not in stateful:
|
|
490
754
|
continue
|
|
491
755
|
current = self._func_call_site_count.get(sub, 0)
|
|
492
756
|
if current < count:
|
|
757
|
+
# One textual nested call is not an independent cs0
|
|
758
|
+
# path: it inherits the active parent clone index.
|
|
759
|
+
# Remove the visitor's provisional cs0 map so codegen's
|
|
760
|
+
# established active-index fallback dispatches
|
|
761
|
+
# F_csK -> G_csK. Keeping the map would make the
|
|
762
|
+
# context-sensitive instance pre-pass pin every parent
|
|
763
|
+
# clone to G_cs0 before that fallback can run.
|
|
764
|
+
if current == 1:
|
|
765
|
+
cs_info = self._func_call_cs_map.get(id(call_node))
|
|
766
|
+
if cs_info == (sub, 0):
|
|
767
|
+
self._func_call_cs_map.pop(id(call_node), None)
|
|
768
|
+
self._func_inherited_call_nodes.add(id(call_node))
|
|
769
|
+
for cs_idx in range(current, count):
|
|
770
|
+
self._materialize_user_func_call_site_state(
|
|
771
|
+
sub,
|
|
772
|
+
cs_idx,
|
|
773
|
+
call_node,
|
|
774
|
+
reuse_existing_owner=fname,
|
|
775
|
+
)
|
|
493
776
|
self._func_call_site_count[sub] = count
|
|
494
777
|
changed = True
|
|
495
778
|
|
|
@@ -1162,6 +1445,7 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1162
1445
|
old_global = self._global_scope
|
|
1163
1446
|
self._global_scope = False
|
|
1164
1447
|
self._enclosing_func_params.append(set(node.params))
|
|
1448
|
+
self._enclosing_func_names.append(node.name)
|
|
1165
1449
|
self._nested_ta_touched = set()
|
|
1166
1450
|
try:
|
|
1167
1451
|
for stmt in node.body:
|
|
@@ -1169,6 +1453,7 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1169
1453
|
finally:
|
|
1170
1454
|
self._global_scope = old_global
|
|
1171
1455
|
self._enclosing_func_params.pop()
|
|
1456
|
+
self._enclosing_func_names.pop()
|
|
1172
1457
|
nested_touched = self._nested_ta_touched
|
|
1173
1458
|
self._nested_ta_touched = None
|
|
1174
1459
|
|
|
@@ -1184,6 +1469,16 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1184
1469
|
if hi > lo:
|
|
1185
1470
|
self._func_ta_ranges[node.name] = (lo, hi)
|
|
1186
1471
|
|
|
1472
|
+
inferred_param_specs = self._param_type_specs_from_def(node)
|
|
1473
|
+
for i, param in enumerate(node.params):
|
|
1474
|
+
if i < len(inferred_param_specs) and inferred_param_specs[i] is not None:
|
|
1475
|
+
continue
|
|
1476
|
+
sym = self._symbols.resolve(param)
|
|
1477
|
+
spec = getattr(sym, "type_spec", None) if sym is not None else None
|
|
1478
|
+
if spec is not None and i < len(inferred_param_specs):
|
|
1479
|
+
inferred_param_specs[i] = spec
|
|
1480
|
+
self._func_param_type_specs[node.name] = inferred_param_specs
|
|
1481
|
+
|
|
1187
1482
|
self._symbols.exit_scope()
|
|
1188
1483
|
|
|
1189
1484
|
# Detect if function returns a tuple (last stmt is TupleLiteral)
|
|
@@ -1511,6 +1806,20 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1511
1806
|
|
|
1512
1807
|
# String concatenation: if either side is STRING, result is STRING
|
|
1513
1808
|
if left_type == PineType.STRING or right_type == PineType.STRING:
|
|
1809
|
+
def _mark_string_param(expr) -> None:
|
|
1810
|
+
if not isinstance(expr, Identifier):
|
|
1811
|
+
return
|
|
1812
|
+
sym = self._symbols.resolve(expr.name)
|
|
1813
|
+
if sym is None or not (sym.scope or "").startswith("func_"):
|
|
1814
|
+
return
|
|
1815
|
+
if sym.pine_type == PineType.UNKNOWN:
|
|
1816
|
+
sym.pine_type = PineType.STRING
|
|
1817
|
+
sym.type_spec = TypeSpec.primitive("string")
|
|
1818
|
+
|
|
1819
|
+
if left_type == PineType.STRING:
|
|
1820
|
+
_mark_string_param(node.right)
|
|
1821
|
+
if right_type == PineType.STRING:
|
|
1822
|
+
_mark_string_param(node.left)
|
|
1514
1823
|
return PineType.STRING
|
|
1515
1824
|
|
|
1516
1825
|
# Arithmetic: promote to FLOAT if either side is FLOAT
|
|
@@ -1583,11 +1892,14 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1583
1892
|
if isinstance(obj, Identifier) and obj.name == "str":
|
|
1584
1893
|
for arg in node.args:
|
|
1585
1894
|
self._visit(arg)
|
|
1586
|
-
# Most str.* return a string, but
|
|
1587
|
-
#
|
|
1895
|
+
# Most str.* return a string, but predicates and index helpers
|
|
1896
|
+
# are scalar. Keep this aligned with signatures.py and the C++
|
|
1897
|
+
# emitter's _infer_type path.
|
|
1898
|
+
if member in ("contains", "startswith", "endswith"):
|
|
1899
|
+
return PineType.BOOL
|
|
1588
1900
|
if member == "tonumber":
|
|
1589
1901
|
return PineType.FLOAT
|
|
1590
|
-
if member
|
|
1902
|
+
if member in ("length", "pos"):
|
|
1591
1903
|
return PineType.INT
|
|
1592
1904
|
return PineType.STRING
|
|
1593
1905
|
|
|
@@ -1812,9 +2124,11 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1812
2124
|
|
|
1813
2125
|
# syminfo.*
|
|
1814
2126
|
if ns == "syminfo":
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
2127
|
+
from .. import signatures as _pf_sigs
|
|
2128
|
+
return _pf_sigs.SYMINFO_VARIABLES.get(
|
|
2129
|
+
f"syminfo.{node.member}",
|
|
2130
|
+
PineType.STRING,
|
|
2131
|
+
)
|
|
1818
2132
|
|
|
1819
2133
|
# color.* constants
|
|
1820
2134
|
if ns == "color":
|
|
@@ -1873,7 +2187,7 @@ class Analyzer(CallHandlers, DiagnosticsHelper, TypeHelper):
|
|
|
1873
2187
|
|
|
1874
2188
|
# text.* constants (align_left, align_right, etc.)
|
|
1875
2189
|
if ns == "text":
|
|
1876
|
-
return PineType.
|
|
2190
|
+
return PineType.STRING
|
|
1877
2191
|
|
|
1878
2192
|
# extend.* constants (left, right, both, none)
|
|
1879
2193
|
if ns == "extend":
|