openpinescript 0.1.0 → 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.
- package/README.md +11 -25
- package/dist/cli.mjs +18 -13
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +8 -8
- package/dist/types/parser/v1/generated/PineV1ParserVisitor.d.ts +2 -2
- package/dist/types/parser/v1/index.d.ts +1 -1
- package/dist/types/parser/v2/generated/PineV2ParserVisitor.d.ts +2 -2
- package/dist/types/parser/v3/generated/PineV3ParserVisitor.d.ts +2 -2
- package/dist/types/parser/v4/generated/PineV4ParserVisitor.d.ts +2 -2
- package/dist/types/parser/v5/generated/PineV5ParserVisitor.d.ts +2 -2
- package/dist/types/parser/v6/generated/PineV6ParserVisitor.d.ts +2 -2
- package/dist/types/transpiler/v1/ToJsVisitor.d.ts +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -8,14 +8,18 @@
|
|
|
8
8
|
No TradingView account. No cloud. No execution quota. No 500 ms loop timeout.
|
|
9
9
|
|
|
10
10
|
[](docs/common/CONFORMANCE.md)
|
|
11
|
-
[](docs/common/CONFORMANCE.md#testing)
|
|
12
12
|
[](#-supported-pine-script-versions)
|
|
13
|
+
[](https://be-thomas.github.io/OpenPineScript/)
|
|
14
|
+
[](https://www.npmjs.com/package/openpinescript)
|
|
13
15
|
|
|
14
16
|
[](LICENSE)
|
|
15
17
|
[](https://nodejs.org)
|
|
16
18
|
[](https://www.typescriptlang.org/)
|
|
17
19
|
[](docs/common/CONFORMANCE.md#parity-763-real-scripts-from-tradingviews-docs)
|
|
18
20
|
|
|
21
|
+
### [📖 Documentation and an interactive tutorial: **be-thomas.github.io/OpenPineScript**](https://be-thomas.github.io/OpenPineScript/)
|
|
22
|
+
|
|
19
23
|
### [▶ Open Beta: try it in your browser at **zealterminal.com**](https://zealterminal.com) — no install, no CSV
|
|
20
24
|
|
|
21
25
|
[Docs](https://be-thomas.github.io/OpenPineScript/) · [Try it online](#-try-it-online) · [Quick start](#-quick-start) · [Why](#-why-openpinescript) · [Parity](#-verified-against-tradingview-itself) · [Guides](#-documentation) · [FAQ](#-faq)
|
|
@@ -105,26 +109,6 @@ npm install openpinescript
|
|
|
105
109
|
import { Session } from "openpinescript";
|
|
106
110
|
```
|
|
107
111
|
|
|
108
|
-
To work on the engine itself, run it from a clone:
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
git clone https://github.com/be-thomas/OpenPineScript.git
|
|
112
|
-
cd OpenPineScript
|
|
113
|
-
npm install
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Then run a bundled example:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
npm run opsv2 -- examples/v1/sma_crossover.pine --data mock_data/common/AAPL_mock.csv
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Or explore interactively:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
npm run replv2
|
|
126
|
-
```
|
|
127
|
-
|
|
128
112
|

|
|
129
113
|
|
|
130
114
|
---
|
|
@@ -138,7 +122,7 @@ npm run replv2
|
|
|
138
122
|
| 🗂️ **Six language versions** | v1 → v6, each with its own grammar and emitter, so a v2 script is parsed by a parser that has never heard of `var`. |
|
|
139
123
|
| 🔁 **Pine → JavaScript** | Emit readable JS and embed it anywhere — a worker, a server, a browser, a CI job. |
|
|
140
124
|
| 🤖 **Built for automation** | JSON output, exit codes, input overrides, and a comparison mode that diffs your run against a TradingView export. |
|
|
141
|
-
| 🧪 **
|
|
125
|
+
| 🧪 **4,400+ tests** | Differential testing against an independent oracle, a full version matrix, 763 real scripts from TradingView's docs, and the parity suites above. |
|
|
142
126
|
|
|
143
127
|
---
|
|
144
128
|
|
|
@@ -198,7 +182,7 @@ broker emulator, multi-timeframe `security()`, and the real-time tick model.
|
|
|
198
182
|
- **Put it behind a chart** — [zealterminal.com](https://zealterminal.com) is this engine in a browser tab, in open beta, if you want to see that shape working before you build it
|
|
199
183
|
|
|
200
184
|
```bash
|
|
201
|
-
|
|
185
|
+
npx openpinescript strategy.pine --data data.csv --out-dir ./results
|
|
202
186
|
```
|
|
203
187
|
|
|
204
188
|
> 📖 **[Full CLI reference →](CLI-Usage.md)** — output flags, comparison mode,
|
|
@@ -210,6 +194,7 @@ npm run opsv2 -- strategy.pine --data data.csv --out-dir ./results --json
|
|
|
210
194
|
|
|
211
195
|
| Doc | What it answers |
|
|
212
196
|
|---|---|
|
|
197
|
+
| **[Docs site](https://be-thomas.github.io/OpenPineScript/)** | The CLI guide, a five-lesson tutorial that runs the real engine in your browser, and a guide written for AI agents |
|
|
213
198
|
| **[Conformance report](docs/common/CONFORMANCE.md)** | How the numbers are verified, what that caught, what is not covered |
|
|
214
199
|
| **[CLI usage](CLI-Usage.md)** | Every flag, with worked examples |
|
|
215
200
|
| **[Architecture](docs/common/ARCHITECTURE.md)** | The compile pipeline and the repository layout |
|
|
@@ -307,8 +292,9 @@ bar by bar against a runtime that provides the standard library.
|
|
|
307
292
|
<summary><b>How do I convert Pine Script to JavaScript?</b></summary>
|
|
308
293
|
<br>
|
|
309
294
|
|
|
310
|
-
`
|
|
311
|
-
|
|
295
|
+
`npx openpinescript script.pine --data data.csv --show-transpiled` prints the
|
|
296
|
+
compiled JavaScript before running it, or call `compileScript(src)` from the
|
|
297
|
+
library (`import { compileScript } from "openpinescript"`) to get it as a string.
|
|
312
298
|
</details>
|
|
313
299
|
|
|
314
300
|
---
|
package/dist/cli.mjs
CHANGED
|
@@ -19109,7 +19109,7 @@ function typeFit(declared, value) {
|
|
|
19109
19109
|
__name(typeFit, "typeFit");
|
|
19110
19110
|
|
|
19111
19111
|
// parser/v1/index.ts
|
|
19112
|
-
import {
|
|
19112
|
+
import { CharStream as CharStream2, CommonTokenStream, BaseErrorListener } from "antlr4ng";
|
|
19113
19113
|
|
|
19114
19114
|
// parser/v1/generated/PineV1Parser.ts
|
|
19115
19115
|
import * as antlr from "antlr4ng";
|
|
@@ -29653,7 +29653,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
29653
29653
|
this.indentErrors = [];
|
|
29654
29654
|
this.tokenFactory = {
|
|
29655
29655
|
create: /* @__PURE__ */ __name((source2, type, text6, channel, start, stop, line4, charPositionInLine) => {
|
|
29656
|
-
const t =
|
|
29656
|
+
const t = CommonToken.fromSource(source2, type, channel, start, stop);
|
|
29657
29657
|
t.line = line4;
|
|
29658
29658
|
t.column = charPositionInLine;
|
|
29659
29659
|
if (text6 !== void 0 && text6 !== null) t.text = text6;
|
|
@@ -29708,7 +29708,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
29708
29708
|
}
|
|
29709
29709
|
let text6 = t.text;
|
|
29710
29710
|
if (!text6 && this.inputStream) {
|
|
29711
|
-
text6 = this.inputStream.
|
|
29711
|
+
text6 = this.inputStream.getTextFromInterval(new Interval(t.start, t.stop));
|
|
29712
29712
|
}
|
|
29713
29713
|
text6 = text6 || "";
|
|
29714
29714
|
const lastNewLineIndex = text6.lastIndexOf("\n");
|
|
@@ -29734,7 +29734,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
29734
29734
|
}
|
|
29735
29735
|
/** Is the line that LBEG token `t` introduces flush against column 0? */
|
|
29736
29736
|
startsAtColumnZero(t) {
|
|
29737
|
-
const text6 = t.text ?? this.inputStream?.
|
|
29737
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new Interval(t.start, t.stop)) ?? "";
|
|
29738
29738
|
const nl = Math.max(text6.lastIndexOf("\n"), text6.lastIndexOf("\r"));
|
|
29739
29739
|
if (text6.substring(nl + 1).length !== 0) return false;
|
|
29740
29740
|
const c = this.inputStream?.LA(1);
|
|
@@ -29745,7 +29745,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
29745
29745
|
}
|
|
29746
29746
|
/** Line number of the last line an LBEG token spans. */
|
|
29747
29747
|
newlinesIn(t) {
|
|
29748
|
-
const text6 = t.text ?? this.inputStream?.
|
|
29748
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new Interval(t.start, t.stop)) ?? "";
|
|
29749
29749
|
return (text6.match(/\n|\r(?!\n)/g) ?? []).length;
|
|
29750
29750
|
}
|
|
29751
29751
|
handleIndentation(indentLength, triggerToken, isEOF = false) {
|
|
@@ -29898,7 +29898,7 @@ var ErrorCollector = class extends BaseErrorListener {
|
|
|
29898
29898
|
};
|
|
29899
29899
|
function createParser(TokenSourceCtor, ParserCtor, entry2) {
|
|
29900
29900
|
return /* @__PURE__ */ __name(function parse7(source2) {
|
|
29901
|
-
const inputStream =
|
|
29901
|
+
const inputStream = CharStream2.fromString(source2);
|
|
29902
29902
|
const lexer = new TokenSourceCtor(inputStream);
|
|
29903
29903
|
lexer.removeErrorListeners();
|
|
29904
29904
|
const lexerListener = new ErrorCollector();
|
|
@@ -101538,7 +101538,7 @@ var PineV6TokenSource = class extends IndentTokenSource(PineV6Lexer, { strictCon
|
|
|
101538
101538
|
var parse6 = createParser(PineV6TokenSource, PineV6Parser, (p) => p.pine_script());
|
|
101539
101539
|
|
|
101540
101540
|
// transpiler/v1/ToJsVisitor.ts
|
|
101541
|
-
import {
|
|
101541
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
101542
101542
|
|
|
101543
101543
|
// transpiler/common/passes/ScopeAnalysis.ts
|
|
101544
101544
|
function children(node) {
|
|
@@ -101933,7 +101933,7 @@ function isConstIntLiteral(node) {
|
|
|
101933
101933
|
}
|
|
101934
101934
|
}
|
|
101935
101935
|
__name(isConstIntLiteral, "isConstIntLiteral");
|
|
101936
|
-
var V1ToJsVisitor = class extends
|
|
101936
|
+
var V1ToJsVisitor = class extends AbstractParseTreeVisitor {
|
|
101937
101937
|
constructor() {
|
|
101938
101938
|
super(...arguments);
|
|
101939
101939
|
/**
|
|
@@ -108265,18 +108265,22 @@ function getFlag(args, flag) {
|
|
|
108265
108265
|
__name(getFlag, "getFlag");
|
|
108266
108266
|
function parseArgs(argv) {
|
|
108267
108267
|
const args = argv.slice(2);
|
|
108268
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
108269
|
+
printUsage(console.log);
|
|
108270
|
+
process.exit(0);
|
|
108271
|
+
}
|
|
108268
108272
|
const scriptPath = args.find((a) => a.endsWith(".pine")) ?? null;
|
|
108269
108273
|
if (!scriptPath) {
|
|
108270
108274
|
console.error(`${C2.Red}Error:${C2.Reset} No .pine script file specified.
|
|
108271
108275
|
`);
|
|
108272
|
-
printUsage();
|
|
108276
|
+
printUsage(console.error);
|
|
108273
108277
|
process.exit(1);
|
|
108274
108278
|
}
|
|
108275
108279
|
const dataPath = getFlag(args, "--data");
|
|
108276
108280
|
if (!dataPath) {
|
|
108277
108281
|
console.error(`${C2.Red}Error:${C2.Reset} --data <csv> is required.
|
|
108278
108282
|
`);
|
|
108279
|
-
printUsage();
|
|
108283
|
+
printUsage(console.error);
|
|
108280
108284
|
process.exit(1);
|
|
108281
108285
|
}
|
|
108282
108286
|
const inputs = {};
|
|
@@ -108317,9 +108321,10 @@ function parseArgs(argv) {
|
|
|
108317
108321
|
};
|
|
108318
108322
|
}
|
|
108319
108323
|
__name(parseArgs, "parseArgs");
|
|
108320
|
-
function printUsage() {
|
|
108321
|
-
|
|
108322
|
-
`${C2.Bold}Usage:${C2.Reset}
|
|
108324
|
+
function printUsage(out) {
|
|
108325
|
+
out(
|
|
108326
|
+
`${C2.Bold}Usage:${C2.Reset} openpinescript <script.pine> --data <data.csv> [flags]
|
|
108327
|
+
npx openpinescript <script.pine> --data <data.csv> [flags]
|
|
108323
108328
|
|
|
108324
108329
|
${C2.Bold}Output flags:${C2.Reset}
|
|
108325
108330
|
--out-dir <dir> Write chart.csv, trades.csv, and summary.json to <dir>
|
package/dist/index.cjs
CHANGED
|
@@ -10595,7 +10595,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10595
10595
|
this.indentErrors = [];
|
|
10596
10596
|
this.tokenFactory = {
|
|
10597
10597
|
create: /* @__PURE__ */ __name((source2, type, text6, channel, start, stop, line4, charPositionInLine) => {
|
|
10598
|
-
const t =
|
|
10598
|
+
const t = import_antlr4ng.CommonToken.fromSource(source2, type, channel, start, stop);
|
|
10599
10599
|
t.line = line4;
|
|
10600
10600
|
t.column = charPositionInLine;
|
|
10601
10601
|
if (text6 !== void 0 && text6 !== null) t.text = text6;
|
|
@@ -10650,7 +10650,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10650
10650
|
}
|
|
10651
10651
|
let text6 = t.text;
|
|
10652
10652
|
if (!text6 && this.inputStream) {
|
|
10653
|
-
text6 = this.inputStream.
|
|
10653
|
+
text6 = this.inputStream.getTextFromInterval(new import_antlr4ng.Interval(t.start, t.stop));
|
|
10654
10654
|
}
|
|
10655
10655
|
text6 = text6 || "";
|
|
10656
10656
|
const lastNewLineIndex = text6.lastIndexOf("\n");
|
|
@@ -10676,7 +10676,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10676
10676
|
}
|
|
10677
10677
|
/** Is the line that LBEG token `t` introduces flush against column 0? */
|
|
10678
10678
|
startsAtColumnZero(t) {
|
|
10679
|
-
const text6 = t.text ?? this.inputStream?.
|
|
10679
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new import_antlr4ng.Interval(t.start, t.stop)) ?? "";
|
|
10680
10680
|
const nl = Math.max(text6.lastIndexOf("\n"), text6.lastIndexOf("\r"));
|
|
10681
10681
|
if (text6.substring(nl + 1).length !== 0) return false;
|
|
10682
10682
|
const c = this.inputStream?.LA(1);
|
|
@@ -10687,7 +10687,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10687
10687
|
}
|
|
10688
10688
|
/** Line number of the last line an LBEG token spans. */
|
|
10689
10689
|
newlinesIn(t) {
|
|
10690
|
-
const text6 = t.text ?? this.inputStream?.
|
|
10690
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new import_antlr4ng.Interval(t.start, t.stop)) ?? "";
|
|
10691
10691
|
return (text6.match(/\n|\r(?!\n)/g) ?? []).length;
|
|
10692
10692
|
}
|
|
10693
10693
|
handleIndentation(indentLength, triggerToken, isEOF = false) {
|
|
@@ -10840,7 +10840,7 @@ var ErrorCollector = class extends import_antlr4ng2.BaseErrorListener {
|
|
|
10840
10840
|
};
|
|
10841
10841
|
function createParser(TokenSourceCtor, ParserCtor, entry2) {
|
|
10842
10842
|
return /* @__PURE__ */ __name(function parse7(source2) {
|
|
10843
|
-
const inputStream = import_antlr4ng2.
|
|
10843
|
+
const inputStream = import_antlr4ng2.CharStream.fromString(source2);
|
|
10844
10844
|
const lexer = new TokenSourceCtor(inputStream);
|
|
10845
10845
|
lexer.removeErrorListeners();
|
|
10846
10846
|
const lexerListener = new ErrorCollector();
|
|
@@ -98788,7 +98788,7 @@ function isConstIntLiteral(node) {
|
|
|
98788
98788
|
}
|
|
98789
98789
|
}
|
|
98790
98790
|
__name(isConstIntLiteral, "isConstIntLiteral");
|
|
98791
|
-
var V1ToJsVisitor = class extends import_antlr4ng3.
|
|
98791
|
+
var V1ToJsVisitor = class extends import_antlr4ng3.AbstractParseTreeVisitor {
|
|
98792
98792
|
constructor() {
|
|
98793
98793
|
super(...arguments);
|
|
98794
98794
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// parser/v1/index.ts
|
|
9
|
-
import {
|
|
9
|
+
import { CharStream as CharStream2, CommonTokenStream, BaseErrorListener } from "antlr4ng";
|
|
10
10
|
|
|
11
11
|
// parser/v1/generated/PineV1Parser.ts
|
|
12
12
|
import * as antlr from "antlr4ng";
|
|
@@ -10550,7 +10550,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10550
10550
|
this.indentErrors = [];
|
|
10551
10551
|
this.tokenFactory = {
|
|
10552
10552
|
create: /* @__PURE__ */ __name((source2, type, text6, channel, start, stop, line4, charPositionInLine) => {
|
|
10553
|
-
const t =
|
|
10553
|
+
const t = CommonToken.fromSource(source2, type, channel, start, stop);
|
|
10554
10554
|
t.line = line4;
|
|
10555
10555
|
t.column = charPositionInLine;
|
|
10556
10556
|
if (text6 !== void 0 && text6 !== null) t.text = text6;
|
|
@@ -10605,7 +10605,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10605
10605
|
}
|
|
10606
10606
|
let text6 = t.text;
|
|
10607
10607
|
if (!text6 && this.inputStream) {
|
|
10608
|
-
text6 = this.inputStream.
|
|
10608
|
+
text6 = this.inputStream.getTextFromInterval(new Interval(t.start, t.stop));
|
|
10609
10609
|
}
|
|
10610
10610
|
text6 = text6 || "";
|
|
10611
10611
|
const lastNewLineIndex = text6.lastIndexOf("\n");
|
|
@@ -10631,7 +10631,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10631
10631
|
}
|
|
10632
10632
|
/** Is the line that LBEG token `t` introduces flush against column 0? */
|
|
10633
10633
|
startsAtColumnZero(t) {
|
|
10634
|
-
const text6 = t.text ?? this.inputStream?.
|
|
10634
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new Interval(t.start, t.stop)) ?? "";
|
|
10635
10635
|
const nl = Math.max(text6.lastIndexOf("\n"), text6.lastIndexOf("\r"));
|
|
10636
10636
|
if (text6.substring(nl + 1).length !== 0) return false;
|
|
10637
10637
|
const c = this.inputStream?.LA(1);
|
|
@@ -10642,7 +10642,7 @@ function IndentTokenSource(Base, options = {}) {
|
|
|
10642
10642
|
}
|
|
10643
10643
|
/** Line number of the last line an LBEG token spans. */
|
|
10644
10644
|
newlinesIn(t) {
|
|
10645
|
-
const text6 = t.text ?? this.inputStream?.
|
|
10645
|
+
const text6 = t.text ?? this.inputStream?.getTextFromInterval(new Interval(t.start, t.stop)) ?? "";
|
|
10646
10646
|
return (text6.match(/\n|\r(?!\n)/g) ?? []).length;
|
|
10647
10647
|
}
|
|
10648
10648
|
handleIndentation(indentLength, triggerToken, isEOF = false) {
|
|
@@ -10795,7 +10795,7 @@ var ErrorCollector = class extends BaseErrorListener {
|
|
|
10795
10795
|
};
|
|
10796
10796
|
function createParser(TokenSourceCtor, ParserCtor, entry2) {
|
|
10797
10797
|
return /* @__PURE__ */ __name(function parse7(source2) {
|
|
10798
|
-
const inputStream =
|
|
10798
|
+
const inputStream = CharStream2.fromString(source2);
|
|
10799
10799
|
const lexer = new TokenSourceCtor(inputStream);
|
|
10800
10800
|
lexer.removeErrorListeners();
|
|
10801
10801
|
const lexerListener = new ErrorCollector();
|
|
@@ -82435,7 +82435,7 @@ var PineV6TokenSource = class extends IndentTokenSource(PineV6Lexer, { strictCon
|
|
|
82435
82435
|
var parse6 = createParser(PineV6TokenSource, PineV6Parser, (p) => p.pine_script());
|
|
82436
82436
|
|
|
82437
82437
|
// transpiler/v1/ToJsVisitor.ts
|
|
82438
|
-
import {
|
|
82438
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
82439
82439
|
|
|
82440
82440
|
// utils/v2/common.ts
|
|
82441
82441
|
var PREFIX = "opsv2_";
|
|
@@ -98743,7 +98743,7 @@ function isConstIntLiteral(node) {
|
|
|
98743
98743
|
}
|
|
98744
98744
|
}
|
|
98745
98745
|
__name(isConstIntLiteral, "isConstIntLiteral");
|
|
98746
|
-
var V1ToJsVisitor = class extends
|
|
98746
|
+
var V1ToJsVisitor = class extends AbstractParseTreeVisitor {
|
|
98747
98747
|
constructor() {
|
|
98748
98748
|
super(...arguments);
|
|
98749
98749
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { Pine_scriptContext } from "./PineV1Parser.js";
|
|
3
3
|
import { StmtContext } from "./PineV1Parser.js";
|
|
4
4
|
import { Global_stmtContext } from "./PineV1Parser.js";
|
|
@@ -50,7 +50,7 @@ import { IdContext } from "./PineV1Parser.js";
|
|
|
50
50
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
51
51
|
* operations with no return type.
|
|
52
52
|
*/
|
|
53
|
-
export declare class PineV1ParserVisitor<Result> extends
|
|
53
|
+
export declare class PineV1ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
54
54
|
/**
|
|
55
55
|
* Visit a parse tree produced by `PineV1Parser.pine_script`.
|
|
56
56
|
* @param ctx the parse tree
|
|
@@ -22,7 +22,7 @@ export interface ParserError {
|
|
|
22
22
|
* cannot satisfy both signatures nominally, and only `line`/`column`/`msg` are
|
|
23
23
|
* read here.
|
|
24
24
|
*/
|
|
25
|
-
export declare class ErrorCollector extends BaseErrorListener
|
|
25
|
+
export declare class ErrorCollector extends BaseErrorListener {
|
|
26
26
|
errors: ParserError[];
|
|
27
27
|
syntaxError(recognizer: any, offendingSymbol: any, line: number, charPositionInLine: number, msg: string, e: any): void;
|
|
28
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { Var_assignContext } from "./PineV2Parser.js";
|
|
3
3
|
import { Global_stmt_contentContext } from "./PineV2Parser.js";
|
|
4
4
|
import { Local_stmt_contentContext } from "./PineV2Parser.js";
|
|
@@ -51,7 +51,7 @@ import { IdContext } from "./PineV2Parser.js";
|
|
|
51
51
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
52
52
|
* operations with no return type.
|
|
53
53
|
*/
|
|
54
|
-
export declare class PineV2ParserVisitor<Result> extends
|
|
54
|
+
export declare class PineV2ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
55
55
|
/**
|
|
56
56
|
* Visit a parse tree produced by `PineV2Parser.var_assign`.
|
|
57
57
|
* @param ctx the parse tree
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { Var_assignContext } from "./PineV3Parser.js";
|
|
3
3
|
import { Global_stmt_contentContext } from "./PineV3Parser.js";
|
|
4
4
|
import { Local_stmt_contentContext } from "./PineV3Parser.js";
|
|
@@ -51,7 +51,7 @@ import { IdContext } from "./PineV3Parser.js";
|
|
|
51
51
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
52
52
|
* operations with no return type.
|
|
53
53
|
*/
|
|
54
|
-
export declare class PineV3ParserVisitor<Result> extends
|
|
54
|
+
export declare class PineV3ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
55
55
|
/**
|
|
56
56
|
* Visit a parse tree produced by `PineV3Parser.var_assign`.
|
|
57
57
|
* @param ctx the parse tree
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { Decl_modContext } from "./PineV4Parser.js";
|
|
3
3
|
import { Type_qualContext } from "./PineV4Parser.js";
|
|
4
4
|
import { Type_nameContext } from "./PineV4Parser.js";
|
|
@@ -57,7 +57,7 @@ import { Other_literalContext } from "./PineV4Parser.js";
|
|
|
57
57
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
58
58
|
* operations with no return type.
|
|
59
59
|
*/
|
|
60
|
-
export declare class PineV4ParserVisitor<Result> extends
|
|
60
|
+
export declare class PineV4ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
61
61
|
/**
|
|
62
62
|
* Visit a parse tree produced by `PineV4Parser.decl_mod`.
|
|
63
63
|
* @param ctx the parse tree
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { While_exprContext } from "./PineV5Parser.js";
|
|
3
3
|
import { Switch_exprContext } from "./PineV5Parser.js";
|
|
4
4
|
import { Switch_bodyContext } from "./PineV5Parser.js";
|
|
@@ -79,7 +79,7 @@ import { Other_literalContext } from "./PineV5Parser.js";
|
|
|
79
79
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
80
80
|
* operations with no return type.
|
|
81
81
|
*/
|
|
82
|
-
export declare class PineV5ParserVisitor<Result> extends
|
|
82
|
+
export declare class PineV5ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
83
83
|
/**
|
|
84
84
|
* Visit a parse tree produced by `PineV5Parser.while_expr`.
|
|
85
85
|
* @param ctx the parse tree
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
2
2
|
import { Once_exprContext } from "./PineV6Parser.js";
|
|
3
3
|
import { Other_literalContext } from "./PineV6Parser.js";
|
|
4
4
|
import { Global_stmt_contentContext } from "./PineV6Parser.js";
|
|
@@ -80,7 +80,7 @@ import { Num_literalContext } from "./PineV6Parser.js";
|
|
|
80
80
|
* @param <Result> The return type of the visit operation. Use `void` for
|
|
81
81
|
* operations with no return type.
|
|
82
82
|
*/
|
|
83
|
-
export declare class PineV6ParserVisitor<Result> extends
|
|
83
|
+
export declare class PineV6ParserVisitor<Result> extends AbstractParseTreeVisitor<Result> {
|
|
84
84
|
/**
|
|
85
85
|
* Visit a parse tree produced by `PineV6Parser.once_expr`.
|
|
86
86
|
* @param ctx the parse tree
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* See transpiler/v3/ToJsVisitor.ts for a worked example, and
|
|
25
25
|
* docs/common/ARCHITECTURE.md ("Design rules") for the rationale.
|
|
26
26
|
*/
|
|
27
|
-
import {
|
|
27
|
+
import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
28
28
|
import type { TerminalNode, ParserRuleContext, ParseTree } from "antlr4ng";
|
|
29
29
|
import type { PineVersion } from "../common/version.js";
|
|
30
30
|
import { Pine_scriptContext, StmtContext, Global_stmtContext, Global_stmt_contentContext, Fun_def_stmtContext, Fun_def_singlelineContext, Fun_def_multilineContext, Fun_headContext, Fun_body_singlelineContext, Local_stmt_singlelineContext, Local_stmt_contentContext, Loop_breakContext, Loop_continueContext, Fun_body_multilineContext, Local_stmts_multilineContext, Local_stmts_listContext, Local_stmt_multilineContext, Var_defContext, Var_defsContext, Ids_arrayContext, Arith_exprsContext, Arith_exprContext, If_exprContext, For_exprContext, Stmts_blockContext, Ternary_exprContext, Or_exprContext, And_exprContext, Eq_exprContext, Cmp_exprContext, Add_exprContext, Mult_exprContext, Unary_exprContext, Sqbr_exprContext, AtomContext, Fun_callContext, Fun_actual_argsContext, Pos_argsContext, Kw_argsContext, Kw_argContext, LiteralContext, Num_literalContext, Other_literalContext, IdContext } from "../../parser/v1/generated/PineV1Parser.js";
|
|
@@ -95,7 +95,7 @@ export declare function isRule(node: unknown, ruleContextName: string): boolean;
|
|
|
95
95
|
* produce JavaScript that does not parse.
|
|
96
96
|
*/
|
|
97
97
|
export declare function unwrapString(text: string): string;
|
|
98
|
-
export declare class V1ToJsVisitor extends
|
|
98
|
+
export declare class V1ToJsVisitor extends AbstractParseTreeVisitor<string> {
|
|
99
99
|
/**
|
|
100
100
|
* Depth of user-function bodies currently being emitted.
|
|
101
101
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openpinescript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Run TradingView Pine Script locally and offline. Compiles Pine Script v1-v6 to JavaScript and executes it against your own OHLCV data, with indicator, plotting and strategy backtesting output verified against TradingView itself.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pine-script",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
],
|
|
54
54
|
"sideEffects": false,
|
|
55
55
|
"scripts": {
|
|
56
|
-
"generate:parser": "node scripts/common/build-grammars.mjs
|
|
56
|
+
"generate:parser": "node scripts/common/build-grammars.mjs",
|
|
57
57
|
"generate:parser:v1": "node scripts/common/build-grammars.mjs v1",
|
|
58
58
|
"generate:parser:v2": "node scripts/common/build-grammars.mjs v2",
|
|
59
59
|
"generate:parser:v3": "node scripts/common/build-grammars.mjs v3",
|
|
@@ -73,11 +73,11 @@
|
|
|
73
73
|
"prepublishOnly": "npm run build && npm test"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"antlr4ng": "^
|
|
76
|
+
"antlr4ng": "^3.0.16"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@types/node": "^22.10.2",
|
|
80
|
-
"antlr-ng": "^1.0.
|
|
80
|
+
"antlr-ng": "^1.0.10",
|
|
81
81
|
"esbuild": "^0.27.0",
|
|
82
82
|
"ts-morph": "^27.0.2",
|
|
83
83
|
"ts-node": "^10.9.2",
|