openpinescript 0.0.0-stage → 0.1.1

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.
Files changed (103) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +332 -2
  3. package/dist/cli.mjs +108691 -0
  4. package/dist/index.cjs +108670 -0
  5. package/dist/index.mjs +108624 -0
  6. package/dist/types/index.d.ts +31 -0
  7. package/dist/types/parser/v1/generated/PineV1Lexer.d.ts +66 -0
  8. package/dist/types/parser/v1/generated/PineV1Parser.d.ts +555 -0
  9. package/dist/types/parser/v1/generated/PineV1ParserVisitor.d.ts +318 -0
  10. package/dist/types/parser/v1/index.d.ts +39 -0
  11. package/dist/types/parser/v2/generated/PineV2Lexer.d.ts +67 -0
  12. package/dist/types/parser/v2/generated/PineV2Parser.d.ts +568 -0
  13. package/dist/types/parser/v2/generated/PineV2ParserVisitor.d.ts +325 -0
  14. package/dist/types/parser/v2/index.d.ts +2 -0
  15. package/dist/types/parser/v3/generated/PineV3Lexer.d.ts +67 -0
  16. package/dist/types/parser/v3/generated/PineV3Parser.d.ts +568 -0
  17. package/dist/types/parser/v3/generated/PineV3ParserVisitor.d.ts +325 -0
  18. package/dist/types/parser/v3/index.d.ts +2 -0
  19. package/dist/types/parser/v4/generated/PineV4Lexer.d.ts +86 -0
  20. package/dist/types/parser/v4/generated/PineV4Parser.d.ts +673 -0
  21. package/dist/types/parser/v4/generated/PineV4ParserVisitor.d.ts +367 -0
  22. package/dist/types/parser/v4/index.d.ts +2 -0
  23. package/dist/types/parser/v5/generated/PineV5Lexer.d.ts +95 -0
  24. package/dist/types/parser/v5/generated/PineV5Parser.d.ts +964 -0
  25. package/dist/types/parser/v5/generated/PineV5ParserVisitor.d.ts +521 -0
  26. package/dist/types/parser/v5/index.d.ts +2 -0
  27. package/dist/types/parser/v6/generated/PineV6Lexer.d.ts +98 -0
  28. package/dist/types/parser/v6/generated/PineV6Parser.d.ts +984 -0
  29. package/dist/types/parser/v6/generated/PineV6ParserVisitor.d.ts +528 -0
  30. package/dist/types/parser/v6/index.d.ts +2 -0
  31. package/dist/types/runtime/v1/Series.d.ts +61 -0
  32. package/dist/types/runtime/v1/broker/Broker.d.ts +325 -0
  33. package/dist/types/runtime/v1/broker/index.d.ts +158 -0
  34. package/dist/types/runtime/v1/broker/val.d.ts +28 -0
  35. package/dist/types/runtime/v1/constDefault.d.ts +11 -0
  36. package/dist/types/runtime/v1/context.d.ts +1705 -0
  37. package/dist/types/runtime/v1/footprint.d.ts +32 -0
  38. package/dist/types/runtime/v1/index.d.ts +7 -0
  39. package/dist/types/runtime/v1/language-spec.d.ts +12 -0
  40. package/dist/types/runtime/v1/openTrades.d.ts +12 -0
  41. package/dist/types/runtime/v1/palette.d.ts +18 -0
  42. package/dist/types/runtime/v1/session.d.ts +482 -0
  43. package/dist/types/runtime/v1/sessions.d.ts +31 -0
  44. package/dist/types/runtime/v1/stateClone.d.ts +19 -0
  45. package/dist/types/runtime/v1/stdlib/alerts.d.ts +31 -0
  46. package/dist/types/runtime/v1/stdlib/arrays.d.ts +133 -0
  47. package/dist/types/runtime/v1/stdlib/barmerge.d.ts +27 -0
  48. package/dist/types/runtime/v1/stdlib/barstate.d.ts +79 -0
  49. package/dist/types/runtime/v1/stdlib/cast.d.ts +81 -0
  50. package/dist/types/runtime/v1/stdlib/chart.d.ts +283 -0
  51. package/dist/types/runtime/v1/stdlib/color.d.ts +51 -0
  52. package/dist/types/runtime/v1/stdlib/core.d.ts +162 -0
  53. package/dist/types/runtime/v1/stdlib/dataset.d.ts +36 -0
  54. package/dist/types/runtime/v1/stdlib/display.d.ts +50 -0
  55. package/dist/types/runtime/v1/stdlib/drawings.d.ts +407 -0
  56. package/dist/types/runtime/v1/stdlib/errors.d.ts +21 -0
  57. package/dist/types/runtime/v1/stdlib/font.d.ts +20 -0
  58. package/dist/types/runtime/v1/stdlib/footprint.d.ts +76 -0
  59. package/dist/types/runtime/v1/stdlib/format.d.ts +57 -0
  60. package/dist/types/runtime/v1/stdlib/index.d.ts +71 -0
  61. package/dist/types/runtime/v1/stdlib/input.d.ts +14 -0
  62. package/dist/types/runtime/v1/stdlib/inputs.d.ts +60 -0
  63. package/dist/types/runtime/v1/stdlib/late_members.d.ts +97 -0
  64. package/dist/types/runtime/v1/stdlib/logging.d.ts +31 -0
  65. package/dist/types/runtime/v1/stdlib/maps.d.ts +55 -0
  66. package/dist/types/runtime/v1/stdlib/math.d.ts +71 -0
  67. package/dist/types/runtime/v1/stdlib/matrix.d.ts +201 -0
  68. package/dist/types/runtime/v1/stdlib/metadata.d.ts +14 -0
  69. package/dist/types/runtime/v1/stdlib/mtf.d.ts +15 -0
  70. package/dist/types/runtime/v1/stdlib/renames.d.ts +117 -0
  71. package/dist/types/runtime/v1/stdlib/renames5.d.ts +113 -0
  72. package/dist/types/runtime/v1/stdlib/renames6.d.ts +81 -0
  73. package/dist/types/runtime/v1/stdlib/request.d.ts +207 -0
  74. package/dist/types/runtime/v1/stdlib/scale.d.ts +19 -0
  75. package/dist/types/runtime/v1/stdlib/session.d.ts +113 -0
  76. package/dist/types/runtime/v1/stdlib/sort_field.d.ts +12 -0
  77. package/dist/types/runtime/v1/stdlib/sources.d.ts +24 -0
  78. package/dist/types/runtime/v1/stdlib/str.d.ts +117 -0
  79. package/dist/types/runtime/v1/stdlib/strategy.d.ts +314 -0
  80. package/dist/types/runtime/v1/stdlib/syminfo.d.ts +209 -0
  81. package/dist/types/runtime/v1/stdlib/ta.d.ts +409 -0
  82. package/dist/types/runtime/v1/stdlib/time.d.ts +158 -0
  83. package/dist/types/runtime/v1/stdlib/trades.d.ts +108 -0
  84. package/dist/types/runtime/v1/stdlib/ui.d.ts +196 -0
  85. package/dist/types/runtime/v1/stdlib/v6_members.d.ts +68 -0
  86. package/dist/types/runtime/v1/timeframes.d.ts +139 -0
  87. package/dist/types/runtime/v1/zones.d.ts +30 -0
  88. package/dist/types/transpiler/common/index.d.ts +51 -0
  89. package/dist/types/transpiler/common/libraries.d.ts +29 -0
  90. package/dist/types/transpiler/common/parseErrors.d.ts +38 -0
  91. package/dist/types/transpiler/common/passes/ScopeAnalysis.d.ts +158 -0
  92. package/dist/types/transpiler/common/passes/TypeRules.d.ts +26 -0
  93. package/dist/types/transpiler/common/profiles/index.d.ts +96 -0
  94. package/dist/types/transpiler/common/version.d.ts +40 -0
  95. package/dist/types/transpiler/v1/ToJsVisitor.d.ts +720 -0
  96. package/dist/types/transpiler/v2/ToJsVisitor.d.ts +72 -0
  97. package/dist/types/transpiler/v3/ToJsVisitor.d.ts +87 -0
  98. package/dist/types/transpiler/v4/ToJsVisitor.d.ts +263 -0
  99. package/dist/types/transpiler/v5/ToJsVisitor.d.ts +1101 -0
  100. package/dist/types/transpiler/v6/ToJsVisitor.d.ts +237 -0
  101. package/dist/types/transpiler/v6/rules.d.ts +94 -0
  102. package/dist/types/utils/v2/common.d.ts +4 -0
  103. package/package.json +92 -4
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Pine Script v2 → JavaScript emitter.
3
+ *
4
+ * v2 inherits every line of emit logic from v1 and adds exactly one thing:
5
+ * reassignment with ':='.
6
+ *
7
+ * The operator is a v2 GRAMMAR addition (PineV2Lexer.g4 declares the token,
8
+ * PineV2Parser.g4 the rule), so v1 rejects `x := 1` as a syntax error — its
9
+ * grammar has never heard of the token. There is no "reassignment is not
10
+ * allowed in v1" guard anywhere, because v1 cannot reach one.
11
+ *
12
+ * SCOPE is the part a grammar cannot express, and the documented rule is a
13
+ * DECLARATION rule, not a scope one:
14
+ *
15
+ * "Pine now supports mutable variables! Use the ':=' operator to assign a new
16
+ * value to a variable that has already been defined."
17
+ * — TradingView release notes, Pine v2
18
+ * "A variable must be declared before you can set a value for it."
19
+ * — Expressions, declarations and statements (v3 manual, which documents
20
+ * ':=' as requiring only //@version=2)
21
+ *
22
+ * Neither source restricts ':=' by scope, and the corpus agrees: two published
23
+ * //@version=2 scripts reassign at script scope —
24
+ *
25
+ * longStopPrice = 0.0 gap_down_reversal_strategy
26
+ * longStopPrice := if (strategy.position_size > 0)
27
+ *
28
+ * if crossunder(corVix, -.1) or ... VIX_bonds_strategy
29
+ * signal1 := -100
30
+ *
31
+ * An earlier version of this file restricted ':=' to for-loop accumulators and
32
+ * rejected both. That restriction was inferred, not sourced, and it was wrong:
33
+ * TradingView compiled and published these scripts. What is enforced now is the
34
+ * rule the documentation actually states — assign only to a name that was
35
+ * declared.
36
+ *
37
+ * v3 inherits this guard unchanged. ':=' scope was never a v1→v2→v3 delta.
38
+ *
39
+ * ⚠ See the sourcing note in grammar/v2/PineV2Lexer.g4 on why ':=' is placed at v2
40
+ * rather than v1. If that turns out to be wrong, this class moves to v1 wholesale.
41
+ */
42
+ import type { PineVersion } from "../common/version.js";
43
+ import { V1ToJsVisitor } from "../v1/ToJsVisitor.js";
44
+ import { Var_assignContext, Global_stmt_contentContext, Local_stmt_contentContext } from "../../parser/v2/generated/PineV2Parser.js";
45
+ export type { Local_stmt_contentContext };
46
+ export declare class V2ToJsVisitor extends V1ToJsVisitor {
47
+ protected readonly version: PineVersion;
48
+ /**
49
+ * ':=' assigns to a variable "that has already been defined". Assigning to a
50
+ * name that is never declared is the `Undeclared identifier` error, which is
51
+ * how `if x==1 / y := 2` fails on TradingView.
52
+ *
53
+ * Scope is deliberately NOT checked — see the sourcing note at the top of this
54
+ * file. POSITION is not checked here either: forward references are legal in
55
+ * v2, and v3 rejects them through `enforceNoForwardReference`, which already
56
+ * sees this id because `visitVar_assign` visits it.
57
+ */
58
+ protected enforceDeclaredBeforeReassignment(ctx: Var_assignContext): void;
59
+ /** Handle: x := 1 */
60
+ visitVar_assign(ctx: Var_assignContext): string;
61
+ /**
62
+ * v2's global_stmt_content / local_stmt_content gained a `var_assign`
63
+ * alternative, so the statement dispatcher has to route it. Everything else
64
+ * falls through to the inherited implementation.
65
+ */
66
+ protected visitContent(ctx: Global_stmt_contentContext | Local_stmt_contentContext): string;
67
+ /**
68
+ * ':=' is a binding form too, so a function body ending in one returns the
69
+ * reassigned variable. v1 only knows about '='.
70
+ */
71
+ protected trailingValueName(content: Local_stmt_contentContext): string | null;
72
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Pine Script v3 → JavaScript emitter.
3
+ *
4
+ * ── THE WORKED EXAMPLE OF A VERSION DELTA ───────────────────────────────────
5
+ *
6
+ * v3 inherits every line of emit logic from v2 (and thus v1). This file
7
+ * contains ONLY what the v2→v3 migration guide documents:
8
+ *
9
+ * 1. A variable may not reference itself in its own '=' declaration.
10
+ * 2. An identifier may not be used before it is declared.
11
+ * 3. Bools no longer coerce to numbers in arithmetic.
12
+ * 4. A ':='-mutated variable may not be passed to security().
13
+ *
14
+ * Each is one `enforce*` method plus a two-line override that calls it and
15
+ * delegates to `super`. Nothing in v1 or v2 was touched to add any of them.
16
+ *
17
+ * Every one is a TIGHTENING. v3 relaxes nothing: an earlier draft listed
18
+ * "':=' becomes available at every scope" as a fifth delta, but v2 never had a
19
+ * scope restriction to lift — see the sourcing note in ../v2/ToJsVisitor.ts.
20
+ *
21
+ * The security() lookahead default also flips in v3, but that is a RUNTIME
22
+ * behaviour rather than an emit one — it lives in the v3 language profile and is
23
+ * read by runtime/v1/stdlib/mtf.ts.
24
+ *
25
+ * NOTE ON `:=` — inherited from v2 wholesale, operator and guard alike. v1
26
+ * rejects it as a syntax error because PineV1Lexer.g4 has no such token.
27
+ */
28
+ import type { ParseTree } from "antlr4ng";
29
+ import type { PineVersion } from "../common/version.js";
30
+ import { V2ToJsVisitor } from "../v2/ToJsVisitor.js";
31
+ import { Var_defContext, Add_exprContext, Mult_exprContext, Fun_callContext, IdContext } from "../../parser/v3/generated/PineV3Parser.js";
32
+ /** Anything carrying a source position (see the v1 base for why it is structural). */
33
+ interface SourceLocated {
34
+ start?: {
35
+ line: number;
36
+ column: number;
37
+ } | null;
38
+ }
39
+ export declare class V3ToJsVisitor extends V2ToJsVisitor {
40
+ protected readonly version: PineVersion;
41
+ /**
42
+ * `s = nz(s[1]) + close` was the v1/v2 state idiom. v3 requires declaring
43
+ * first (`s = 0.0`) and then assigning with ':='.
44
+ */
45
+ protected enforceNoSelfReference(name: string, value: ParseTree, ctx: SourceLocated): void;
46
+ visitVar_def(ctx: Var_defContext): string;
47
+ /** An identifier may not be used before its declaration. Checked lexically. */
48
+ protected enforceNoForwardReference(name: string, ctx: SourceLocated): void;
49
+ visitId(ctx: IdContext): string;
50
+ /**
51
+ * v1/v2 coerced true→1 and false→0; v3 requires an explicit `b ? 1 : 0`.
52
+ *
53
+ * Static detection only, and deliberately conservative — `isStaticallyBool`
54
+ * answers "provably bool", not "possibly bool". A false negative is caught by
55
+ * the runtime backstop in the arithmetic helpers; a false positive would
56
+ * reject valid code.
57
+ */
58
+ protected enforceNoBoolArithmetic(operand: ParseTree, ctx: SourceLocated, op: string): void;
59
+ /**
60
+ * The operator ADJACENT to operand `i`, in a flat `a + b - c` chain.
61
+ *
62
+ * Children alternate operand, operator, operand, …, so operand `i` is
63
+ * preceded by the operator at `i * 2 - 1`. Reading `getChild(1)`
64
+ * unconditionally named the FIRST operator every time, so `z = 1 + 2 - b`
65
+ * with a bool `b` reported "cannot use a bool as an operand of '+'" when the
66
+ * offending operator is '-'. Cosmetic, but a diagnostic that points at the
67
+ * wrong token sends the reader to the wrong place.
68
+ */
69
+ private operatorFor;
70
+ visitAdd_expr(ctx: Add_exprContext): string;
71
+ visitMult_expr(ctx: Mult_exprContext): string;
72
+ /**
73
+ * Its value at HTF evaluation time is not the value the chart context holds,
74
+ * so the result would be silently wrong. Wrap the calculation in a function.
75
+ */
76
+ protected enforceNoMutableSecurityArg(args: ParseTree | null, ctx: SourceLocated): void;
77
+ /**
78
+ * Does this security-family call carry the mutable-argument restriction?
79
+ *
80
+ * A seam, because v5 splits the family: `request.security_lower_tf` keeps the
81
+ * rule and `request.security` loses it. Answering here rather than in
82
+ * `emitSecurity` keeps the walk in one place.
83
+ */
84
+ protected securityRestrictsMutableArgs(_ctx: Fun_callContext): boolean;
85
+ protected emitSecurity(ctx: Fun_callContext): string;
86
+ }
87
+ export {};
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Pine Script v4 → JavaScript emitter.
3
+ *
4
+ * v4 inherits every guard v3 added — self-reference, forward reference, bool
5
+ * arithmetic, mutable `security()` argument — and every line of emit logic from
6
+ * v1. The migration guide relaxes none of them.
7
+ *
8
+ * What v4 adds is in two halves:
9
+ *
10
+ * SYNTAX (this file)
11
+ * `var` / `varip` declaration modifiers, and an optional type prefix.
12
+ * `var` is the only one with emit consequences; the type prefix is checked
13
+ * and discarded, and the qualifiers are discarded outright.
14
+ *
15
+ * The five compound assignment operators, `+= -= *= /= %=` (March 2021).
16
+ * Sourced from the v4 release notes; see PineV4Lexer.g4 for the quote.
17
+ *
18
+ * `else if` (May 2020). Grammar in PineV4Parser.g4, emit below.
19
+ *
20
+ * NAMES (transpiler/common/profiles/index.ts + runtime)
21
+ * The 3a rename table — `n` → `bar_index`, `red` → `color.red`,
22
+ * `period` → `timeframe.period`, and the rest. Those are lookups, not emit
23
+ * rules, so they do not belong here.
24
+ *
25
+ * NOT in v4, despite an earlier draft of the delta spec saying so: `while` and
26
+ * `switch`. Both are v5. v4 adds no statement keyword at all, which is why this
27
+ * file overrides declarations and nothing else.
28
+ */
29
+ import type { PineVersion } from "../common/version.js";
30
+ import { V3ToJsVisitor } from "../v3/ToJsVisitor.js";
31
+ import type { StdlibEntry } from "../../runtime/v1/stdlib/metadata.js";
32
+ import { Var_defContext, Var_defsContext, Var_assignContext, If_exprContext, IdContext, Pos_argsContext, Pos_argContext, Fun_callContext } from "../../parser/v4/generated/PineV4Parser.js";
33
+ /** Anything carrying a source position (see the v1 base for why it is structural). */
34
+ interface SourceLocated {
35
+ start?: {
36
+ line: number;
37
+ column: number;
38
+ } | null;
39
+ }
40
+ /** A declaration's `var` / `varip` modifier, or null when it has neither. */
41
+ type Persistence = "var" | "varip" | null;
42
+ export declare class V4ToJsVisitor extends V3ToJsVisitor {
43
+ protected readonly version: PineVersion;
44
+ /**
45
+ * v4's view of the stdlib: the base, minus the spellings v4 removed, plus the
46
+ * namespaced ones it introduced.
47
+ *
48
+ * Subtracting matters as much as adding. Leaving `red` in alongside
49
+ * `color.red` would accept both dialects, and a script written half in each
50
+ * would compile here and fail on TradingView — the exact class of divergence
51
+ * this engine exists to avoid.
52
+ */
53
+ protected get registry(): Record<string, StdlibEntry>;
54
+ /**
55
+ * From v4, a user-defined function MAY return a tuple.
56
+ *
57
+ * SOURCING. From the manual's user-defined functions page: "Programmers can
58
+ * write functions that return multiple values or references by using a tuple
59
+ * as the final statement in the function's body", with
60
+ *
61
+ * sumDiff(float val1, float val2) =>
62
+ * [val1 + val2, val1 - val2]
63
+ *
64
+ * [sum, diff] = sumDiff(math.random(), math.random())
65
+ *
66
+ * and the rule for reading one back: "the script must use a tuple declaration
67
+ * containing one NEW variable for each returned item. It is not possible to
68
+ * reassign existing tuples or to use previously declared variables within
69
+ * them."
70
+ *
71
+ * v1–v3 keep the refusal — `conformance/common/guards_by_version.test.ts` has
72
+ * always declared the guard for those three and left v4 and v5 unstated, and
73
+ * this is the override that was missing. Eight of TradingView's own published
74
+ * scripts were rejected by it, including the one on its own error-messages
75
+ * page about tuples.
76
+ *
77
+ * Lifting the guard is the WHOLE change: `[a, b]` already emits a JavaScript
78
+ * array through `visitArith_exprs`, a body's last statement is already what a
79
+ * function returns, and `ctx.new_vars` already unpacks a built-in's tuple.
80
+ */
81
+ protected enforceNoTupleReturn(): void;
82
+ /**
83
+ * Rejects a v1–v3 spelling with the name that replaced it.
84
+ *
85
+ * Hooked on `visitId` rather than driven off the registry, because a missing
86
+ * registry entry is not by itself an error — `visitId` emits any identifier
87
+ * it does not recognise, since most identifiers are the script's own
88
+ * variables. So `red` at v4 would just emit `opsv2_red` and read as
89
+ * `undefined`: a colour that is silently `na`, on a chart that still draws.
90
+ */
91
+ protected enforceRenamedInV4(name: string, ctx: SourceLocated): void;
92
+ /**
93
+ * Is this identifier the CALLEE of a function call, rather than a read?
94
+ *
95
+ * Structural rather than `instanceof` — every version generates its own
96
+ * context classes, so `instanceof` is false across the hierarchy (see the
97
+ * note on `isRule` in the v1 base).
98
+ */
99
+ protected isCalleeOf(ctx: SourceLocated): boolean;
100
+ visitId(ctx: IdContext): string;
101
+ /** Reads the modifier off a declaration. Absent on every v1–v3 declaration. */
102
+ protected persistenceOf(ctx: Var_defContext | Var_defsContext): Persistence;
103
+ /**
104
+ * `var x = expr` initialises once and then holds its value across bars.
105
+ *
106
+ * The initialiser is emitted as a THUNK. `ctx.var_def` runs it on the first
107
+ * bar only, so `expr` is not re-evaluated afterwards — which matters both for
108
+ * cost and for correctness: `var t = timenow` must keep the first bar's
109
+ * timestamp, and passing an already-evaluated value would silently make it
110
+ * the current one every bar while still looking like it worked.
111
+ *
112
+ * The @L:C key is the DECLARATION SITE, not the name. Two `var`s of the same
113
+ * name in different scopes are different variables and must not share an
114
+ * initialised flag.
115
+ */
116
+ visitVar_def(ctx: Var_defContext): string;
117
+ /**
118
+ * `var [a, b] = f()` — the tuple form.
119
+ *
120
+ * Rejected rather than emitted wrongly. `ctx.new_vars` destructures a fresh
121
+ * call result into several series, and there is no once-only form of it: the
122
+ * honest options are to build one, or to say so. A wrong `var` here would
123
+ * re-run `f()` every bar while the script says it must not, and nothing
124
+ * downstream could detect that.
125
+ */
126
+ visitVar_defs(ctx: Var_defsContext): string;
127
+ /** Script-scope names declared with an explicit `int`, bound once. */
128
+ private readonly declaredInts;
129
+ /**
130
+ * "Value with NA type cannot be assigned to a variable that was defined
131
+ * without type keyword" — `x = na`, and the `b = na` of `var float a = na, b = na`,
132
+ * where the keyword covers `a` only. v1–v3 accept it, so this lives in v4.
133
+ *
134
+ * `int q = close` — a float stored in a declared int. Only when the
135
+ * initialiser is PROVABLY a float (see TypeRules.ts).
136
+ */
137
+ protected enforceDeclarationTypes(ctx: Var_defContext): void;
138
+ /** TradingView's wording, which differs by version. */
139
+ protected declaredIntMessage(name: string): string;
140
+ /**
141
+ * A float argument where a `series int` length is required. The first
142
+ * positional slot of these functions is the source, so only the second is
143
+ * read — `ta.highest(10)` has its length first and is left alone.
144
+ */
145
+ protected enforceIntLengthArgument(ctx: Fun_callContext): void;
146
+ /**
147
+ * A float where a drawing constructor's x coordinate (a `series int`) is
148
+ * required: `label.new(bar_index - 10.7, ...)` is a compile error on v4, v5
149
+ * and v6. `w / 2` between ints is no proof (see isProvablyFloat), so it still
150
+ * compiles. The `chart.point` overloads (v5/v6) take points, not coordinates,
151
+ * so only the 4-coordinate form (4+ positional args, or the x1/x2 keywords)
152
+ * is read.
153
+ */
154
+ protected enforceIntCoordinateArguments(ctx: Fun_callContext): void;
155
+ /** TradingView names a binary expression `call 'operator -' (series float)`; anything else is shown as written. */
156
+ private describeFloatOperand;
157
+ visitFun_call(ctx: any): string;
158
+ /**
159
+ * `tostring(x)` / `str.tostring(x)` of a constant number prints differently
160
+ * from the same call on a series (runtime/v1/stdlib/str.ts `numberToString`),
161
+ * and only the source can tell them apart. A call with no format whose
162
+ * argument is provably constant gets the runtime's CONST_DEFAULT marker in
163
+ * the format position.
164
+ */
165
+ private markConstTostring;
166
+ /**
167
+ * The arithmetic half of a compound assignment — `"+"` for `+=` — or null
168
+ * when the statement is a plain `:=`.
169
+ */
170
+ protected compoundOperatorOf(ctx: Var_assignContext): string | null;
171
+ /**
172
+ * `current <op> value`, emitted EXACTLY as the binary operator would be.
173
+ *
174
+ * TradingView defines `x += y` as "an arithmetic operator combined with the
175
+ * reassignment operator", so it has to mean precisely `x := x + y` — which
176
+ * for `+` and `-` is not the JavaScript operator. `opsv2_safe_add` is what
177
+ * `visitAdd_expr` emits, and it is what makes `na + 1` come out `na` and
178
+ * `"a" + "b"` concatenate. Emitting a raw `+` here would have made compound
179
+ * assignment the one place in the language where `na` behaved differently.
180
+ *
181
+ * `value` is parenthesised because not every emitted expression is
182
+ * self-contained: a comparison comes out as bare `a > b`, so `x *= a > b`
183
+ * would otherwise bind as `(x * a) > b`. (`and` and `or` used to be the
184
+ * example here, back when they emitted `a && b`; they are now a call to
185
+ * `ctx.allOf`, which brackets itself — see visitAnd_expr.)
186
+ */
187
+ protected compoundValue(op: string, current: string, value: string): string;
188
+ /**
189
+ * `x += expr`.
190
+ *
191
+ * Routed through the same guard as `:=` — the target must already be
192
+ * declared, which for a compound assignment is not a formality: there is no
193
+ * previous value to add to otherwise.
194
+ */
195
+ visitVar_assign(ctx: Var_assignContext): string;
196
+ /**
197
+ * `else if cond` — the else branch is another `if` rather than a block.
198
+ *
199
+ * Emitted INLINE, as one more `else if` on the JavaScript side, instead of
200
+ * by visiting the nested `if` normally. That distinction is the whole of the
201
+ * work here, and it is not a matter of taste:
202
+ *
203
+ * x = if a
204
+ * 1
205
+ * else if b
206
+ * 2
207
+ * else
208
+ * 3
209
+ *
210
+ * A normal visit would give the nested `if` its own IIFE, producing
211
+ * `(() => { if (a) { return 1; } else (() => { … })(); })()` — the inner
212
+ * function computes 2 or 3 and the outer one throws the result away, so `x`
213
+ * is `undefined` on every bar that takes the `else`. No error; just an `na`
214
+ * where a number belongs.
215
+ *
216
+ * Recursing HERE keeps the whole chain inside the single wrapper
217
+ * `visitIf_expr` already opened, and inside the one `suppressBlockReturn`
218
+ * level it already set — so every arm of the chain returns, or does not,
219
+ * together.
220
+ */
221
+ protected emitElseBranch(ctx: If_exprContext): string | null;
222
+ /**
223
+ * v4's `pos_args` is a list of `pos_arg`, not of `arith_expr`. Overriding the
224
+ * SEAM rather than `visitPos_args` means `emitSecurity` — which walks the
225
+ * same list to defer its third argument into a thunk — picks the change up
226
+ * without knowing about it.
227
+ */
228
+ protected positionalArgs(ctx: Pos_argsContext): any[];
229
+ /** `arith_expr | arith_exprs` — a transparent wrapper either way. */
230
+ visitPos_arg(ctx: Pos_argContext): string;
231
+ /**
232
+ * `[o, h, l, c] = security(sym, "D", [open, high, low, close])`.
233
+ *
234
+ * The tuple is the ARGUMENT's, so its width is read off the bracketed list
235
+ * rather than out of the registry — `security` returns one value or four
236
+ * depending on what it was handed, and no single registry entry can say that.
237
+ *
238
+ * Both spellings are read, positional and keyword, because both appear in
239
+ * TradingView's own examples.
240
+ */
241
+ protected tupleArityFromArgument(call: Fun_callContext): number | null;
242
+ /**
243
+ * How many values this `expression` argument yields, when that is knowable.
244
+ *
245
+ * Two shapes, and the second is why this is not just `.arith_exprs()`:
246
+ *
247
+ * [o, h, l, c] = request.security(sym, "D", [open, high, low, close])
248
+ * [bop, avg] = request.security(sym, "1D", dataFunction())
249
+ *
250
+ * The manual's own error-messages page uses the second — a call to a
251
+ * user-defined function whose body ends in a tuple. Its width is a fact about
252
+ * that DEFINITION, which `ScopeInfo.tupleArity` collected for exactly this.
253
+ */
254
+ protected expressionArity(node: any): number | null;
255
+ /**
256
+ * The call this expression consists of ENTIRELY, or null.
257
+ *
258
+ * Only a single-child spine is followed, so `f() + 1` is not `f()`: the
259
+ * arithmetic makes it one value however many `f` returns.
260
+ */
261
+ protected soleCall(node: any): any | null;
262
+ }
263
+ export {};