pineforge-codegen 0.7.0__tar.gz → 0.7.2__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.7.2/.github/workflows/gate.yml +60 -0
- pineforge_codegen-0.7.2/.github/workflows/publish-pyodide.yml +80 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/.github/workflows/release.yml +29 -9
- pineforge_codegen-0.7.2/.github/workflows/test.yml +42 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/.gitignore +11 -2
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/PKG-INFO +2 -1
- pineforge_codegen-0.7.2/PYODIDE_TARGET +1 -0
- pineforge_codegen-0.7.2/VERSION +1 -0
- pineforge_codegen-0.7.2/gate/compare.mjs +69 -0
- pineforge_codegen-0.7.2/gate/glue.py +35 -0
- pineforge_codegen-0.7.2/gate/oracle.py +34 -0
- pineforge_codegen-0.7.2/gate/run-gate.mjs +133 -0
- pineforge_codegen-0.7.2/gate/selftest.mjs +57 -0
- pineforge_codegen-0.7.2/npm/README.md +25 -0
- pineforge_codegen-0.7.2/npm/index.mjs +30 -0
- pineforge_codegen-0.7.2/npm/package.json +34 -0
- pineforge_codegen-0.7.2/package-lock.json +132 -0
- pineforge_codegen-0.7.2/package.json +16 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/base.py +22 -10
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pyproject.toml +2 -1
- pineforge_codegen-0.7.2/scripts/build-npm-package.mjs +74 -0
- pineforge_codegen-0.7.2/scripts/dump-tables.py +148 -0
- pineforge_codegen-0.7.2/scripts/worker-template.mjs +49 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/chart_bg_color.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/const_ns_plot_style_free.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/const_ns_shape_free.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/export_func.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/footprint_new.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/hard_reject_dividends.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/matrix_unknown_elem.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/multi_error_one_line.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/sec_tf_invalid.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_color.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_math.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_str.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_strategy_fn.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_syminfo.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/err/unknown_ta.pine +3 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine +16 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine +16 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine +29 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine +19 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/tutorial__macd__strategy.pine +45 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/tutorial__mtf__strategy_htf.pine +49 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/tutorial__mtf__strategy_ltf.pine +58 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine +34 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-parity-choch-bos-isolator-01.pine +83 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-parity-edge-margin-50-pct-01.pine +39 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-parity-percent-of-equity-sizing-01.pine +42 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-parity-small-equity-fraction-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-parity-stop-limit-timing-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__analyzer-self-test-multi-mode-01.pine +80 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__anomaly-equity-mirror-strategy-equity-01.pine +56 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-off-01b.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__barstate-isconfirmed-magnifier-on-01a.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-atr-trail-series-int-points-01.pine +57 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-atr-trailing-stop-state-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-entry-exit-same-pass-attach-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-exit-stop-limit-trail-same-bar-01.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-exit-three-way-set-once-entry-01.pine +49 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-exit-tp-sl-fixed-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-narrow-stop-limit-with-trail8-01.pine +49 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-partial-exit-qty-percent-01.pine +28 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-same-id-exit-replace-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-tp-sl-oca-reduce-isolate-01.pine +64 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-trail-points-no-offset-explicit-01.pine +50 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-trail-points-with-offset-only-01.pine +34 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__bracket-trailing-activation-offset-path-01.pine +35 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__cap-max-intraday-filled-orders-isolate-01.pine +45 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__cap-risk-gates-allow-max-intraday-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-4emarsi-integration-01.pine +99 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-4emarsi-quad-ema-stack-01.pine +59 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-4emarsi-rsi-pullback-latch-01.pine +61 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-4emarsi-session-window-nbar-exit-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-boscurv-integration-01.pine +80 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-boscurv-linreg-slope-channel-01.pine +64 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-boscurv-pivot-bos-trigger-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-bracket-cap-range-pending-stop-01.pine +98 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-adx-regime-classify-01.pine +87 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-bb-kc-squeeze-release-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-cooldown-daily-cap-01.pine +72 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-equity-feedback-sizing-01.pine +95 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-integration-01.pine +236 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-pivot-liquidity-sweep-01.pine +66 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-pressure-gauge-01.pine +79 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-rsi-macd-momentum-01.pine +88 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-ies-three-ema-bias-score-01.pine +82 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kanuck-calc-on-every-tick-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kanuck-integration-01.pine +85 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kanuck-kama-state-recurrence-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kanuck-max-bars-back-500-01.pine +67 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kkb-ema-atr-breakout-band-01.pine +48 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kkb-integration-01.pine +68 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kkb-kalman-filter-1d-01.pine +58 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-kkb-margin-100-pct-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-liqsweep-integration-01.pine +89 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-liqsweep-pivot-hh-ll-01.pine +58 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-liqsweep-wait-one-continuation-01.pine +73 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-liqsweep-wick-pierce-close-back-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-marketshift-integration-01.pine +97 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-marketshift-pivot-state-machine-01.pine +64 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-marketshift-rolling-highest-lowest-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-marketshift-state-edge-detector-01.pine +69 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-scalping-fast-ma-cross-trigger-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-scalping-integration-01.pine +61 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-scalping-tight-tp-sl-points-01.pine +63 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-trendmaster-integration-01.pine +124 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-trendmaster-line-new-projection-01.pine +92 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-trendmaster-pivot-anchored-bracket-01.pine +75 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-trendmaster-three-tier-ema-state-01.pine +66 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-trendmaster-trend-momentum-structure-gate-01.pine +73 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-cumulative-volume-delta-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-fvg-active-zones-01.pine +96 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-integration-01.pine +195 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-manual-adx-regime-01.pine +73 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-pivot-strength-5-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-rsi-smooth-divergence-01.pine +57 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-session-tz-newyork-01.pine +56 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-vcp-vol-zscore-anomaly-01.pine +52 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-wunderscalper-alert-templates-01.pine +56 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-wunderscalper-explicit-reverse-01.pine +53 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__composite-wunderscalper-integration-01.pine +53 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__input-source-runtime-override-high-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__input-source-subscript-hl2-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ltf-bool-array-bull-majority-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ltf-numeric-float-ratio15-01.pine +49 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__magnifier-tick-dist-endpoints-rsi-cross-08a.pine +37 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__magnifier-tick-dist-volume-weighted-on-01.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-bool-mask-explicit-utc-tz-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-bool-mask-no-transpose-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-bool-mask-transpose-roundtrip-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-bool-regime-mask-24x7-01.pine +65 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-covariance-eigen-pca-01.pine +43 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__matrix-eigen-rank-deficient-cov-01.pine +85 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-daily-array-median-percentrank-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-daily-ema26-warmup-01.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-daily-prev-high-break-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-dual-tf-60-240-rising-01.pine +28 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-close-change-baseline-01.pine +57 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-close-roll-01.pine +25 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-gaps-on-roll-01.pine +34 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-rsi14-inside-security-01.pine +25 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-sma20-inside-security-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-60-volume-spike-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-confluence-manual-trail-01.pine +77 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-confluence-static-bracket-01.pine +75 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-htf-weekly-sma-cross-01.pine +24 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-roll-state-60-240-d-minimal-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-triple-tf-close-confluence-01.pine +39 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__mtf-triple-tf-macd-hist-confluence-01.pine +47 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__na-deep-history-int-na-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__na-nz-fixnan-history-chain-01.pine +29 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__oca-exit-bracket-internal-cancel-01.pine +39 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__oca-multi-bracket-isolation-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__oca-raw-strategy-order-reduce-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-close-all-cancel-all-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-close-immediate-vs-next-bar-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-cross-entry-cancel-same-pass-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-cross-entry-close-same-pass-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-cross-exit-close-same-pass-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-deferred-flip-guaranteed-gap-stops-01.pine +63 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-deferred-flip-pooc-cross-bar-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-four-bar-stop-no-close-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-side-same-id-stop-no-cancel-01.pine +31 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-both-touch-priority-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-cancel-rotation-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-far-only-01.pine +22 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-near-only-01.pine +22 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-open-high-first-path-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-open-low-first-path-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-open-tie-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-source-order-long-first-01.pine +23 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-dual-stop-source-order-short-first-01.pine +23 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-entry-implicit-reversal-exit-01.pine +29 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-flip-stop-no-paired-close-01.pine +37 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-market-close-fill-basis-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-one-side-four-bar-far-opposite-01.pine +28 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-opposite-entry-close-same-pass-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-percent-equity-cash-commission-01.pine +21 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-process-on-close-false-01.pine +35 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-process-on-close-true-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-range-expansion-pending-stop-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-entry-close-same-bar-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-market-entry-repeat-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-after-flat-01.pine +31 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-cross-before-modify-01.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-minute-zero-01.pine +28 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-modification-01.pine +31 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-raise-only-01.pine +31 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-same-id-stop-window-four-bars-01.pine +24 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-stale-stop-after-close-no-cancel-01.pine +29 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-stop-cancel-no-regime-close-01.pine +47 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-stop-entry-cancel-opposite-01.pine +35 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-stop-entry-reversal-grouping-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__order-stop-entry-touch-boundary-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__pyramid-cash-fractional-commission-01.pine +37 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__pyramid-close-id-grouping-01.pine +40 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__pyramid-deferred-flip-close-all-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__pyramid-flip-stop-pyramiding-2-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__recompute-alma-sar-corr-magnifier-01.pine +36 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__recompute-mtf-rsi-macd-bb-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__risk-max-contracts-held-gate-pyramid-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__session-hour-minute-pulse-filter-01.pine +25 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__session-ny-spring-forward-dst-01.pine +40 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__stats-eventrades-zero-pnl-count-01.pine +48 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-accdist-ema-cross-01.pine +24 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-bb-kc-squeeze-breakout-01.pine +57 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-bb-rsi-mean-reversion-01.pine +41 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-cci-threshold-cross-01.pine +39 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-chandelier-exit-direction-01.pine +45 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-closedtrades-risk-introspection-01.pine +37 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-cmo-9-zero-cross-01.pine +23 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-cog-10-signal-cross-01.pine +25 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-dmi-adx-di-cross-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-donchian-channel-breakout-01.pine +42 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-dual-ma-switch-dispatch-01.pine +42 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-dual-thrust-open-anchored-range-01.pine +47 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-elder-ray-bull-bear-power-01.pine +45 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-ema-ribbon-stack-transition-01.pine +40 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-engulfing-candle-pattern-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-highestbars-lowestbars-breakout-01.pine +47 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-hma-55-close-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-hma-fast-slow-cross-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-inside-bar-engulfing-01.pine +48 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-kama-style-efficiency-ratio-01.pine +50 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-keltner-channel-break-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-linreg-stdev-channel-revert-01.pine +40 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-macd-12-26-9-line-signal-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-macd-histogram-reversal-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-macd-line-gt-signal-continuous-state-01.pine +23 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-map-regime-threshold-lookup-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-median-vs-ema-cross-01.pine +30 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-mfi-14-bands-20-80-01.pine +24 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-momentum-roc-zero-cross-01.pine +38 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-multi-indicator-score-composite-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-nvi-pvi-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-obv-ema-cross-01.pine +24 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-percentrank-mean-reversion-01.pine +43 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-pivot-array-unshift-pop-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-pivot-atr-stop-target-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-pivot-confirmed-break-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-pivot-point-levels-break-01.pine +28 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-pvt-ema-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-range-filter-var-band-01.pine +53 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rci-14-zero-cross-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi-bb-self-bands-01.pine +44 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi-ema-signal-cross-01.pine +32 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi-macd-and-continuous-state-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi14-bands-30-70-01.pine +26 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi14-cross-50-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi14-gt-50-continuous-state-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-rsi14-gt60-lt45-no-matrix-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-sar-flip-entry-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-sma-152-close-cross-01.pine +27 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-sma-dual-cross-01.pine +54 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-stdev-sma-expansion-break-01.pine +56 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-stoch-slow-k-d-cross-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-stochastic-rsi-cross-01.pine +39 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-str-match-regex-filter-01.pine +34 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-supertrend-adx-filter-01.pine +45 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-supertrend-direction-flip-01.pine +65 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-triple-sma-stack-latch-01.pine +46 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-tsi-25-13-signal-cross-01.pine +22 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-volume-spike-atr-breakout-01.pine +40 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-vwma-vs-sma-divergence-01.pine +33 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__ta-wpr-14-bands-01.pine +22 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__timeframe-main-period-self-adaptive-01.pine +34 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-calls-sibling-cumulative-01.pine +98 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-default-param-kwargs-01.pine +64 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-drives-strategy-entry-01.pine +62 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-extra-primitive-args-01.pine +42 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-feeds-strategy-exit-prices-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-in-for-loop-01.pine +55 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-in-if-else-branch-01.pine +65 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-in-switch-arms-01.pine +64 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-in-while-loop-01.pine +58 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-mutating-self-ref-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-on-array-element-01.pine +98 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-reads-strategy-state-01.pine +53 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-receives-ta-series-param-01.pine +57 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-scalar-return-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-tuple-return-destructure-01.pine +61 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-udt-return-from-func-01.pine +67 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-uses-history-globals-01.pine +60 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-uses-math-funcs-01.pine +59 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-uses-na-nz-fixnan-01.pine +50 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-var-instance-streak-01.pine +51 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-method-windowed-method-chain-01.pine +78 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__udt-regime-stack-stress-01.pine +186 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__vwap-bands-breakout-1sigma-01.pine +21 -0
- pineforge_codegen-0.7.2/tests/gate-corpus/ok/validation__vwap-bands-mean-reversion-2sigma-01.pine +23 -0
- pineforge_codegen-0.7.2/tests/test_codegen_determinism.py +136 -0
- pineforge_codegen-0.7.2/tests/test_import_all.py +34 -0
- pineforge_codegen-0.7.0/VERSION +0 -1
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/.github/dependabot.yml +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/CLAUDE.md +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/LEGAL.md +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/LICENSE +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/README.md +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/docs/codegen-coverage-gaps.md +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/__init__.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/__init__.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/base.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/call_handlers.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/contracts.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/diagnostics.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/tables.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/analyzer/types.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/ast_nodes.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/__init__.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/emit_top.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/helpers.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/helpers_syminfo.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/input.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/security.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/ta.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/tables.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/types.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/visit_call.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/visit_expr.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/codegen/visit_stmt.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/errors.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/lexer.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/parser.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/pragmas.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/signatures.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/support_checker.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/symbols.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/tokens.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/pineforge_codegen/tv_input_choices.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/__init__.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/_compile.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/golden/matrix_eigen_pca.cpp +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_analyzer.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_analyzer_matrix_inference.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_analyzer_ta_return_types.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_audit_fixes.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_fallthrough_guards.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_golden.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_input_getters.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_matrix_typed.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_codegen_new.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_compile_corpus.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_compile_smoke.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_errors.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_input_time_int64.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_int64_time_storage.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_lexer.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_official_surface.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_parser.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_security_tf_literal.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_signatures.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_chart_visible_bar_time.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_color_cast.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_const_namespaces.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_dividends_earnings.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_footprint.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_input_color.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_input_source.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_matrix.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_security_adjustment.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_syminfo_gap_fields.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_timeframe_from_seconds.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_varip.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_support_checker_volume_row.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_symbols.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_ta_official_surface.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_transpile_division.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_transpile_enum_order.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_transpile_pf_trace.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_transpile_tr_handle_na.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_transpiler_matrix_kwargs.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_typespec_matrix.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_udt_drawing_field_cleanup.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_unsupported_reporting.py +0 -0
- {pineforge_codegen-0.7.0 → pineforge_codegen-0.7.2}/tests/test_vwap_tuple_unpack.py +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Pyodide Gate
|
|
2
|
+
|
|
3
|
+
# Differential parity gate: the transpiler in real wasm32 Pyodide must match
|
|
4
|
+
# native CPython on every corpus input (success + failure). Heavier than the
|
|
5
|
+
# unit matrix (loads Pyodide), so: on demand, nightly, and on PRs that touch the
|
|
6
|
+
# gate itself. It does NOT block releases yet — that wiring is Phase 3.
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "27 5 * * *" # nightly 05:27 UTC
|
|
11
|
+
pull_request:
|
|
12
|
+
paths:
|
|
13
|
+
- "gate/**"
|
|
14
|
+
- "tests/gate-corpus/**"
|
|
15
|
+
- "package.json"
|
|
16
|
+
- "package-lock.json"
|
|
17
|
+
- ".github/workflows/gate.yml"
|
|
18
|
+
- "pineforge_codegen/**"
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: gate-${{ github.ref }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
gate:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
env:
|
|
31
|
+
PYTHONHASHSEED: "0"
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
34
|
+
|
|
35
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.14"
|
|
38
|
+
|
|
39
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
40
|
+
with:
|
|
41
|
+
node-version: "22"
|
|
42
|
+
|
|
43
|
+
- name: Install codegen (native oracle) + node deps
|
|
44
|
+
run: |
|
|
45
|
+
python -m pip install -e .
|
|
46
|
+
npm ci
|
|
47
|
+
|
|
48
|
+
- name: Selftest (comparator catches divergences)
|
|
49
|
+
run: npm run gate:selftest
|
|
50
|
+
|
|
51
|
+
- name: Run differential gate (full corpus)
|
|
52
|
+
run: npm run gate:full
|
|
53
|
+
|
|
54
|
+
- name: Upload release.json (derived versions, for Phase 3 handoff)
|
|
55
|
+
if: always()
|
|
56
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
57
|
+
with:
|
|
58
|
+
name: release-json
|
|
59
|
+
path: release.json
|
|
60
|
+
if-no-files-found: ignore
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Publish codegen-pyodide
|
|
2
|
+
|
|
3
|
+
# Builds @pineforge/codegen-pyodide from the GATE-VALIDATED archive and publishes
|
|
4
|
+
# it via npm OIDC Trusted Publishing (mirrors pineforge-codegen-mcp/publish.yml).
|
|
5
|
+
# Auto-release: a `v*` tag push (e.g. created by release.yml) publishes for real,
|
|
6
|
+
# gate-blocked. workflow_dispatch defaults to a DRY RUN (set dry_run=false to
|
|
7
|
+
# publish manually). Publishing only happens after the gate passes.
|
|
8
|
+
on:
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
inputs:
|
|
11
|
+
dry_run:
|
|
12
|
+
description: "npm publish --dry-run (default true). Set false to actually publish."
|
|
13
|
+
type: boolean
|
|
14
|
+
default: true
|
|
15
|
+
push:
|
|
16
|
+
tags: ["v*"]
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
id-token: write # npm OIDC Trusted Publishing
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: publish-pyodide-${{ github.ref }}
|
|
24
|
+
cancel-in-progress: false
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
publish:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
env:
|
|
30
|
+
PYTHONHASHSEED: "0"
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
33
|
+
|
|
34
|
+
# Tag push must match VERSION (mirrors mcp). Skipped for dispatch.
|
|
35
|
+
- name: Verify tag matches VERSION
|
|
36
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
37
|
+
env:
|
|
38
|
+
TAG_NAME: ${{ github.ref_name }}
|
|
39
|
+
run: |
|
|
40
|
+
tag="${TAG_NAME#v}"; file="$(tr -d '[:space:]' < VERSION)"
|
|
41
|
+
if [ "$tag" != "$file" ]; then
|
|
42
|
+
echo "::error::tag '$TAG_NAME' != VERSION '$file'"; exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
46
|
+
with:
|
|
47
|
+
python-version: "3.14"
|
|
48
|
+
|
|
49
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
50
|
+
with:
|
|
51
|
+
node-version: "22"
|
|
52
|
+
registry-url: https://registry.npmjs.org
|
|
53
|
+
|
|
54
|
+
# npm OIDC Trusted Publishing needs npm >= 11.5.1 (newer than Node 22's npm;
|
|
55
|
+
# npm docs + spec §7 require >= 11.5.1).
|
|
56
|
+
- run: npm install -g npm@11.5.1
|
|
57
|
+
|
|
58
|
+
- name: Install + run the gate (publish only ships gate-validated bytes)
|
|
59
|
+
run: |
|
|
60
|
+
python -m pip install -e .
|
|
61
|
+
npm ci
|
|
62
|
+
npm run gate:selftest
|
|
63
|
+
npm run gate:full
|
|
64
|
+
|
|
65
|
+
- name: Assemble the package
|
|
66
|
+
run: node scripts/build-npm-package.mjs
|
|
67
|
+
|
|
68
|
+
- name: Publish (real on tag push or dispatch dry_run=false; dry-run otherwise)
|
|
69
|
+
working-directory: npm
|
|
70
|
+
env:
|
|
71
|
+
EVENT: ${{ github.event_name }}
|
|
72
|
+
DRY_RUN: ${{ inputs.dry_run }}
|
|
73
|
+
run: |
|
|
74
|
+
if [ "$EVENT" = "push" ] || { [ "$EVENT" = "workflow_dispatch" ] && [ "$DRY_RUN" = "false" ]; }; then
|
|
75
|
+
echo "Publishing for real (--access=public)"
|
|
76
|
+
npm publish --access=public
|
|
77
|
+
else
|
|
78
|
+
echo "DRY RUN (a v* tag push or dispatch with dry_run=false publishes for real)"
|
|
79
|
+
npm publish --dry-run --access=public
|
|
80
|
+
fi
|
|
@@ -36,8 +36,9 @@ jobs:
|
|
|
36
36
|
release:
|
|
37
37
|
runs-on: ubuntu-latest
|
|
38
38
|
env:
|
|
39
|
-
BUMP:
|
|
40
|
-
OVERRIDE:
|
|
39
|
+
BUMP: ${{ inputs.bump }}
|
|
40
|
+
OVERRIDE: ${{ inputs.override }}
|
|
41
|
+
PYTHONHASHSEED: "0" # deterministic gate runtime (match gate.yml)
|
|
41
42
|
steps:
|
|
42
43
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
43
44
|
with:
|
|
@@ -83,7 +84,22 @@ jobs:
|
|
|
83
84
|
|
|
84
85
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
85
86
|
with:
|
|
86
|
-
python-version: "3.
|
|
87
|
+
python-version: "3.14" # match the gate's runtime
|
|
88
|
+
|
|
89
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
90
|
+
with:
|
|
91
|
+
node-version: "22"
|
|
92
|
+
|
|
93
|
+
# Conformance gate (BLOCKING): the differential parity gate must pass
|
|
94
|
+
# before anything is built, published, or tagged. A gate-broken codegen
|
|
95
|
+
# fails the release here — nothing reaches PyPI, no tag is pushed (so the
|
|
96
|
+
# tag->npm trigger never fires), and no GitHub Release is created.
|
|
97
|
+
- name: Run conformance gate (blocking)
|
|
98
|
+
run: |
|
|
99
|
+
python -m pip install -e .
|
|
100
|
+
npm ci
|
|
101
|
+
npm run gate:selftest
|
|
102
|
+
npm run gate:full
|
|
87
103
|
|
|
88
104
|
- name: Build sdist + wheel
|
|
89
105
|
run: |
|
|
@@ -91,8 +107,16 @@ jobs:
|
|
|
91
107
|
python -m build
|
|
92
108
|
ls -l dist/
|
|
93
109
|
|
|
94
|
-
#
|
|
95
|
-
#
|
|
110
|
+
# Publish to PyPI BEFORE the tag is pushed. The tag push triggers
|
|
111
|
+
# publish-pyodide.yml (npm), so PyPI must land first — otherwise a PyPI
|
|
112
|
+
# failure would leave npm shipping a version PyPI never got.
|
|
113
|
+
- name: Publish to PyPI
|
|
114
|
+
if: ${{ !inputs.dry_run }}
|
|
115
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
|
|
116
|
+
|
|
117
|
+
# Commit + tag + push AFTER PyPI succeeds. The `git push --tags` triggers
|
|
118
|
+
# publish-pyodide.yml for npm (which re-runs the gate — defense in depth),
|
|
119
|
+
# so the tag only exists once the gate passed and PyPI published.
|
|
96
120
|
- name: Commit + tag + push
|
|
97
121
|
if: ${{ !inputs.dry_run }}
|
|
98
122
|
env:
|
|
@@ -105,10 +129,6 @@ jobs:
|
|
|
105
129
|
git tag "v${NEW_VERSION}"
|
|
106
130
|
git push origin HEAD --tags
|
|
107
131
|
|
|
108
|
-
- name: Publish to PyPI
|
|
109
|
-
if: ${{ !inputs.dry_run }}
|
|
110
|
-
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
|
|
111
|
-
|
|
112
132
|
- name: Create GitHub Release
|
|
113
133
|
if: ${{ !inputs.dry_run }}
|
|
114
134
|
env:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
# First CI for this repo: run the test suite on every push and PR across the
|
|
4
|
+
# supported CPython range (the floor is 3.11; the ceiling tracks the Pyodide
|
|
5
|
+
# target's CPython, currently 3.14). Engine-dependent compile tests skip
|
|
6
|
+
# automatically on the runner (no engine checkout / no Eigen / no compiler env).
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
pull_request:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: test-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
pytest:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
26
|
+
env:
|
|
27
|
+
PYTHONHASHSEED: "0" # determinism; lockstep with the Phase 2 Pyodide gate
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
30
|
+
|
|
31
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
|
|
35
|
+
- name: Install (with dev extras)
|
|
36
|
+
run: python -m pip install -e ".[dev]"
|
|
37
|
+
|
|
38
|
+
- name: Run test suite
|
|
39
|
+
# No engine present on the runner -> compile tests skip via
|
|
40
|
+
# pytest.mark.skipif(not have_compile_env()). This validates the
|
|
41
|
+
# pure-Python transpile path across the matrix.
|
|
42
|
+
run: python -m pytest -q
|
|
@@ -56,8 +56,6 @@ pineforge_codegen/**/*.cpp
|
|
|
56
56
|
# ─── Node / TypeScript ─────────────────────────────────────────────────────
|
|
57
57
|
node_modules/
|
|
58
58
|
**/node_modules/
|
|
59
|
-
package-lock.json
|
|
60
|
-
**/package-lock.json
|
|
61
59
|
yarn.lock
|
|
62
60
|
pnpm-lock.yaml
|
|
63
61
|
npm-debug.log*
|
|
@@ -120,3 +118,14 @@ temp/
|
|
|
120
118
|
# cloud/mcp-local/ was extracted to a public repo:
|
|
121
119
|
# https://github.com/fullpass-4pass/pineforge-codegen-mcp
|
|
122
120
|
# Don't bring it back here.
|
|
121
|
+
|
|
122
|
+
# ─── Gate output ───────────────────────────────────────────────────────────
|
|
123
|
+
/release.json
|
|
124
|
+
|
|
125
|
+
# @pineforge/codegen-pyodide built payload (assembled at publish time)
|
|
126
|
+
/npm/pineforge_codegen-*.tar.gz
|
|
127
|
+
/npm/pineforge_codegen/
|
|
128
|
+
/npm/tables.json
|
|
129
|
+
/npm/release.json
|
|
130
|
+
/npm/transpile.worker.mjs
|
|
131
|
+
/npm/glue.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pineforge-codegen
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
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
|
|
@@ -211,6 +211,7 @@ Classifier: License :: Free for non-commercial use
|
|
|
211
211
|
Classifier: Programming Language :: Python :: 3.11
|
|
212
212
|
Classifier: Programming Language :: Python :: 3.12
|
|
213
213
|
Classifier: Programming Language :: Python :: 3.13
|
|
214
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
214
215
|
Classifier: Topic :: Office/Business :: Financial
|
|
215
216
|
Requires-Python: >=3.11
|
|
216
217
|
Provides-Extra: dev
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
314.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.7.2
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Pure, side-effect-free comparator for the gate. Both run-gate.mjs (the runner)
|
|
2
|
+
// and selftest.mjs (the canary) import this — so importing it never triggers a
|
|
3
|
+
// gate run. Each side is {json: "<transpile_json string>"} (normal return) or
|
|
4
|
+
// {unexpected: "Type: msg"} (non-CompileError exception). Returns a mismatch
|
|
5
|
+
// string, or null if the two sides agree.
|
|
6
|
+
export function compareResults(name, native, browser) {
|
|
7
|
+
if (!native) return `${name}: oracle produced no result`;
|
|
8
|
+
if (!browser) return `${name}: pyodide produced no result`;
|
|
9
|
+
if (native.unexpected || browser.unexpected) {
|
|
10
|
+
if (native.unexpected !== browser.unexpected) {
|
|
11
|
+
return `${name}: unexpected-exception mismatch\n native : ${native.unexpected ?? "<none>"}\n pyodide: ${browser.unexpected ?? "<none>"}`;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
if (native.json !== browser.json) {
|
|
16
|
+
let detail = "";
|
|
17
|
+
try {
|
|
18
|
+
const n = JSON.parse(native.json);
|
|
19
|
+
const b = JSON.parse(browser.json);
|
|
20
|
+
if (n.ok !== b.ok) detail = `verdict ${b.ok} (pyodide) != ${n.ok} (native)`;
|
|
21
|
+
else if (n.ok) detail = "C++ output differs";
|
|
22
|
+
else detail = `error/diagnostics differ\n native : ${native.json}\n pyodide: ${browser.json}`;
|
|
23
|
+
} catch {
|
|
24
|
+
detail = `raw json differs\n native : ${native.json}\n pyodide: ${browser.json}`;
|
|
25
|
+
}
|
|
26
|
+
return `${name}: ${detail}`;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Expected verdict for a corpus branch: "ok/*" fixtures must transpile
|
|
32
|
+
// successfully (result.ok === true), "err/*" fixtures must be rejected
|
|
33
|
+
// (result.ok === false). Anything else — the wrong verdict, an unparseable
|
|
34
|
+
// payload, or an unexpected (non-CompileError) exception — is a gate failure
|
|
35
|
+
// even when native and wasm agree (two identical crashes must NOT pass).
|
|
36
|
+
//
|
|
37
|
+
// This is intentionally separate from compareResults so the gate enforces BOTH
|
|
38
|
+
// (a) native↔wasm parity and (b) the right answer. `side` is {json} or
|
|
39
|
+
// {unexpected}; `expectOk` is true for "ok", false for "err".
|
|
40
|
+
function verdictOf(side) {
|
|
41
|
+
if (!side) return { kind: "missing" };
|
|
42
|
+
if (side.unexpected) return { kind: "unexpected", detail: side.unexpected };
|
|
43
|
+
try {
|
|
44
|
+
const v = JSON.parse(side.json);
|
|
45
|
+
if (typeof v.ok !== "boolean") return { kind: "malformed", detail: side.json };
|
|
46
|
+
return { kind: "verdict", ok: v.ok };
|
|
47
|
+
} catch {
|
|
48
|
+
return { kind: "malformed", detail: side.json };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Returns a failure string if either side does not match the expected verdict
|
|
53
|
+
// for the fixture's branch, or null if both sides produced the expected verdict.
|
|
54
|
+
export function checkExpectedVerdict(name, expectOk, native, browser) {
|
|
55
|
+
for (const [label, side] of [["native", native], ["pyodide", browser]]) {
|
|
56
|
+
const r = verdictOf(side);
|
|
57
|
+
if (r.kind === "missing") return `${name}: ${label} produced no result`;
|
|
58
|
+
if (r.kind === "unexpected") {
|
|
59
|
+
return `${name}: ${label} threw an unexpected exception (expected ok=${expectOk}): ${r.detail}`;
|
|
60
|
+
}
|
|
61
|
+
if (r.kind === "malformed") {
|
|
62
|
+
return `${name}: ${label} returned a malformed result (expected ok=${expectOk}): ${r.detail}`;
|
|
63
|
+
}
|
|
64
|
+
if (r.ok !== expectOk) {
|
|
65
|
+
return `${name}: ${label} verdict ok=${r.ok} but corpus dir expects ok=${expectOk}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# CANONICAL GLUE — runtime-equivalent to the body of PY_GLUE in
|
|
2
|
+
# pineforge-app/apps/web/lib/pyodide-transpiler/glue.ts (produces identical
|
|
3
|
+
# transpile_json output). The browser worker and this gate run the same logic,
|
|
4
|
+
# so the gate's parity guarantee reflects shipped behavior.
|
|
5
|
+
# (Phase 3: ship this from the npm package so there is one source of truth.)
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
if "/codegen" not in sys.path:
|
|
10
|
+
sys.path.insert(0, "/codegen")
|
|
11
|
+
|
|
12
|
+
from pineforge_codegen import transpile
|
|
13
|
+
from pineforge_codegen.errors import CompileError
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def transpile_json(source: str) -> str:
|
|
17
|
+
try:
|
|
18
|
+
cpp = transpile(source)
|
|
19
|
+
except CompileError as e:
|
|
20
|
+
diags = []
|
|
21
|
+
for d in e.diagnostics:
|
|
22
|
+
loc = d.location
|
|
23
|
+
message = d.message + " — " + d.hint if getattr(d, "hint", None) else d.message
|
|
24
|
+
entry = {
|
|
25
|
+
"line": loc.line if loc else 1,
|
|
26
|
+
"col": loc.col if loc else 1,
|
|
27
|
+
"message": message,
|
|
28
|
+
"severity": getattr(d.level, "value", "error"),
|
|
29
|
+
}
|
|
30
|
+
end_col = getattr(loc, "end_col", None) if loc else None
|
|
31
|
+
if end_col is not None:
|
|
32
|
+
entry["endCol"] = end_col
|
|
33
|
+
diags.append(entry)
|
|
34
|
+
return json.dumps({"ok": False, "error": str(e), "diagnostics": diags})
|
|
35
|
+
return json.dumps({"ok": True, "cpp": cpp})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Native-CPython oracle for the conformance gate.
|
|
2
|
+
|
|
3
|
+
Reads a JSON array of {"name","src"} from stdin, runs the CANONICAL glue's
|
|
4
|
+
transpile_json on each, and writes a JSON object {name: result} to stdout.
|
|
5
|
+
Each result is {"json": <transpile_json string>} on a normal return, or
|
|
6
|
+
{"unexpected": "<ExcType>: <msg>"} if transpile_json raised something other
|
|
7
|
+
than CompileError (CompileError is already encoded inside the json string).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
GLUE = os.path.join(os.path.dirname(__file__), "glue.py")
|
|
17
|
+
exec(compile(open(GLUE).read(), GLUE, "exec")) # defines transpile_json # noqa: S102
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main() -> None:
|
|
21
|
+
items = json.load(sys.stdin)
|
|
22
|
+
out: dict[str, dict] = {}
|
|
23
|
+
for item in items:
|
|
24
|
+
name = item["name"]
|
|
25
|
+
src = item["src"]
|
|
26
|
+
try:
|
|
27
|
+
out[name] = {"json": transpile_json(src)} # noqa: F821 — from exec
|
|
28
|
+
except Exception as exc: # noqa: BLE001 — capture for parity, don't throw
|
|
29
|
+
out[name] = {"unexpected": f"{type(exc).__name__}: {exc}"}
|
|
30
|
+
json.dump(out, sys.stdout)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
main()
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Differential parity gate: run the transpiler in real wasm32 Pyodide and assert
|
|
2
|
+
// it behaves identically to native CPython on EVERY corpus input — success
|
|
3
|
+
// (byte-identical cpp) AND failure (same verdict/error/diagnostics + same
|
|
4
|
+
// unexpected-exception type+message). Also writes release.json.
|
|
5
|
+
//
|
|
6
|
+
// node gate/run-gate.mjs # smoke: all err + first N ok fixtures
|
|
7
|
+
// GATE_FULL=1 node gate/run-gate.mjs # entire corpus
|
|
8
|
+
//
|
|
9
|
+
// Exit 0 = parity holds; exit 1 = mismatch(es) or setup failure.
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { checkExpectedVerdict, compareResults } from "./compare.mjs";
|
|
17
|
+
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const ROOT = join(HERE, "..");
|
|
21
|
+
const CORPUS = join(ROOT, "tests", "gate-corpus");
|
|
22
|
+
const SCRATCH = join(HERE, ".scratch");
|
|
23
|
+
const GLUE = readFileSync(join(HERE, "glue.py"), "utf8");
|
|
24
|
+
const PYTHON = process.env.GATE_PYTHON ?? "python3";
|
|
25
|
+
const OK_CAP = process.env.GATE_FULL ? Infinity : 60;
|
|
26
|
+
|
|
27
|
+
function branchItems(branch) {
|
|
28
|
+
const dir = join(CORPUS, branch);
|
|
29
|
+
if (!existsSync(dir)) return [];
|
|
30
|
+
return readdirSync(dir)
|
|
31
|
+
.filter((x) => x.endsWith(".pine"))
|
|
32
|
+
.sort()
|
|
33
|
+
.map((f) => ({ name: `${branch}/${f}`, src: readFileSync(join(dir, f), "utf8") }));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function main() {
|
|
37
|
+
const okItems = branchItems("ok");
|
|
38
|
+
const errItems = branchItems("err");
|
|
39
|
+
if (okItems.length + errItems.length === 0) {
|
|
40
|
+
console.error("gate: empty corpus at tests/gate-corpus/{ok,err}");
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// ALWAYS include the (small) err branch so the smoke run exercises the failure
|
|
44
|
+
// path; cap only the large ok branch.
|
|
45
|
+
const items = [
|
|
46
|
+
...(Number.isFinite(OK_CAP) ? okItems.slice(0, OK_CAP) : okItems),
|
|
47
|
+
...errItems,
|
|
48
|
+
];
|
|
49
|
+
console.log(
|
|
50
|
+
`gate: ${items.length} fixtures (ok=${Math.min(okItems.length, OK_CAP)}/${okItems.length}, err=${errItems.length}, GATE_FULL=${process.env.GATE_FULL ? "1" : "0"})`,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// 1. Pack the in-repo source into an archive (excluding __pycache__).
|
|
54
|
+
mkdirSync(SCRATCH, { recursive: true });
|
|
55
|
+
const archive = join(SCRATCH, "pineforge_codegen.tar.gz");
|
|
56
|
+
const tar = require("tar");
|
|
57
|
+
await tar.create(
|
|
58
|
+
{ gzip: true, file: archive, cwd: ROOT, portable: true, filter: (p) => !p.includes("__pycache__") },
|
|
59
|
+
["pineforge_codegen"],
|
|
60
|
+
);
|
|
61
|
+
const archiveBytes = readFileSync(archive);
|
|
62
|
+
|
|
63
|
+
// 2. Load Pyodide, unpack, run glue.
|
|
64
|
+
const { loadPyodide } = await import("pyodide");
|
|
65
|
+
const indexURL = dirname(require.resolve("pyodide/package.json"));
|
|
66
|
+
const pyodide = await loadPyodide({ indexURL });
|
|
67
|
+
const u8 = new Uint8Array(archiveBytes.buffer, archiveBytes.byteOffset, archiveBytes.byteLength);
|
|
68
|
+
pyodide.unpackArchive(u8, "gztar", { extractDir: "/codegen" });
|
|
69
|
+
pyodide.runPython(GLUE);
|
|
70
|
+
const transpileJson = pyodide.globals.get("transpile_json");
|
|
71
|
+
|
|
72
|
+
// 3. Native oracle (one process, whole corpus). PYTHONHASHSEED pinned for
|
|
73
|
+
// determinism per spec §6.1.
|
|
74
|
+
const oracleOut = execFileSync(PYTHON, [join(HERE, "oracle.py")], {
|
|
75
|
+
input: JSON.stringify(items),
|
|
76
|
+
env: { ...process.env, PYTHONPATH: ROOT, PYTHONHASHSEED: "0" },
|
|
77
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
});
|
|
80
|
+
const native = JSON.parse(oracleOut);
|
|
81
|
+
|
|
82
|
+
// 4. Pyodide side + compare. The gate enforces TWO independent properties:
|
|
83
|
+
// (a) native↔wasm parity (compareResults) and
|
|
84
|
+
// (b) the EXPECTED verdict by corpus dir (checkExpectedVerdict): ok/* must
|
|
85
|
+
// succeed, err/* must be rejected. A purely differential check would
|
|
86
|
+
// let two identical crashes — or an ok/ fixture that erroneously errors
|
|
87
|
+
// — slip through; (b) closes that gap.
|
|
88
|
+
const mismatches = [];
|
|
89
|
+
const verdictFailures = [];
|
|
90
|
+
for (const { name, src } of items) {
|
|
91
|
+
let browser;
|
|
92
|
+
try {
|
|
93
|
+
browser = { json: transpileJson(src) };
|
|
94
|
+
} catch (err) {
|
|
95
|
+
browser = { unexpected: `${err?.constructor?.name ?? "Error"}: ${err?.message ?? String(err)}` };
|
|
96
|
+
}
|
|
97
|
+
const m = compareResults(name, native[name], browser);
|
|
98
|
+
if (m) mismatches.push(m);
|
|
99
|
+
const expectOk = name.startsWith("ok/");
|
|
100
|
+
const v = checkExpectedVerdict(name, expectOk, native[name], browser);
|
|
101
|
+
if (v) verdictFailures.push(v);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 5. release.json (versions derived from the loaded Pyodide lock).
|
|
105
|
+
const lock = require("pyodide/pyodide-lock.json");
|
|
106
|
+
const codegen = readFileSync(join(ROOT, "VERSION"), "utf8").trim();
|
|
107
|
+
const pyodideVer = readFileSync(join(ROOT, "PYODIDE_TARGET"), "utf8").trim();
|
|
108
|
+
const release = {
|
|
109
|
+
codegen,
|
|
110
|
+
pyodide: pyodideVer,
|
|
111
|
+
python: lock.info.python,
|
|
112
|
+
emscripten: lock.info.platform,
|
|
113
|
+
sha256: createHash("sha256").update(archiveBytes).digest("hex"),
|
|
114
|
+
};
|
|
115
|
+
writeFileSync(join(ROOT, "release.json"), JSON.stringify(release, null, 2) + "\n");
|
|
116
|
+
console.log("gate: release.json ->", JSON.stringify(release));
|
|
117
|
+
|
|
118
|
+
if (mismatches.length || verdictFailures.length) {
|
|
119
|
+
if (mismatches.length) {
|
|
120
|
+
console.error(`gate: ${mismatches.length} PARITY MISMATCH(es):\n` + mismatches.join("\n"));
|
|
121
|
+
}
|
|
122
|
+
if (verdictFailures.length) {
|
|
123
|
+
console.error(`gate: ${verdictFailures.length} VERDICT FAILURE(s) (wrong ok/err result):\n` + verdictFailures.join("\n"));
|
|
124
|
+
}
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
console.log(`gate: PARITY OK over ${items.length} fixtures (verdicts asserted: ok/* succeed, err/* rejected)`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
main().catch((e) => {
|
|
131
|
+
console.error("gate: fatal", e);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Canary: prove the gate's checks actually catch divergences. Imports the PURE
|
|
2
|
+
// comparator + verdict checker (gate/compare.mjs) so it runs in <1s without
|
|
3
|
+
// loading Pyodide. Covers BOTH (a) native↔wasm parity (compareResults) and
|
|
4
|
+
// (b) expected-verdict-by-corpus-dir (checkExpectedVerdict).
|
|
5
|
+
import { checkExpectedVerdict, compareResults } from "./compare.mjs";
|
|
6
|
+
|
|
7
|
+
const OK = '{"ok":true,"cpp":"X"}';
|
|
8
|
+
const ERR = '{"ok":false,"error":"e","diagnostics":[]}';
|
|
9
|
+
|
|
10
|
+
// --- (a) differential comparator cases: [name, native, browser, mustFlag] ---
|
|
11
|
+
const cmpCases = [
|
|
12
|
+
["same-ok", { json: OK }, { json: OK }, false],
|
|
13
|
+
["cpp-differs", { json: '{"ok":true,"cpp":"X"}' }, { json: '{"ok":true,"cpp":"Y"}' }, true],
|
|
14
|
+
["verdict-differs", { json: OK }, { json: ERR }, true],
|
|
15
|
+
["error-differs", { json: '{"ok":false,"error":"a","diagnostics":[]}' }, { json: '{"ok":false,"error":"b","diagnostics":[]}' }, true],
|
|
16
|
+
["unexpected-one-side", { json: OK }, { unexpected: "TypeError: boom" }, true],
|
|
17
|
+
["unexpected-both-same", { unexpected: "TypeError: boom" }, { unexpected: "TypeError: boom" }, false],
|
|
18
|
+
["unexpected-both-diff", { unexpected: "TypeError: a" }, { unexpected: "ValueError: b" }, true],
|
|
19
|
+
["missing-native", undefined, { json: OK }, true],
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
// --- (b) expected-verdict cases: [name, expectOk, native, browser, mustFlag] ---
|
|
23
|
+
// A native↔wasm match with the WRONG verdict (e.g. ok/ that errors, or a shared
|
|
24
|
+
// unexpected exception) must FAIL even though compareResults would pass it.
|
|
25
|
+
const verdictCases = [
|
|
26
|
+
["ok/good", true, { json: OK }, { json: OK }, false],
|
|
27
|
+
["err/bad", false, { json: ERR }, { json: ERR }, false],
|
|
28
|
+
["ok/that-errors-both-sides", true, { json: ERR }, { json: ERR }, true],
|
|
29
|
+
["err/that-succeeds-both-sides", false, { json: OK }, { json: OK }, true],
|
|
30
|
+
["ok/unexpected-both-same", true, { unexpected: "TypeError: boom" }, { unexpected: "TypeError: boom" }, true],
|
|
31
|
+
["err/unexpected-both-same", false, { unexpected: "TypeError: boom" }, { unexpected: "TypeError: boom" }, true],
|
|
32
|
+
["ok/native-wrong-only", true, { json: ERR }, { json: OK }, true],
|
|
33
|
+
["ok/pyodide-wrong-only", true, { json: OK }, { json: ERR }, true],
|
|
34
|
+
["ok/missing-native", true, undefined, { json: OK }, true],
|
|
35
|
+
["ok/malformed", true, { json: "not json" }, { json: OK }, true],
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
let failed = 0;
|
|
39
|
+
for (const [name, n, b, mustFlag] of cmpCases) {
|
|
40
|
+
const flagged = compareResults(name, n, b) !== null;
|
|
41
|
+
if (flagged !== mustFlag) {
|
|
42
|
+
console.error(`selftest FAIL (compareResults): ${name} expected mustFlag=${mustFlag} got ${flagged}`);
|
|
43
|
+
failed++;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const [name, expectOk, n, b, mustFlag] of verdictCases) {
|
|
47
|
+
const flagged = checkExpectedVerdict(name, expectOk, n, b) !== null;
|
|
48
|
+
if (flagged !== mustFlag) {
|
|
49
|
+
console.error(`selftest FAIL (checkExpectedVerdict): ${name} expected mustFlag=${mustFlag} got ${flagged}`);
|
|
50
|
+
failed++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (failed) {
|
|
54
|
+
console.error(`gate selftest: ${failed} case(s) failed`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
console.log(`gate selftest: ${cmpCases.length} comparator + ${verdictCases.length} verdict cases OK`);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @pineforge/codegen-pyodide
|
|
2
|
+
|
|
3
|
+
Gate-validated Pyodide payload for the PineScript v6 → C++ transpiler. Built and
|
|
4
|
+
published from `pineforge-codegen-oss` by `.github/workflows/publish-pyodide.yml`.
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
- `pineforge_codegen-<version>.tar.gz` — the gate-validated archive (unpack into Pyodide).
|
|
8
|
+
- `pineforge_codegen/` — unpacked Python source (put on `PYTHONPATH` for Node oracle/grammar tooling).
|
|
9
|
+
- `tables.json` — introspected codegen tables (the app renders `tables.generated.ts` from this).
|
|
10
|
+
- `release.json` — `{ codegen, pyodide, python, emscripten, sha256 }`.
|
|
11
|
+
- `index.mjs` — `release`, `tables`, `archivePath`, `codegenSourceDir`.
|
|
12
|
+
|
|
13
|
+
## One-time bootstrap (maintainer, manual)
|
|
14
|
+
This is a NEW package; npm OIDC Trusted Publishing can only be configured after
|
|
15
|
+
the package exists:
|
|
16
|
+
1. Build locally: `npm run gate:full && node scripts/build-npm-package.mjs`.
|
|
17
|
+
2. From `npm/`, do the first publish with a granular npm token:
|
|
18
|
+
`npm publish --access=public` (one time).
|
|
19
|
+
3. On npmjs.com, configure the package's Trusted Publisher: GitHub Actions,
|
|
20
|
+
repo `pineforge-4pass/pineforge-codegen-oss`, workflow `publish-pyodide.yml`.
|
|
21
|
+
4. Thereafter releases publish via OIDC (no token): run `publish-pyodide.yml`
|
|
22
|
+
via **workflow_dispatch with `dry_run=false`**. NOTE: tag pushes currently run
|
|
23
|
+
a DRY-RUN only (a safe validation) — the sole real-publish path is dispatch +
|
|
24
|
+
`dry_run=false`. To switch to tag-driven releases later, change the publish
|
|
25
|
+
condition in the workflow.
|