@hoox-sh/pynets 0.5.0 → 0.7.0
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/CHANGELOG.md +35 -0
- package/README.md +6 -4
- package/dist/browser.js +68 -68
- package/dist/index.js +2551 -205
- package/package.json +1 -1
- package/src/cli/rich.ts +1 -1
- package/src/generated/PinescriptLexerBase.ts +22 -4
- package/src/parser/LexerBase.ts +22 -4
- package/src/runtime/compile/draw.ts +26 -2
- package/src/runtime/compile/emit_call.ts +485 -6
- package/src/runtime/compile/helpers.ts +2 -1
- package/src/runtime/compile/runtime.ts +20 -5
- package/src/runtime/compile/strategy.ts +5 -2
- package/src/runtime/interpret.ts +680 -41
- package/src/runtime/str.ts +3 -2
- package/src/runtime/strategy.ts +164 -12
- package/src/runtime/ta.ts +1667 -149
- package/src/runtime/time.ts +12 -0
package/package.json
CHANGED
package/src/cli/rich.ts
CHANGED
|
@@ -73,6 +73,10 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
73
73
|
private _lastPendingTokenType = 0;
|
|
74
74
|
private _lastPendingTokenTypeFromDefaultChannel = 0;
|
|
75
75
|
private _numOpens = 0;
|
|
76
|
+
// Open square brackets (history-refs / tuples). Tracked separately from
|
|
77
|
+
// parens so wrapped `[...]` allows any indentation, like `(...)`.
|
|
78
|
+
// Python `PinescriptLexerBase._numSqBrackets` SoT (Sept 2026 release notes).
|
|
79
|
+
private _numSqBrackets = 0;
|
|
76
80
|
private _indentLengthStack: number[] = [];
|
|
77
81
|
private _inputStarted = false;
|
|
78
82
|
|
|
@@ -129,6 +133,7 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
129
133
|
this._lastPendingTokenType = 0;
|
|
130
134
|
this._lastPendingTokenTypeFromDefaultChannel = 0;
|
|
131
135
|
this._numOpens = 0;
|
|
136
|
+
this._numSqBrackets = 0;
|
|
132
137
|
this._indentLengthStack = [];
|
|
133
138
|
this._inputStarted = false;
|
|
134
139
|
}
|
|
@@ -147,11 +152,17 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
147
152
|
const tok = this._currentToken!;
|
|
148
153
|
const tokType = tok.type;
|
|
149
154
|
const C = this.C;
|
|
150
|
-
if (tokType === C.LPAR
|
|
155
|
+
if (tokType === C.LPAR) {
|
|
151
156
|
this._numOpens += 1;
|
|
152
157
|
this._addPendingToken(tok);
|
|
153
|
-
} else if (tokType === C.
|
|
154
|
-
this.
|
|
158
|
+
} else if (tokType === C.LSQB) {
|
|
159
|
+
this._numSqBrackets += 1;
|
|
160
|
+
this._addPendingToken(tok);
|
|
161
|
+
} else if (tokType === C.RPAR) {
|
|
162
|
+
this._numOpens = Math.max(0, this._numOpens - 1);
|
|
163
|
+
this._addPendingToken(tok);
|
|
164
|
+
} else if (tokType === C.RSQB) {
|
|
165
|
+
this._numSqBrackets = Math.max(0, this._numSqBrackets - 1);
|
|
155
166
|
this._addPendingToken(tok);
|
|
156
167
|
} else if (tokType === C.NEWLINE) {
|
|
157
168
|
this._handleNEWLINEToken();
|
|
@@ -264,7 +275,14 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
private _handleNEWLINEToken(): void {
|
|
267
|
-
|
|
278
|
+
// Newlines inside (...) or [...] are hidden (Python parity): wrapped
|
|
279
|
+
// history-refs / tuples may use any indentation without emitting
|
|
280
|
+
// INDENT/DEDENT mid-expression.
|
|
281
|
+
if (
|
|
282
|
+
this._numOpens > 0 ||
|
|
283
|
+
this._numSqBrackets > 0 ||
|
|
284
|
+
this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)
|
|
285
|
+
) {
|
|
268
286
|
this._hideAndAddPendingToken(this._currentToken!);
|
|
269
287
|
return;
|
|
270
288
|
}
|
package/src/parser/LexerBase.ts
CHANGED
|
@@ -73,6 +73,10 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
73
73
|
private _lastPendingTokenType = 0;
|
|
74
74
|
private _lastPendingTokenTypeFromDefaultChannel = 0;
|
|
75
75
|
private _numOpens = 0;
|
|
76
|
+
// Open square brackets (history-refs / tuples). Tracked separately from
|
|
77
|
+
// parens so wrapped `[...]` allows any indentation, like `(...)`.
|
|
78
|
+
// Python `PinescriptLexerBase._numSqBrackets` SoT (Sept 2026 release notes).
|
|
79
|
+
private _numSqBrackets = 0;
|
|
76
80
|
private _indentLengthStack: number[] = [];
|
|
77
81
|
private _inputStarted = false;
|
|
78
82
|
|
|
@@ -129,6 +133,7 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
129
133
|
this._lastPendingTokenType = 0;
|
|
130
134
|
this._lastPendingTokenTypeFromDefaultChannel = 0;
|
|
131
135
|
this._numOpens = 0;
|
|
136
|
+
this._numSqBrackets = 0;
|
|
132
137
|
this._indentLengthStack = [];
|
|
133
138
|
this._inputStarted = false;
|
|
134
139
|
}
|
|
@@ -147,11 +152,17 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
147
152
|
const tok = this._currentToken!;
|
|
148
153
|
const tokType = tok.type;
|
|
149
154
|
const C = this.C;
|
|
150
|
-
if (tokType === C.LPAR
|
|
155
|
+
if (tokType === C.LPAR) {
|
|
151
156
|
this._numOpens += 1;
|
|
152
157
|
this._addPendingToken(tok);
|
|
153
|
-
} else if (tokType === C.
|
|
154
|
-
this.
|
|
158
|
+
} else if (tokType === C.LSQB) {
|
|
159
|
+
this._numSqBrackets += 1;
|
|
160
|
+
this._addPendingToken(tok);
|
|
161
|
+
} else if (tokType === C.RPAR) {
|
|
162
|
+
this._numOpens = Math.max(0, this._numOpens - 1);
|
|
163
|
+
this._addPendingToken(tok);
|
|
164
|
+
} else if (tokType === C.RSQB) {
|
|
165
|
+
this._numSqBrackets = Math.max(0, this._numSqBrackets - 1);
|
|
155
166
|
this._addPendingToken(tok);
|
|
156
167
|
} else if (tokType === C.NEWLINE) {
|
|
157
168
|
this._handleNEWLINEToken();
|
|
@@ -264,7 +275,14 @@ export default class PinescriptLexerBase extends Lexer {
|
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
private _handleNEWLINEToken(): void {
|
|
267
|
-
|
|
278
|
+
// Newlines inside (...) or [...] are hidden (Python parity): wrapped
|
|
279
|
+
// history-refs / tuples may use any indentation without emitting
|
|
280
|
+
// INDENT/DEDENT mid-expression.
|
|
281
|
+
if (
|
|
282
|
+
this._numOpens > 0 ||
|
|
283
|
+
this._numSqBrackets > 0 ||
|
|
284
|
+
this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)
|
|
285
|
+
) {
|
|
268
286
|
this._hideAndAddPendingToken(this._currentToken!);
|
|
269
287
|
return;
|
|
270
288
|
}
|
|
@@ -103,8 +103,32 @@ export class CompileDraw {
|
|
|
103
103
|
return this.book.boxNew(n(bar, 0), Object.keys(extra).length ? extra : undefined);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
table_new(
|
|
107
|
-
|
|
106
|
+
table_new(
|
|
107
|
+
bar: unknown,
|
|
108
|
+
position?: unknown,
|
|
109
|
+
columns?: unknown,
|
|
110
|
+
rows?: unknown,
|
|
111
|
+
bgcolor?: unknown,
|
|
112
|
+
frameColor?: unknown,
|
|
113
|
+
frameWidth?: unknown,
|
|
114
|
+
borderColor?: unknown,
|
|
115
|
+
borderWidth?: unknown,
|
|
116
|
+
forceOverlay?: unknown,
|
|
117
|
+
): number {
|
|
118
|
+
// Pine positional order: (position, columns, rows, bgcolor, frame_color,
|
|
119
|
+
// frame_width, border_color, border_width, force_overlay) — Python
|
|
120
|
+
// `compiler.py` table emit SoT (columns then rows).
|
|
121
|
+
const extra: Record<string, unknown> = {};
|
|
122
|
+
if (position != null) extra.position = position;
|
|
123
|
+
putNum(extra, "columns", columns);
|
|
124
|
+
putNum(extra, "rows", rows);
|
|
125
|
+
if (bgcolor != null) extra.bgcolor = bgcolor;
|
|
126
|
+
if (frameColor != null) extra.frame_color = frameColor;
|
|
127
|
+
putNum(extra, "frame_width", frameWidth);
|
|
128
|
+
if (borderColor != null) extra.border_color = borderColor;
|
|
129
|
+
putNum(extra, "border_width", borderWidth);
|
|
130
|
+
if (forceOverlay != null) extra.force_overlay = forceOverlay;
|
|
131
|
+
return this.book.tableNew(n(bar, 0), Object.keys(extra).length ? extra : undefined);
|
|
108
132
|
}
|
|
109
133
|
|
|
110
134
|
polyline_new(bar: unknown, points?: unknown): number {
|