pineforge-codegen 0.7.6__tar.gz → 0.8.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.

Potentially problematic release.


This version of pineforge-codegen might be problematic. Click here for more details.

Files changed (391) hide show
  1. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/PKG-INFO +1 -1
  2. pineforge_codegen-0.8.0/VERSION +1 -0
  3. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/base.py +23 -7
  4. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/emit_top.py +45 -3
  5. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/helpers.py +26 -1
  6. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/input.py +25 -2
  7. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/security.py +31 -0
  8. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/ta.py +4 -1
  9. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/tables.py +4 -4
  10. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/types.py +14 -2
  11. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/visit_call.py +12 -0
  12. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/visit_expr.py +37 -3
  13. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/visit_stmt.py +27 -12
  14. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/lexer.py +68 -3
  15. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/parser.py +64 -40
  16. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/support_checker.py +80 -20
  17. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/_compile.py +69 -1
  18. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/golden/matrix_eigen_pca.cpp +1 -1
  19. pineforge_codegen-0.8.0/tests/test_codegen_drawing_handles.py +33 -0
  20. pineforge_codegen-0.8.0/tests/test_codegen_string_escape.py +25 -0
  21. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_official_surface.py +7 -7
  22. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_parser.py +56 -0
  23. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker.py +14 -6
  24. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_chart_visible_bar_time.py +6 -3
  25. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_color_cast.py +6 -3
  26. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_const_namespaces.py +11 -7
  27. pineforge_codegen-0.7.6/VERSION +0 -1
  28. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.github/dependabot.yml +0 -0
  29. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.github/workflows/gate.yml +0 -0
  30. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.github/workflows/publish-pyodide.yml +0 -0
  31. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.github/workflows/release.yml +0 -0
  32. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.github/workflows/test.yml +0 -0
  33. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/.gitignore +0 -0
  34. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/CLAUDE.md +0 -0
  35. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/LEGAL.md +0 -0
  36. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/LICENSE +0 -0
  37. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/PYODIDE_TARGET +0 -0
  38. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/README.md +0 -0
  39. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/docs/codegen-coverage-gaps.md +0 -0
  40. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/gate/compare.mjs +0 -0
  41. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/gate/glue.py +0 -0
  42. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/gate/oracle.py +0 -0
  43. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/gate/run-gate.mjs +0 -0
  44. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/gate/selftest.mjs +0 -0
  45. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/npm/README.md +0 -0
  46. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/npm/index.mjs +0 -0
  47. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/npm/package.json +0 -0
  48. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/package-lock.json +0 -0
  49. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/package.json +0 -0
  50. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/__init__.py +0 -0
  51. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/__init__.py +0 -0
  52. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/base.py +0 -0
  53. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/call_handlers.py +0 -0
  54. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/contracts.py +0 -0
  55. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/diagnostics.py +0 -0
  56. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/tables.py +0 -0
  57. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/analyzer/types.py +0 -0
  58. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/ast_nodes.py +0 -0
  59. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/__init__.py +0 -0
  60. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/codegen/helpers_syminfo.py +0 -0
  61. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/errors.py +0 -0
  62. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/pragmas.py +0 -0
  63. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/signatures.py +0 -0
  64. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/symbols.py +0 -0
  65. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/tokens.py +0 -0
  66. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pineforge_codegen/tv_input_choices.py +0 -0
  67. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/pyproject.toml +0 -0
  68. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/scripts/build-npm-package.mjs +0 -0
  69. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/scripts/dump-tables.py +0 -0
  70. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/scripts/worker-template.mjs +0 -0
  71. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/__init__.py +0 -0
  72. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/const_ns_plot_style_free.pine +0 -0
  73. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/const_ns_shape_free.pine +0 -0
  74. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/divergent_last_bar_index.pine +0 -0
  75. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/divergent_time_close.pine +0 -0
  76. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/export_func.pine +0 -0
  77. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/footprint_new.pine +0 -0
  78. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/hard_reject_dividends.pine +0 -0
  79. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/matrix_unknown_elem.pine +0 -0
  80. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/multi_error_one_line.pine +0 -0
  81. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/sec_tf_invalid.pine +0 -0
  82. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_color.pine +0 -0
  83. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_math.pine +0 -0
  84. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_str.pine +0 -0
  85. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_strategy_fn.pine +0 -0
  86. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_syminfo.pine +0 -0
  87. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/err/unknown_ta.pine +0 -0
  88. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine +0 -0
  89. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine +0 -0
  90. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine +0 -0
  91. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine +0 -0
  92. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine +0 -0
  93. {pineforge_codegen-0.7.6/tests/gate-corpus/err → pineforge_codegen-0.8.0/tests/gate-corpus/ok}/chart_bg_color.pine +0 -0
  94. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine +0 -0
  95. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine +0 -0
  96. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine +0 -0
  97. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine +0 -0
  98. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/tutorial__macd__strategy.pine +0 -0
  99. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/tutorial__mtf__strategy_htf.pine +0 -0
  100. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/tutorial__mtf__strategy_ltf.pine +0 -0
  101. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine +0 -0
  102. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine +0 -0
  103. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-parity-choch-bos-isolator-01.pine +0 -0
  104. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-parity-edge-margin-50-pct-01.pine +0 -0
  105. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-parity-percent-of-equity-sizing-01.pine +0 -0
  106. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-parity-small-equity-fraction-01.pine +0 -0
  107. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-parity-stop-limit-timing-01.pine +0 -0
  108. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__analyzer-self-test-multi-mode-01.pine +0 -0
  109. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__anomaly-equity-mirror-strategy-equity-01.pine +0 -0
  110. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-off-01b.pine +0 -0
  111. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-on-01a.pine +0 -0
  112. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-atr-trail-series-int-points-01.pine +0 -0
  113. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-atr-trailing-stop-state-01.pine +0 -0
  114. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-entry-exit-same-pass-attach-01.pine +0 -0
  115. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-exit-stop-limit-trail-same-bar-01.pine +0 -0
  116. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-exit-three-way-set-once-entry-01.pine +0 -0
  117. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-exit-tp-sl-fixed-01.pine +0 -0
  118. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-narrow-stop-limit-with-trail8-01.pine +0 -0
  119. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-partial-exit-qty-percent-01.pine +0 -0
  120. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-same-id-exit-replace-01.pine +0 -0
  121. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-tp-sl-oca-reduce-isolate-01.pine +0 -0
  122. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-trail-points-no-offset-explicit-01.pine +0 -0
  123. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-trail-points-with-offset-only-01.pine +0 -0
  124. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__bracket-trailing-activation-offset-path-01.pine +0 -0
  125. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__cap-max-intraday-filled-orders-isolate-01.pine +0 -0
  126. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__cap-risk-gates-allow-max-intraday-01.pine +0 -0
  127. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-4emarsi-integration-01.pine +0 -0
  128. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-4emarsi-quad-ema-stack-01.pine +0 -0
  129. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-4emarsi-rsi-pullback-latch-01.pine +0 -0
  130. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-4emarsi-session-window-nbar-exit-01.pine +0 -0
  131. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-boscurv-integration-01.pine +0 -0
  132. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-boscurv-linreg-slope-channel-01.pine +0 -0
  133. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-boscurv-pivot-bos-trigger-01.pine +0 -0
  134. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-bracket-cap-range-pending-stop-01.pine +0 -0
  135. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-adx-regime-classify-01.pine +0 -0
  136. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-bb-kc-squeeze-release-01.pine +0 -0
  137. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-cooldown-daily-cap-01.pine +0 -0
  138. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-equity-feedback-sizing-01.pine +0 -0
  139. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-integration-01.pine +0 -0
  140. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-pivot-liquidity-sweep-01.pine +0 -0
  141. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-pressure-gauge-01.pine +0 -0
  142. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-rsi-macd-momentum-01.pine +0 -0
  143. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-ies-three-ema-bias-score-01.pine +0 -0
  144. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kanuck-calc-on-every-tick-01.pine +0 -0
  145. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kanuck-integration-01.pine +0 -0
  146. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kanuck-kama-state-recurrence-01.pine +0 -0
  147. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kanuck-max-bars-back-500-01.pine +0 -0
  148. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kkb-ema-atr-breakout-band-01.pine +0 -0
  149. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kkb-integration-01.pine +0 -0
  150. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kkb-kalman-filter-1d-01.pine +0 -0
  151. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-kkb-margin-100-pct-01.pine +0 -0
  152. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-liqsweep-integration-01.pine +0 -0
  153. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-liqsweep-pivot-hh-ll-01.pine +0 -0
  154. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-liqsweep-wait-one-continuation-01.pine +0 -0
  155. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-liqsweep-wick-pierce-close-back-01.pine +0 -0
  156. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-marketshift-integration-01.pine +0 -0
  157. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-marketshift-pivot-state-machine-01.pine +0 -0
  158. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-marketshift-rolling-highest-lowest-01.pine +0 -0
  159. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-marketshift-state-edge-detector-01.pine +0 -0
  160. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-scalping-fast-ma-cross-trigger-01.pine +0 -0
  161. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-scalping-integration-01.pine +0 -0
  162. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-scalping-tight-tp-sl-points-01.pine +0 -0
  163. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-trendmaster-integration-01.pine +0 -0
  164. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-trendmaster-line-new-projection-01.pine +0 -0
  165. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-trendmaster-pivot-anchored-bracket-01.pine +0 -0
  166. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-trendmaster-three-tier-ema-state-01.pine +0 -0
  167. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-trendmaster-trend-momentum-structure-gate-01.pine +0 -0
  168. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-cumulative-volume-delta-01.pine +0 -0
  169. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-fvg-active-zones-01.pine +0 -0
  170. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-integration-01.pine +0 -0
  171. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-manual-adx-regime-01.pine +0 -0
  172. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-pivot-strength-5-01.pine +0 -0
  173. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-rsi-smooth-divergence-01.pine +0 -0
  174. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-session-tz-newyork-01.pine +0 -0
  175. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-vcp-vol-zscore-anomaly-01.pine +0 -0
  176. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-alert-templates-01.pine +0 -0
  177. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-explicit-reverse-01.pine +0 -0
  178. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__composite-wunderscalper-integration-01.pine +0 -0
  179. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__input-source-runtime-override-high-01.pine +0 -0
  180. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__input-source-subscript-hl2-01.pine +0 -0
  181. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ltf-bool-array-bull-majority-01.pine +0 -0
  182. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ltf-numeric-float-ratio15-01.pine +0 -0
  183. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-01.pine +0 -0
  184. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-rsi-cross-08a.pine +0 -0
  185. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__magnifier-tick-dist-volume-weighted-on-01.pine +0 -0
  186. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-explicit-utc-tz-01.pine +0 -0
  187. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-no-transpose-01.pine +0 -0
  188. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-bool-mask-transpose-roundtrip-01.pine +0 -0
  189. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-bool-regime-mask-24x7-01.pine +0 -0
  190. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-covariance-eigen-pca-01.pine +0 -0
  191. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__matrix-eigen-rank-deficient-cov-01.pine +0 -0
  192. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__max-bars-back-function-call-deep-history-01.pine +0 -0
  193. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-daily-array-median-percentrank-01.pine +0 -0
  194. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-daily-ema26-warmup-01.pine +0 -0
  195. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-daily-prev-high-break-01.pine +0 -0
  196. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-dual-tf-60-240-rising-01.pine +0 -0
  197. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-close-change-baseline-01.pine +0 -0
  198. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-close-roll-01.pine +0 -0
  199. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-gaps-on-roll-01.pine +0 -0
  200. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-rsi14-inside-security-01.pine +0 -0
  201. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-sma20-inside-security-01.pine +0 -0
  202. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-60-volume-spike-01.pine +0 -0
  203. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-confluence-manual-trail-01.pine +0 -0
  204. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-confluence-static-bracket-01.pine +0 -0
  205. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-htf-weekly-sma-cross-01.pine +0 -0
  206. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-roll-state-60-240-d-minimal-01.pine +0 -0
  207. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-triple-tf-close-confluence-01.pine +0 -0
  208. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__mtf-triple-tf-macd-hist-confluence-01.pine +0 -0
  209. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__na-deep-history-int-na-01.pine +0 -0
  210. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__na-nz-fixnan-history-chain-01.pine +0 -0
  211. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__oca-exit-bracket-internal-cancel-01.pine +0 -0
  212. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__oca-multi-bracket-isolation-01.pine +0 -0
  213. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__oca-raw-strategy-order-reduce-01.pine +0 -0
  214. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-close-all-cancel-all-01.pine +0 -0
  215. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-close-immediate-vs-next-bar-01.pine +0 -0
  216. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-cross-entry-cancel-same-pass-01.pine +0 -0
  217. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-cross-entry-close-same-pass-01.pine +0 -0
  218. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-cross-exit-close-same-pass-01.pine +0 -0
  219. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-deferred-flip-guaranteed-gap-stops-01.pine +0 -0
  220. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-deferred-flip-pooc-cross-bar-01.pine +0 -0
  221. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-four-bar-stop-no-close-01.pine +0 -0
  222. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-side-same-id-stop-no-cancel-01.pine +0 -0
  223. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-both-touch-priority-01.pine +0 -0
  224. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-cancel-rotation-01.pine +0 -0
  225. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-far-only-01.pine +0 -0
  226. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-near-only-01.pine +0 -0
  227. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-high-first-path-01.pine +0 -0
  228. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-low-first-path-01.pine +0 -0
  229. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-open-tie-01.pine +0 -0
  230. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-source-order-long-first-01.pine +0 -0
  231. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-dual-stop-source-order-short-first-01.pine +0 -0
  232. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-entry-implicit-reversal-exit-01.pine +0 -0
  233. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-flip-stop-no-paired-close-01.pine +0 -0
  234. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-market-close-fill-basis-01.pine +0 -0
  235. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-one-side-four-bar-far-opposite-01.pine +0 -0
  236. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-opposite-entry-close-same-pass-01.pine +0 -0
  237. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-percent-equity-cash-commission-01.pine +0 -0
  238. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-process-on-close-false-01.pine +0 -0
  239. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-process-on-close-true-01.pine +0 -0
  240. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-range-expansion-pending-stop-01.pine +0 -0
  241. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-entry-close-same-bar-01.pine +0 -0
  242. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-market-entry-repeat-01.pine +0 -0
  243. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-after-flat-01.pine +0 -0
  244. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-cross-before-modify-01.pine +0 -0
  245. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-minute-zero-01.pine +0 -0
  246. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-modification-01.pine +0 -0
  247. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-raise-only-01.pine +0 -0
  248. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-same-id-stop-window-four-bars-01.pine +0 -0
  249. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-stale-stop-after-close-no-cancel-01.pine +0 -0
  250. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-stop-cancel-no-regime-close-01.pine +0 -0
  251. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-stop-entry-cancel-opposite-01.pine +0 -0
  252. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-stop-entry-reversal-grouping-01.pine +0 -0
  253. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__order-stop-entry-touch-boundary-01.pine +0 -0
  254. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__pyramid-cash-fractional-commission-01.pine +0 -0
  255. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__pyramid-close-id-grouping-01.pine +0 -0
  256. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__pyramid-deferred-flip-close-all-01.pine +0 -0
  257. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__pyramid-flip-stop-pyramiding-2-01.pine +0 -0
  258. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__recompute-alma-sar-corr-magnifier-01.pine +0 -0
  259. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__recompute-mtf-rsi-macd-bb-01.pine +0 -0
  260. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__risk-max-contracts-held-gate-pyramid-01.pine +0 -0
  261. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__session-hour-minute-pulse-filter-01.pine +0 -0
  262. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__session-ny-spring-forward-dst-01.pine +0 -0
  263. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__stats-eventrades-zero-pnl-count-01.pine +0 -0
  264. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-accdist-ema-cross-01.pine +0 -0
  265. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-bb-kc-squeeze-breakout-01.pine +0 -0
  266. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-bb-rsi-mean-reversion-01.pine +0 -0
  267. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-cci-threshold-cross-01.pine +0 -0
  268. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-chandelier-exit-direction-01.pine +0 -0
  269. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-closedtrades-risk-introspection-01.pine +0 -0
  270. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-cmo-9-zero-cross-01.pine +0 -0
  271. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-cog-10-signal-cross-01.pine +0 -0
  272. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-dmi-adx-di-cross-01.pine +0 -0
  273. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-donchian-channel-breakout-01.pine +0 -0
  274. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-dual-ma-switch-dispatch-01.pine +0 -0
  275. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-dual-thrust-open-anchored-range-01.pine +0 -0
  276. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-elder-ray-bull-bear-power-01.pine +0 -0
  277. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-ema-ribbon-stack-transition-01.pine +0 -0
  278. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-engulfing-candle-pattern-01.pine +0 -0
  279. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-highestbars-lowestbars-breakout-01.pine +0 -0
  280. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-hma-55-close-cross-01.pine +0 -0
  281. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-hma-fast-slow-cross-01.pine +0 -0
  282. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-inside-bar-engulfing-01.pine +0 -0
  283. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-kama-style-efficiency-ratio-01.pine +0 -0
  284. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-keltner-channel-break-01.pine +0 -0
  285. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-linreg-stdev-channel-revert-01.pine +0 -0
  286. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-macd-12-26-9-line-signal-cross-01.pine +0 -0
  287. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-macd-histogram-reversal-01.pine +0 -0
  288. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-macd-line-gt-signal-continuous-state-01.pine +0 -0
  289. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-map-regime-threshold-lookup-01.pine +0 -0
  290. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-median-vs-ema-cross-01.pine +0 -0
  291. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-mfi-14-bands-20-80-01.pine +0 -0
  292. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-momentum-roc-zero-cross-01.pine +0 -0
  293. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-multi-indicator-score-composite-01.pine +0 -0
  294. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-nvi-pvi-cross-01.pine +0 -0
  295. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-obv-ema-cross-01.pine +0 -0
  296. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-percentrank-mean-reversion-01.pine +0 -0
  297. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-pivot-array-unshift-pop-01.pine +0 -0
  298. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-pivot-atr-stop-target-01.pine +0 -0
  299. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-pivot-confirmed-break-01.pine +0 -0
  300. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-pivot-point-levels-break-01.pine +0 -0
  301. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-pvt-ema-cross-01.pine +0 -0
  302. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-range-filter-var-band-01.pine +0 -0
  303. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rci-14-zero-cross-01.pine +0 -0
  304. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi-bb-self-bands-01.pine +0 -0
  305. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi-ema-signal-cross-01.pine +0 -0
  306. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi-macd-and-continuous-state-01.pine +0 -0
  307. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi14-bands-30-70-01.pine +0 -0
  308. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi14-cross-50-01.pine +0 -0
  309. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi14-gt-50-continuous-state-01.pine +0 -0
  310. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-rsi14-gt60-lt45-no-matrix-01.pine +0 -0
  311. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-sar-flip-entry-01.pine +0 -0
  312. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-sma-152-close-cross-01.pine +0 -0
  313. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-sma-dual-cross-01.pine +0 -0
  314. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-stdev-sma-expansion-break-01.pine +0 -0
  315. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-stoch-slow-k-d-cross-01.pine +0 -0
  316. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-stochastic-rsi-cross-01.pine +0 -0
  317. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-str-match-regex-filter-01.pine +0 -0
  318. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-supertrend-adx-filter-01.pine +0 -0
  319. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-supertrend-direction-flip-01.pine +0 -0
  320. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-triple-sma-stack-latch-01.pine +0 -0
  321. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-tsi-25-13-signal-cross-01.pine +0 -0
  322. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-volume-spike-atr-breakout-01.pine +0 -0
  323. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-vwma-vs-sma-divergence-01.pine +0 -0
  324. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__ta-wpr-14-bands-01.pine +0 -0
  325. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__timeframe-main-period-self-adaptive-01.pine +0 -0
  326. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-calls-sibling-cumulative-01.pine +0 -0
  327. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-default-param-kwargs-01.pine +0 -0
  328. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-drives-strategy-entry-01.pine +0 -0
  329. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-extra-primitive-args-01.pine +0 -0
  330. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-feeds-strategy-exit-prices-01.pine +0 -0
  331. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-in-for-loop-01.pine +0 -0
  332. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-in-if-else-branch-01.pine +0 -0
  333. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-in-switch-arms-01.pine +0 -0
  334. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-in-while-loop-01.pine +0 -0
  335. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-mutating-self-ref-01.pine +0 -0
  336. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-on-array-element-01.pine +0 -0
  337. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-reads-strategy-state-01.pine +0 -0
  338. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-receives-ta-series-param-01.pine +0 -0
  339. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-scalar-return-01.pine +0 -0
  340. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-tuple-return-destructure-01.pine +0 -0
  341. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-udt-return-from-func-01.pine +0 -0
  342. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-uses-history-globals-01.pine +0 -0
  343. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-uses-math-funcs-01.pine +0 -0
  344. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-uses-na-nz-fixnan-01.pine +0 -0
  345. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-var-instance-streak-01.pine +0 -0
  346. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-method-windowed-method-chain-01.pine +0 -0
  347. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__udt-regime-stack-stress-01.pine +0 -0
  348. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__vwap-bands-breakout-1sigma-01.pine +0 -0
  349. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/gate-corpus/ok/validation__vwap-bands-mean-reversion-2sigma-01.pine +0 -0
  350. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_analyzer.py +0 -0
  351. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_analyzer_matrix_inference.py +0 -0
  352. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_analyzer_ta_return_types.py +0 -0
  353. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_audit_fixes.py +0 -0
  354. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_determinism.py +0 -0
  355. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_fallthrough_guards.py +0 -0
  356. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_golden.py +0 -0
  357. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_input_getters.py +0 -0
  358. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_matrix_typed.py +0 -0
  359. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_codegen_new.py +0 -0
  360. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_compile_corpus.py +0 -0
  361. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_compile_smoke.py +0 -0
  362. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_errors.py +0 -0
  363. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_extract_inputs.py +0 -0
  364. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_glue_smoke.py +0 -0
  365. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_import_all.py +0 -0
  366. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_input_time_int64.py +0 -0
  367. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_int64_time_storage.py +0 -0
  368. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_lexer.py +0 -0
  369. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_security_tf_literal.py +0 -0
  370. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_signatures.py +0 -0
  371. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_dividends_earnings.py +0 -0
  372. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_footprint.py +0 -0
  373. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_input_color.py +0 -0
  374. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_input_source.py +0 -0
  375. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_matrix.py +0 -0
  376. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_security_adjustment.py +0 -0
  377. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_syminfo_gap_fields.py +0 -0
  378. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_timeframe_from_seconds.py +0 -0
  379. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_varip.py +0 -0
  380. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_support_checker_volume_row.py +0 -0
  381. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_symbols.py +0 -0
  382. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_ta_official_surface.py +0 -0
  383. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_transpile_division.py +0 -0
  384. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_transpile_enum_order.py +0 -0
  385. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_transpile_pf_trace.py +0 -0
  386. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_transpile_tr_handle_na.py +0 -0
  387. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_transpiler_matrix_kwargs.py +0 -0
  388. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_typespec_matrix.py +0 -0
  389. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_udt_drawing_field_cleanup.py +0 -0
  390. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_unsupported_reporting.py +0 -0
  391. {pineforge_codegen-0.7.6 → pineforge_codegen-0.8.0}/tests/test_vwap_tuple_unpack.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pineforge-codegen
3
- Version: 0.7.6
3
+ Version: 0.8.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.8.0
@@ -902,8 +902,15 @@ class CodeGen(CallVisitor, ExprVisitor, StmtVisitor, TopLevelEmitter, SecurityEm
902
902
  else:
903
903
  default = self._default_for_spec(spec)
904
904
  lines.append(f" {cpp_type} {f.name} = {default};")
905
+ # NA sentinel (always the last data member). A default-constructed
906
+ # UDT - ``var T x = na``, an array fill slot, ``T.copy()`` no-arg -
907
+ # is na; the ``T.new(...)`` lowering sets this false. This lets
908
+ # ``na(udtVar)`` lower to the ``is_na(const T&)`` overload below
909
+ # instead of failing because no ``is_na`` accepts a struct.
910
+ lines.append(f" bool __pf_na = true;")
905
911
  lines.append(f" static {type_name} create() {{ return {type_name}{{}}; }}")
906
912
  lines.append("};")
913
+ lines.append(f"inline bool is_na(const {type_name}& _z) {{ return _z.__pf_na; }}")
907
914
  lines.append("")
908
915
 
909
916
  # 1c. Enum constants + string tables for str.tostring(enumVar)
@@ -1048,13 +1055,22 @@ class CodeGen(CallVisitor, ExprVisitor, StmtVisitor, TopLevelEmitter, SecurityEm
1048
1055
  self._map_vars.add(name)
1049
1056
  lines.append(f" {self._type_spec_to_cpp(self._map_spec_for_name(name))} {safe};")
1050
1057
  continue
1051
- # Detect UDT vars: init_str like "TypeName.new(...)"
1058
+ # Detect UDT vars. Two signals: (1) the analyzer recorded an
1059
+ # explicit UDT type annotation in ``_udt_var_types`` - this is the
1060
+ # ONLY signal when the initializer is ``na`` (``var SDZone z = na``),
1061
+ # where the inferred ``ptype`` is NA->double; (2) the init_str is a
1062
+ # ``TypeName.new(...)`` constructor. Without (1) the member would
1063
+ # decl as ``double`` and the later ``z = SDZone{...}`` would not
1064
+ # compile (assigning SDZone to double).
1052
1065
  init_s = str(init_str)
1053
- udt_type = None
1054
- for udt_name in self._udt_defs:
1055
- if init_s.startswith(f"{udt_name}.new"):
1056
- udt_type = udt_name
1057
- break
1066
+ udt_type = self._udt_var_types.get(name)
1067
+ if udt_type not in self._udt_defs:
1068
+ udt_type = None
1069
+ if udt_type is None:
1070
+ for udt_name in self._udt_defs:
1071
+ if init_s.startswith(f"{udt_name}.new"):
1072
+ udt_type = udt_name
1073
+ break
1058
1074
  if udt_type:
1059
1075
  lines.append(f" {udt_type} {safe};")
1060
1076
  continue
@@ -1258,7 +1274,7 @@ class CodeGen(CallVisitor, ExprVisitor, StmtVisitor, TopLevelEmitter, SecurityEm
1258
1274
  if isinstance(val, (int, float)):
1259
1275
  return str(val)
1260
1276
  if isinstance(val, str):
1261
- return f'std::string("{val}")'
1277
+ return f'std::string("{self._cpp_string_escape(val)}")'
1262
1278
  # Also resolve bar field references
1263
1279
  if arg_str in BAR_FIELDS:
1264
1280
  return BAR_FIELDS[arg_str]
@@ -182,11 +182,27 @@ class TopLevelEmitter:
182
182
  for node in self._walk_ast(self.ctx.ast):
183
183
  if not isinstance(node, FuncCall):
184
184
  continue
185
- func_name, namespace = self._resolve_callee(node.callee)
186
- if namespace == "input" and func_name == "source":
185
+ if self._is_source_input(node):
187
186
  return True
188
187
  return False
189
188
 
189
+ def _typed_na_init(self, cpp_val: str, name: str, ptype) -> str:
190
+ """Re-type a bare ``na<double>()`` initializer to match a non-double
191
+ member's C++ type. A ``var int x = na`` resolves its RHS to
192
+ ``na<double>()`` (a quiet NaN); constructing/pushing that into an int or
193
+ bool member is a NaN->int conversion (UB) that yields garbage and defeats
194
+ ``is_na<T>()`` (which checks the type sentinel, e.g. INT_MIN). Returns the
195
+ value unchanged unless it is exactly ``na<double>()`` and the member type
196
+ is non-double."""
197
+ if cpp_val != "na<double>()":
198
+ return cpp_val
199
+ cpp_type = PINE_TYPE_TO_CPP.get(ptype, "double")
200
+ if cpp_type == "int" and self._is_int64_builtin_init(name):
201
+ cpp_type = "int64_t"
202
+ if cpp_type == "double":
203
+ return cpp_val
204
+ return f"na<{cpp_type}>()"
205
+
190
206
  def _emit_constructor(self, lines: list[str]) -> None:
191
207
  init_parts: list[str] = []
192
208
  # TA members with ctor args
@@ -224,8 +240,14 @@ class TopLevelEmitter:
224
240
  safe = self._safe_name(name)
225
241
  if name in self._array_vars or name in self._map_vars:
226
242
  continue
243
+ # UDT-typed var members (``var SDZone z = na``) default-construct to
244
+ # na via the struct's in-class ``__pf_na = true``; a ctor init like
245
+ # ``z(na<double>())`` would not type-match the struct member.
246
+ if name in self._udt_var_types and self._udt_var_types[name] in self._udt_defs:
247
+ continue
227
248
  if name not in self.ctx.series_vars:
228
249
  cpp_val = self._resolve_known(init_expr)
250
+ cpp_val = self._typed_na_init(cpp_val, name, ptype)
229
251
  if self._is_compile_time_value(cpp_val):
230
252
  init_parts.append(f"{safe}({cpp_val})")
231
253
  # Strategy params that map to engine members
@@ -394,6 +416,25 @@ class TopLevelEmitter:
394
416
  lines.append(f" if (is_first_tick_) _s_{field_name}.push({push_expr});")
395
417
  lines.append(f" else _s_{field_name}.update({push_expr});")
396
418
 
419
+ # a1. Push history-referenced scalar bar builtins (time[n], bar_index[n],
420
+ # hl2[n], …). They land in ``series_vars`` and are declared as Series
421
+ # members (base.py section 6) but — unlike user series vars (pushed at
422
+ # their assignment) and bar fields (pushed above) — have no push site,
423
+ # so ``[n]`` would read an unfed buffer (the na sentinel) on every bar.
424
+ # Push each from its scalar lowering. A builtin whose lowering is a
425
+ # self-referential call (e.g. ``time_close`` -> ``time_close()``) is
426
+ # skipped — the call would resolve to the shadowing Series member.
427
+ from .tables import BAR_BUILTINS
428
+ for _bname in sorted(self.ctx.series_vars):
429
+ if _bname in self._var_names:
430
+ continue
431
+ _bexpr = BAR_BUILTINS.get(_bname)
432
+ if _bexpr is None or f"{_bname}(" in _bexpr:
433
+ continue
434
+ _bsafe = self._safe_name(_bname)
435
+ lines.append(f" if (is_first_tick_) {_bsafe}.push({_bexpr});")
436
+ lines.append(f" else {_bsafe}.update({_bexpr});")
437
+
397
438
  # a2. Push strategy series
398
439
  for svar in sorted(self._strategy_series_vars):
399
440
  member = svar.replace("_strat_", "")
@@ -447,6 +488,7 @@ class TopLevelEmitter:
447
488
  continue
448
489
  if name in self.ctx.series_vars:
449
490
  cpp_val = self._resolve_known(init_expr)
491
+ cpp_val = self._typed_na_init(cpp_val, name, ptype)
450
492
  lines.append(f" {safe}.push({cpp_val});")
451
493
  # Also init cloned copies for per-call-site function variants
452
494
  init_emitted: set[str] = set()
@@ -490,7 +532,7 @@ class TopLevelEmitter:
490
532
  func_name_i, namespace_i = self._resolve_callee(stmt.value.callee)
491
533
  is_static_global_input = (
492
534
  stmt.name in self._global_member_vars
493
- and func_name_i != "source"
535
+ and not self._is_source_input(stmt.value)
494
536
  and stmt.name not in self._array_vars
495
537
  and stmt.name not in getattr(self, "_matrix_specs", {})
496
538
  and stmt.name not in getattr(self, "_map_vars", {})
@@ -33,6 +33,31 @@ CPP_RESERVED = {
33
33
  }
34
34
 
35
35
 
36
+ # Bare C++ identifiers that ``strategy.*`` (and a few other) read-only
37
+ # accessors lower to as zero-arg free-function calls — e.g.
38
+ # ``strategy.grossprofit`` -> ``gross_profit()`` (see codegen/visit_expr.py
39
+ # and codegen/emit_top.py). A user variable emitted with one of these names
40
+ # becomes a class member that shadows the engine accessor, so the codegen
41
+ # would emit ``gross_profit = gross_profit();`` and clang rejects the call
42
+ # ("called object type 'double' is not a function"). Escaping such user
43
+ # identifiers in ``_safe_name`` keeps the two namespaces disjoint; the
44
+ # accessor call strings are emitted verbatim and never routed through
45
+ # ``_safe_name``, so they are unaffected. Keep in sync with the accessor
46
+ # lowerings if new bare-call accessors are added.
47
+ BUILTIN_ACCESSOR_NAMES = {
48
+ "signed_position_size", "position_entry_name",
49
+ "count_wintrades", "count_losstrades", "eventrades",
50
+ "net_profit", "gross_profit", "gross_loss",
51
+ "grossprofit_percent", "grossloss_percent",
52
+ "max_contracts_held_all", "max_contracts_held_long",
53
+ "max_contracts_held_short", "max_drawdown_percent", "max_runup_percent",
54
+ "avg_trade", "avg_trade_percent", "avg_winning_trade", "avg_losing_trade",
55
+ "avg_winning_trade_percent", "avg_losing_trade_percent",
56
+ "margin_liquidation_price", "open_profit", "current_equity",
57
+ "open_trades_capital_held",
58
+ }
59
+
60
+
36
61
  class NamingHelper:
37
62
  """Identifier escaping, callee resolution, and a generic AST walker.
38
63
 
@@ -56,7 +81,7 @@ class NamingHelper:
56
81
 
57
82
  def _safe_name(self, name: str) -> str:
58
83
  """Rename identifiers that collide with C++ reserved words."""
59
- if name in CPP_RESERVED:
84
+ if name in CPP_RESERVED or name in BUILTIN_ACCESSOR_NAMES:
60
85
  return f"_{name}_"
61
86
  return name
62
87
 
@@ -156,6 +156,27 @@ class InputHelper:
156
156
  return "get_input_int"
157
157
  return "get_input_double"
158
158
 
159
+ def _is_source_input(self, node: FuncCall) -> bool:
160
+ """True if an ``input.*`` call yields a *live per-bar source series*.
161
+
162
+ Covers both ``input.source(<native series>)`` and a bare
163
+ ``input(<native series>)`` — in Pine v6 ``input(close)`` is the
164
+ source-input overload and behaves like ``input.source(close)``,
165
+ returning a series that tracks ``close`` every bar (not a constant
166
+ frozen at the first bar). The defval is restricted to the native
167
+ OHLCV series the engine can resolve at runtime (the same set
168
+ ``input.source`` is restricted to); a bare ``input(14)`` /
169
+ ``input(\"x\")`` / ``input(true)`` stays a frozen scalar."""
170
+ func_name, namespace = self._resolve_callee(node.callee)
171
+ if namespace == "input" and func_name == "source":
172
+ return True
173
+ if func_name == "input" and namespace is None:
174
+ default = self._get_input_default(node)
175
+ if (isinstance(default, Identifier)
176
+ and default.name in self._NATIVE_SOURCE_SERIES):
177
+ return True
178
+ return False
179
+
159
180
  def _source_defval_to_base_series(self, default) -> str:
160
181
  """Map an input.source defval (close/high/hl2/…) to its engine base
161
182
  source series member (``_src_close_`` …). Falls back to
@@ -175,8 +196,10 @@ class InputHelper:
175
196
  series and we read its current value; a subscripted source var is
176
197
  already tracked as a series var by the analyzer so ``src[1]`` lowers
177
198
  to a Series subscript. Every other input type routes through the
178
- scalar getter table."""
179
- if namespace == "input" and func_name == "source":
199
+ scalar getter table. A bare ``input(<native series>)`` is the Pine
200
+ source-input overload and is rendered identically to
201
+ ``input.source``."""
202
+ if self._is_source_input(node):
180
203
  default = self._get_input_default(node)
181
204
  base = self._source_defval_to_base_series(default)
182
205
  return f'get_input_source("{title}", {base})[0]'
@@ -1232,6 +1232,37 @@ class SecurityEmitter:
1232
1232
 
1233
1233
  self._emit_security_rebinds(sec_id, info, lines, ta_results, indent=2, emitted_lines=lines)
1234
1234
  emit_security_ta(post_rebind_ta_indices)
1235
+ returns_tuple = item.get("returns_tuple", False)
1236
+ tuple_size = item.get("tuple_size", 0)
1237
+ if (
1238
+ returns_tuple
1239
+ and tuple_size
1240
+ and tuple_size > 0
1241
+ and isinstance(expr_node, TupleLiteral)
1242
+ ):
1243
+ # A tuple body destructures into per-element scalar members
1244
+ # ``_req_sec_{sec_id}_{i}`` (declared in ``base.py`` and reset in
1245
+ # ``clear_security``). Assign each element individually rather
1246
+ # than building the whole ``TupleLiteral`` (which lowers to an
1247
+ # ``std::make_tuple(...)`` against the non-existent aggregate
1248
+ # member ``_req_sec_{sec_id}``).
1249
+ for i, el in enumerate(expr_node.elements):
1250
+ el_cpp = self._build_security_expr(
1251
+ sec_id,
1252
+ el,
1253
+ None,
1254
+ ta_results,
1255
+ security_mutable_names=security_mutable_names,
1256
+ emitted_lines=lines,
1257
+ )
1258
+ lines.append(f" _req_sec_{sec_id}_{i} = {el_cpp};")
1259
+ for field in sorted(self._security_ohlc_hist_fields_by_sec.get(sec_id, ())):
1260
+ lines.append(
1261
+ f" {self._security_ohlc_hist_series_cpp(sec_id, field)}.push(bar.{field});"
1262
+ )
1263
+ lines.append(" }")
1264
+ lines.append("")
1265
+ continue
1235
1266
  expr_cpp = self._build_security_expr(
1236
1267
  sec_id,
1237
1268
  expr_node,
@@ -295,4 +295,7 @@ class TaSiteHelper:
295
295
  return True
296
296
  except ValueError:
297
297
  pass
298
- return val in ("true", "false", "0", "0.0", "na<double>()")
298
+ return val in (
299
+ "true", "false", "0", "0.0",
300
+ "na<double>()", "na<int>()", "na<int64_t>()", "na<bool>()",
301
+ )
@@ -382,14 +382,14 @@ ORDER_DIRECTION_MAP = {
382
382
 
383
383
  # Methods called as ``array.method(arr, ...)`` or ``arr.method(...)``.
384
384
  ARRAY_METHODS = {
385
- "get": lambda a, args: f"{a}[{args[0]}]",
386
- "set": lambda a, args: f"{a}[{args[0]}] = {args[1]}",
385
+ "get": lambda a, args: f"{a}[({args[0]})]",
386
+ "set": lambda a, args: f"{a}[({args[0]})] = {args[1]}",
387
387
  "push": lambda a, args: f"{a}.push_back({args[0]})",
388
388
  "unshift": lambda a, args: f"{a}.insert({a}.begin(), {args[0]})",
389
389
  "insert": lambda a, args: f"{a}.insert({a}.begin() + (int)({args[0]}), {args[1]})",
390
390
  "pop": lambda a, args: f"[&](){{ auto v={a}.back(); {a}.pop_back(); return v; }}()",
391
391
  "shift": lambda a, args: f"[&](){{ auto v={a}.front(); {a}.erase({a}.begin()); return v; }}()",
392
- "remove": lambda a, args: f"[&](){{ auto v={a}[{args[0]}]; {a}.erase({a}.begin()+(int)({args[0]})); return v; }}()",
392
+ "remove": lambda a, args: f"[&](){{ auto v={a}[({args[0]})]; {a}.erase({a}.begin()+(int)({args[0]})); return v; }}()",
393
393
  "first": lambda a, args: f"{a}.front()",
394
394
  "last": lambda a, args: f"{a}.back()",
395
395
  "size": lambda a, args: f"(double){a}.size()",
@@ -435,7 +435,7 @@ ARRAY_METHODS = {
435
435
  "mode": lambda a, args: f"[&](){{ std::unordered_map<double,int> m; for(auto v:{a})m[v]++; double best=0; int bc=0; for(auto&[v,c]:m)if(c>bc||(c==bc&&v<best)){{bc=c;best=v;}} return best; }}()",
436
436
  "percentile_linear_interpolation": lambda a, args: f"[&](){{ auto c={a}; std::sort(c.begin(),c.end()); double k=({args[0]}/100.0)*c.size()-0.5; int i=std::max(0,(int)k); double f=k-i; if(i+1>=(int)c.size()) return c.back(); return c[i]*(1-f)+c[i+1]*f; }}()",
437
437
  "percentile_nearest_rank": lambda a, args: f"[&](){{ auto c={a}; std::sort(c.begin(),c.end()); int r=(int)std::ceil(({args[0]}/100.0)*c.size()); return c[std::min(r-1,(int)c.size()-1)]; }}()",
438
- "percentrank": lambda a, args: f"[&](){{ if({a}.size()<=1) return na<double>(); double v={a}[{args[0]}]; if(std::isnan(v)) return na<double>(); int le=0; for(auto x:{a}) if(!std::isnan(x) && x<=v) le++; return (double)(le-1)/({a}.size()-1)*100.0; }}()",
438
+ "percentrank": lambda a, args: f"[&](){{ if({a}.size()<=1) return na<double>(); double v={a}[({args[0]})]; if(std::isnan(v)) return na<double>(); int le=0; for(auto x:{a}) if(!std::isnan(x) && x<=v) le++; return (double)(le-1)/({a}.size()-1)*100.0; }}()",
439
439
  "abs": lambda a, args: f"[&](){{ std::vector<double> r; for(auto v:{a})r.push_back(std::abs(v)); return r; }}()",
440
440
  "join": lambda a, args: "[&](){{ std::string r; for(size_t i=0;i<{arr}.size();i++){{ if(i>0)r+={sep}; r+=std::to_string({arr}[i]); }} return r; }}()".format(arr=a, sep=args[0] if args else 'std::string(",")'),
441
441
  "standardize": lambda a, args: f"[&](){{ double m=std::accumulate({a}.begin(),{a}.end(),0.0)/{a}.size(); double s=0; for(auto v:{a})s+=(v-m)*(v-m); s=std::sqrt(s/{a}.size()); std::vector<double> r; for(auto v:{a})r.push_back(s==0?1.0:(v-m)/s); return r; }}()",
@@ -357,7 +357,12 @@ class TypeInferer:
357
357
 
358
358
  def _series_type_for(self, name: str) -> str:
359
359
  """C++ element type for a series variable's history buffer."""
360
- if self._is_int64_builtin_init(name):
360
+ from .tables import INT64_BUILTINS
361
+ # A bare int64 bar builtin used as a history series (``time[1]``) needs an
362
+ # int64_t buffer: epoch-ms overflow int32 and the na sentinel would be
363
+ # misdetected. ``_is_int64_builtin_init`` only matches user vars whose
364
+ # init RHS is such a builtin, so also match the builtin name directly.
365
+ if name in INT64_BUILTINS or self._is_int64_builtin_init(name):
361
366
  return "int64_t"
362
367
  sym = self.ctx.symbols.resolve(name)
363
368
  if sym is not None:
@@ -473,8 +478,15 @@ class TypeInferer:
473
478
  return "std::string"
474
479
  if func_name == "bool":
475
480
  return "bool"
476
- if func_name in ("int", "color", "time"):
481
+ if func_name == "int":
477
482
  return "int"
483
+ # ``input.time`` returns an epoch-MS timestamp and ``input.color``
484
+ # a packed ARGB int — both use the ``get_input_int64`` getter
485
+ # (input.py), so their storage must be ``int64_t`` or the value
486
+ # truncates under int32 (e.g. a date-window bound flips sign and
487
+ # the guard is permanently false).
488
+ if func_name in ("color", "time"):
489
+ return "int64_t"
478
490
  return "double"
479
491
  if namespace == "str":
480
492
  if func_name == "split":
@@ -439,6 +439,13 @@ class CallVisitor:
439
439
  if namespace == "color":
440
440
  return self._visit_color_call(func_name, node)
441
441
 
442
+ # Bare color(...) cast (cosmetic). The engine has no color-cast helper
443
+ # and colors have no backtest-logic effect, so emit a benign default
444
+ # color (0 = na color, matching the color.new / from_gradient
445
+ # fallbacks). The support checker warns on this construct.
446
+ if namespace is None and func_name == "color" and func_name not in self._func_names:
447
+ return "0"
448
+
442
449
  # Skip visual/unsupported namespace calls
443
450
  if namespace in SKIP_NAMESPACES or namespace in SKIP_VAR_TYPES:
444
451
  return "0"
@@ -913,6 +920,11 @@ class CallVisitor:
913
920
  if f_cpp_type == "int" and "na<double>" in val:
914
921
  val = val.replace("na<double>()", "0")
915
922
  field_inits.append(f".{f.name} = {val}")
923
+ # Mark the constructed object non-na (the struct's ``__pf_na`` is the
924
+ # last declared field, so this designator stays in declaration order).
925
+ # A bare default-constructed UDT keeps ``__pf_na = true`` (na); only a
926
+ # real ``.new(...)`` flips it false so ``na(obj)`` reports correctly.
927
+ field_inits.append(".__pf_na = false")
916
928
  return f"{namespace}{{{', '.join(field_inits)}}}"
917
929
 
918
930
  # UDT copy: TypeName.copy(obj)
@@ -180,7 +180,7 @@ class ExprVisitor:
180
180
  if isinstance(node, NumberLiteral):
181
181
  return str(node.value)
182
182
  if isinstance(node, StringLiteral):
183
- return f'std::string("{node.value}")'
183
+ return f'std::string("{self._cpp_string_escape(node.value)}")'
184
184
  if isinstance(node, BoolLiteral):
185
185
  return "true" if node.value else "false"
186
186
  if isinstance(node, NaLiteral):
@@ -475,8 +475,17 @@ class ExprVisitor:
475
475
  if node.member in ("is_heikinashi", "is_kagi", "is_linebreak",
476
476
  "is_pnf", "is_range", "is_renko"):
477
477
  return "false"
478
- # Defensive: support_checker.UNSUPPORTED_MEMBERS should already have
479
- # rejected any unhandled chart.* member. Reaching here is a bug.
478
+ # Cosmetic / chart-only reads with no batch-mode value (theme
479
+ # colors, viewport bar times). The support checker warns on
480
+ # these (COSMETIC_MEMBERS); emit a benign default (0 = na color /
481
+ # epoch 0). They have no backtest-logic effect.
482
+ if node.member in ("fg_color", "bg_color",
483
+ "left_visible_bar_time",
484
+ "right_visible_bar_time"):
485
+ return "0"
486
+ # Defensive: support_checker (COSMETIC_MEMBERS / UNSUPPORTED_MEMBERS)
487
+ # should already have warned/rejected any unhandled chart.* member.
488
+ # Reaching here is a bug.
480
489
  raise ValueError(
481
490
  f"codegen: unhandled chart.{node.member} — analyzer should have rejected. "
482
491
  f"Add a handler above or extend UNSUPPORTED_MEMBERS."
@@ -717,6 +726,31 @@ class ExprVisitor:
717
726
  if series_name not in self._strategy_series_vars:
718
727
  self._strategy_series_vars.add(series_name)
719
728
  return f"{series_name}[{idx}]"
729
+ # History reference applied directly to an inline call result, e.g.
730
+ # ``ta.highest(high, 10)[1]`` or ``f()[2]``. In Pine the call yields a
731
+ # series, so ``[k]`` reads its value k bars ago — but the call lowers to
732
+ # a freshly-computed C++ scalar, and ``scalar[k]`` is not subscriptable.
733
+ # Materialize the result into a self-contained history buffer: a static
734
+ # ``Series<T>`` that pushes (new bar) / updates (intrabar) the value
735
+ # exactly once per evaluation — same semantics as every other series in
736
+ # the strategy — and read ``[k]`` off it. The inner call is emitted once
737
+ # so its own stateful indicator is not double-stepped, and the buffer
738
+ # clears itself on run-start (``is_first_tick_ && bar_index_ == 0``) so a
739
+ # reused strategy handle (parameter sweep) does not leak prior-run history.
740
+ if isinstance(node.object, FuncCall):
741
+ inner = self._visit_expr(node.object)
742
+ cpp_t = self._infer_type(node.object)
743
+ if cpp_t not in ("double", "int", "bool"):
744
+ cpp_t = "double"
745
+ return (
746
+ f"([&]() -> {cpp_t} {{ "
747
+ f"static thread_local Series<{cpp_t}> _hist_call; "
748
+ f"if (is_first_tick_ && bar_index_ == 0) _hist_call.clear(); "
749
+ f"{cpp_t} _hv = ({inner}); "
750
+ f"if (is_first_tick_) _hist_call.push(_hv); "
751
+ f"else _hist_call.update(_hv); "
752
+ f"return _hist_call[(int)({idx})]; }}())"
753
+ )
720
754
  obj = self._visit_expr(node.object)
721
755
  # If subscripting a non-series variable (e.g., function parameter),
722
756
  # src[0] → src (current value), src[N>0] → src (can't access history)
@@ -100,7 +100,6 @@ from ..ast_nodes import (
100
100
  )
101
101
  from ..symbols import TypeSpec
102
102
  from .tables import (
103
- SKIP_VAR_TYPES,
104
103
  TA_RETURNS_BOOL,
105
104
  TA_TUPLE_FIELDS,
106
105
  MATRIX_RETURNING_METHODS,
@@ -259,7 +258,7 @@ class StmtVisitor:
259
258
  if is_global_member and isinstance(node.value, FuncCall) and self._is_input_call(node.value):
260
259
  func_name_i, namespace_i = self._resolve_callee(node.value.callee)
261
260
  is_static_global_input = (
262
- func_name_i != "source"
261
+ not self._is_source_input(node.value)
263
262
  and node.name not in self._array_vars
264
263
  and node.name not in getattr(self, "_matrix_specs", {})
265
264
  and node.name not in getattr(self, "_map_vars", {})
@@ -356,16 +355,19 @@ class StmtVisitor:
356
355
  lines.append(f"{pad}{cpp_type} {safe};")
357
356
  return
358
357
 
359
- # Skip visual function assignments but still emit declaration for
360
- # table function results since the var may be used later
358
+ # Visual/drawing function assignments (line.new, label.new, box.new,
359
+ # table.new, ...) are no-ops in a backtest, but the assigned variable may
360
+ # still be referenced later (e.g. pushed into an array<line>, or used as a
361
+ # handle by sibling set_* calls). Emit a default-valued local declaration
362
+ # so those references compile; the value is inert. Global members are
363
+ # already declared at class scope, so only locals need this. (Previously
364
+ # only `table` results were declared, which dropped loop-local line/label
365
+ # handles and produced "use of undeclared identifier".)
361
366
  if isinstance(node.value, FuncCall) and self._is_skip_expr(node.value):
362
- func_name, namespace = self._resolve_callee(node.value.callee)
363
- if namespace in SKIP_VAR_TYPES:
364
- # Emit var with default value so references don't fail
365
- if not is_global_member:
366
- cpp_type = self._type_for_decl(node)
367
- default = "0" if cpp_type in ("int", "double") else ('std::string("")' if cpp_type == "std::string" else "false")
368
- lines.append(f"{pad}{cpp_type} {safe} = {default};")
367
+ if not is_global_member:
368
+ cpp_type = self._type_for_decl(node)
369
+ default = "0" if cpp_type in ("int", "double") else ('std::string("")' if cpp_type == "std::string" else "false")
370
+ lines.append(f"{pad}{cpp_type} {safe} = {default};")
369
371
  return
370
372
 
371
373
  # TA call
@@ -542,7 +544,20 @@ class StmtVisitor:
542
544
  if name == "_":
543
545
  continue
544
546
  if i < len(fields):
545
- lines.append(f"{pad}double {name} = {result_var}.{fields[i]};")
547
+ field_expr = f"{result_var}.{fields[i]}"
548
+ # A history-referenced destructured name (e.g.
549
+ # ``[v, dir] = ta.supertrend(...)`` with ``dir[1]`` used
550
+ # later) is tracked in ``series_vars`` and declared as a
551
+ # ``Series<T>`` class member. Pushing into that member keeps
552
+ # its history buffer advancing so ``dir[n]`` resolves; a
553
+ # fresh ``double`` local would shadow the member and make
554
+ # ``dir[n]`` a scalar subscript (clang error). Non-series
555
+ # destructured names keep the plain scalar declaration.
556
+ if name in self.ctx.series_vars:
557
+ safe = self._safe_name(name)
558
+ lines.append(f"{pad}{safe}.push({field_expr});")
559
+ else:
560
+ lines.append(f"{pad}double {name} = {field_expr};")
546
561
  return
547
562
 
548
563
  # User-defined function returning a tuple: use C++17 structured bindings
@@ -273,9 +273,16 @@ class Lexer:
273
273
  self._read_token()
274
274
  if not self._at_end() and self.source[self.pos] == "\n":
275
275
  self._advance()
276
- # If parens closed on this line, emit NEWLINE so parser sees end of statement
276
+ # If parens closed on this line, end the statement UNLESS the line
277
+ # ends with a continuation token (e.g. trailing operator), in which
278
+ # case the next line continues the same logical line.
277
279
  if self.paren_depth == 0 and emitted_in_parens:
278
- self._emit(TokenType.NEWLINE, "\\n", self.line - 1, self.col)
280
+ last_token = self.tokens[-1] if self.tokens else None
281
+ if last_token and last_token.type in self.CONTINUATION_TOKENS:
282
+ self._in_continuation = True
283
+ else:
284
+ self._in_continuation = False
285
+ self._emit(TokenType.NEWLINE, "\\n", self.line - 1, self.col)
279
286
  return
280
287
 
281
288
  # Indentation handling
@@ -290,9 +297,24 @@ class Lexer:
290
297
  else:
291
298
  indent_level = len(raw) // 4
292
299
 
300
+ # Operator-first line continuation: when a line *begins* with a binary
301
+ # / ternary operator that cannot start a statement (e.g. ``? x``,
302
+ # ``: y``, ``+ z``, ``and w``), it continues the previous logical line
303
+ # even though that line did not *end* with an operator (the break was
304
+ # placed before the operator instead of after it). Suppress this line's
305
+ # INDENT/DEDENT and drop the NEWLINE that ended the prior line so the
306
+ # parser sees one contiguous expression. Only applies outside parens
307
+ # and when not already in an end-of-line continuation.
308
+ starts_with_cont_op = (
309
+ not self._in_continuation
310
+ and self._line_starts_with_continuation_op()
311
+ )
312
+ if starts_with_cont_op and self.tokens and self.tokens[-1].type == TokenType.NEWLINE:
313
+ self.tokens.pop()
314
+
293
315
  # If we're in a continuation (previous line ended with an operator),
294
316
  # suppress INDENT/DEDENT — the indentation is cosmetic, not structural
295
- if not self._in_continuation:
317
+ if not self._in_continuation and not starts_with_cont_op:
296
318
  current_indent = self.indent_stack[-1]
297
319
  if indent_level > current_indent:
298
320
  self.indent_stack.append(indent_level)
@@ -329,6 +351,49 @@ class Lexer:
329
351
  else:
330
352
  self._in_continuation = False
331
353
 
354
+ def _line_starts_with_continuation_op(self) -> bool:
355
+ """True when the upcoming line content begins with a binary/ternary
356
+ operator that can never begin a statement, so the line is a
357
+ continuation of the previous logical line.
358
+
359
+ Called with ``self.pos`` positioned at the first non-whitespace
360
+ character of the line. Deliberately conservative: ``-`` is excluded
361
+ (ambiguous leading unary minus) and ``.`` is excluded (``.5`` is a
362
+ leading-dot number, not member access). The included operators
363
+ (``? : + * / % == != > < >= <= and or``) cannot legally start a Pine
364
+ statement, so suppressing the line break for them never merges two
365
+ independent statements that previously parsed."""
366
+ src = self.source
367
+ p = self.pos
368
+ n = len(src)
369
+ if p >= n:
370
+ return False
371
+ c = src[p]
372
+ c2 = src[p + 1] if p + 1 < n else ""
373
+ # Two-character comparison operators.
374
+ if c2 == "=" and c in ("=", "!", ">", "<"):
375
+ return True
376
+ # ':' ternary-else continuation, but not ':=' (reassignment).
377
+ if c == ":" and c2 != "=":
378
+ return True
379
+ # Single-character operators that cannot start a statement.
380
+ if c in "?+*%><":
381
+ return True
382
+ # '/' division continuation, but never '//' (comment).
383
+ if c == "/" and c2 != "/":
384
+ return True
385
+ # 'and' / 'or' keyword continuation (require a word boundary so names
386
+ # like ``android`` / ``organic`` are not misread).
387
+ def _kw(word: str) -> bool:
388
+ end = p + len(word)
389
+ if src[p:end] != word:
390
+ return False
391
+ nxt = src[end] if end < n else ""
392
+ return not (nxt.isalnum() or nxt == "_")
393
+ if _kw("and") or _kw("or"):
394
+ return True
395
+ return False
396
+
332
397
  def _advance_to(self, target: int) -> None:
333
398
  while self.pos < target and self.pos < len(self.source):
334
399
  self._advance()