@coderyo/pine-lite 1.0.0-rc.4 → 1.0.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.
@@ -0,0 +1,228 @@
1
+ // src/vm.ts
2
+ import { ema, rsi, sma } from "@coderyo/indicators";
3
+ var MAX_STEPS_PER_BAR = 1e5;
4
+ function barsForSeries(bars, series) {
5
+ switch (series) {
6
+ case "hl2":
7
+ return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));
8
+ case "hlc3":
9
+ return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));
10
+ case "open":
11
+ return bars.map((b) => ({ ...b, c: b.o }));
12
+ case "high":
13
+ return bars.map((b) => ({ ...b, c: b.h }));
14
+ case "low":
15
+ return bars.map((b) => ({ ...b, c: b.l }));
16
+ case "volume":
17
+ return bars.map((b) => ({ ...b, c: b.v ?? 0 }));
18
+ case "close":
19
+ default:
20
+ return bars;
21
+ }
22
+ }
23
+ function seriesAt(bars, series, index) {
24
+ const b = bars[index];
25
+ switch (series) {
26
+ case "open":
27
+ return b.o;
28
+ case "high":
29
+ return b.h;
30
+ case "low":
31
+ return b.l;
32
+ case "volume":
33
+ return b.v ?? 0;
34
+ case "hl2":
35
+ return (b.h + b.l) / 2;
36
+ case "hlc3":
37
+ return (b.h + b.l + b.c) / 3;
38
+ case "close":
39
+ default:
40
+ return b.c;
41
+ }
42
+ }
43
+ function highestAt(bars, series, index, period) {
44
+ const p = Math.max(1, Math.floor(period));
45
+ if (index < p - 1) return null;
46
+ let max = -Infinity;
47
+ for (let i = index - p + 1; i <= index; i++) {
48
+ const v = seriesAt(bars, series, i);
49
+ if (v > max) max = v;
50
+ }
51
+ return Number.isFinite(max) ? max : null;
52
+ }
53
+ function lowestAt(bars, series, index, period) {
54
+ const p = Math.max(1, Math.floor(period));
55
+ if (index < p - 1) return null;
56
+ let min = Infinity;
57
+ for (let i = index - p + 1; i <= index; i++) {
58
+ const v = seriesAt(bars, series, i);
59
+ if (v < min) min = v;
60
+ }
61
+ return Number.isFinite(min) ? min : null;
62
+ }
63
+ function crossAt(bars, seriesA, seriesB, index, mode) {
64
+ if (index < 1) return 0;
65
+ const a0 = seriesAt(bars, seriesA, index);
66
+ const b0 = seriesAt(bars, seriesB, index);
67
+ const a1 = seriesAt(bars, seriesA, index - 1);
68
+ const b1 = seriesAt(bars, seriesB, index - 1);
69
+ if (mode === "over") return a1 <= b1 && a0 > b0 ? 1 : 0;
70
+ return a1 >= b1 && a0 < b0 ? 1 : 0;
71
+ }
72
+ function indicatorAt(fn, bars, series, index, period, series2) {
73
+ if (fn === "crossover" || fn === "crossunder") {
74
+ if (!series2) return 0;
75
+ return crossAt(bars, series, series2, index, fn === "crossover" ? "over" : "under");
76
+ }
77
+ if (fn === "highest") return highestAt(bars, series, index, period);
78
+ if (fn === "lowest") return lowestAt(bars, series, index, period);
79
+ const src = barsForSeries(bars, series);
80
+ const p = Math.max(1, Math.floor(period));
81
+ const slice = src.slice(0, index + 1);
82
+ if (fn === "sma") return sma(slice, p)[index] ?? null;
83
+ if (fn === "ema") return ema(slice, p)[index] ?? null;
84
+ return rsi(slice, p)[index] ?? null;
85
+ }
86
+ function truthy(v) {
87
+ return Number.isFinite(v) && v !== 0;
88
+ }
89
+ function execOp(op, stack, bars, barIndex, vars, plotBuffers) {
90
+ const pop = () => stack.pop() ?? NaN;
91
+ switch (op.op) {
92
+ case "push":
93
+ stack.push(op.value);
94
+ break;
95
+ case "load_series":
96
+ stack.push(seriesAt(bars, op.name, barIndex));
97
+ break;
98
+ case "load_var": {
99
+ const s = vars.get(op.name);
100
+ stack.push(s?.[barIndex] ?? NaN);
101
+ break;
102
+ }
103
+ case "store_var": {
104
+ const v = pop();
105
+ const s = vars.get(op.name);
106
+ if (s) s[barIndex] = Number.isFinite(v) ? v : null;
107
+ break;
108
+ }
109
+ case "call_ind": {
110
+ if (op.fn === "crossover" || op.fn === "crossunder") {
111
+ const v2 = indicatorAt(op.fn, bars, op.series, barIndex, 0, op.series2);
112
+ stack.push(v2 ?? 0);
113
+ break;
114
+ }
115
+ const period = pop();
116
+ const v = indicatorAt(op.fn, bars, op.series, barIndex, period, op.series2);
117
+ stack.push(v ?? NaN);
118
+ break;
119
+ }
120
+ case "add":
121
+ stack.push(pop() + pop());
122
+ break;
123
+ case "sub":
124
+ stack.push(pop() - pop());
125
+ break;
126
+ case "mul":
127
+ stack.push(pop() * pop());
128
+ break;
129
+ case "div": {
130
+ const b = pop();
131
+ const a = pop();
132
+ stack.push(b === 0 ? NaN : a / b);
133
+ break;
134
+ }
135
+ case "neg":
136
+ stack.push(-pop());
137
+ break;
138
+ case "not":
139
+ stack.push(truthy(pop()) ? 0 : 1);
140
+ break;
141
+ case "cmp": {
142
+ const b = pop();
143
+ const a = pop();
144
+ let r = false;
145
+ switch (op.mode) {
146
+ case "eq":
147
+ r = a === b;
148
+ break;
149
+ case "ne":
150
+ r = a !== b;
151
+ break;
152
+ case "lt":
153
+ r = a < b;
154
+ break;
155
+ case "gt":
156
+ r = a > b;
157
+ break;
158
+ case "le":
159
+ r = a <= b;
160
+ break;
161
+ case "ge":
162
+ r = a >= b;
163
+ break;
164
+ }
165
+ stack.push(r ? 1 : 0);
166
+ break;
167
+ }
168
+ case "and": {
169
+ const b = pop();
170
+ const a = pop();
171
+ stack.push(truthy(a) && truthy(b) ? 1 : 0);
172
+ break;
173
+ }
174
+ case "or": {
175
+ const b = pop();
176
+ const a = pop();
177
+ stack.push(truthy(a) || truthy(b) ? 1 : 0);
178
+ break;
179
+ }
180
+ case "pop":
181
+ pop();
182
+ break;
183
+ case "plot": {
184
+ const v = pop();
185
+ const buf = plotBuffers.get(op.title);
186
+ if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;
187
+ break;
188
+ }
189
+ case "jump":
190
+ return op.target;
191
+ case "jump_if_false":
192
+ return truthy(pop()) ? -1 : op.target;
193
+ default:
194
+ break;
195
+ }
196
+ return -1;
197
+ }
198
+ function runPineIr(ir, bars) {
199
+ const n = bars.length;
200
+ const vars = /* @__PURE__ */ new Map();
201
+ for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));
202
+ const plotBuffers = /* @__PURE__ */ new Map();
203
+ for (const title of ir.plots) {
204
+ plotBuffers.set(title, Array.from({ length: n }, () => null));
205
+ }
206
+ for (let i = 0; i < n; i++) {
207
+ const stack = [];
208
+ let pc = 0;
209
+ let steps = 0;
210
+ while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {
211
+ steps++;
212
+ const jmp = execOp(ir.ops[pc], stack, bars, i, vars, plotBuffers);
213
+ if (jmp >= 0) pc = jmp;
214
+ else pc++;
215
+ }
216
+ }
217
+ return {
218
+ plots: ir.plots.map((title) => ({
219
+ title,
220
+ values: plotBuffers.get(title) ?? []
221
+ }))
222
+ };
223
+ }
224
+
225
+ export {
226
+ runPineIr
227
+ };
228
+ //# sourceMappingURL=chunk-JLVAE3JC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vm.ts"],"sourcesContent":["import type { Bar } from '@coderyo/data';\nimport { ema, rsi, sma } from '@coderyo/indicators';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nexport interface PinePlotSeries {\n title: string;\n values: (number | null)[];\n}\n\nexport interface PineRunResult {\n plots: PinePlotSeries[];\n}\n\nconst MAX_STEPS_PER_BAR = 100_000;\n\nfunction barsForSeries(bars: Bar[], series: string): Bar[] {\n switch (series) {\n case 'hl2':\n return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));\n case 'hlc3':\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n case 'open':\n return bars.map((b) => ({ ...b, c: b.o }));\n case 'high':\n return bars.map((b) => ({ ...b, c: b.h }));\n case 'low':\n return bars.map((b) => ({ ...b, c: b.l }));\n case 'volume':\n return bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n case 'close':\n default:\n return bars;\n }\n}\n\nfunction seriesAt(bars: Bar[], series: string, index: number): number {\n const b = bars[index]!;\n switch (series) {\n case 'open':\n return b.o;\n case 'high':\n return b.h;\n case 'low':\n return b.l;\n case 'volume':\n return b.v ?? 0;\n case 'hl2':\n return (b.h + b.l) / 2;\n case 'hlc3':\n return (b.h + b.l + b.c) / 3;\n case 'close':\n default:\n return b.c;\n }\n}\n\nfunction highestAt(bars: Bar[], series: string, index: number, period: number): number | null {\n const p = Math.max(1, Math.floor(period));\n if (index < p - 1) return null;\n let max = -Infinity;\n for (let i = index - p + 1; i <= index; i++) {\n const v = seriesAt(bars, series, i);\n if (v > max) max = v;\n }\n return Number.isFinite(max) ? max : null;\n}\n\nfunction lowestAt(bars: Bar[], series: string, index: number, period: number): number | null {\n const p = Math.max(1, Math.floor(period));\n if (index < p - 1) return null;\n let min = Infinity;\n for (let i = index - p + 1; i <= index; i++) {\n const v = seriesAt(bars, series, i);\n if (v < min) min = v;\n }\n return Number.isFinite(min) ? min : null;\n}\n\nfunction crossAt(\n bars: Bar[],\n seriesA: string,\n seriesB: string,\n index: number,\n mode: 'over' | 'under',\n): number {\n if (index < 1) return 0;\n const a0 = seriesAt(bars, seriesA, index);\n const b0 = seriesAt(bars, seriesB, index);\n const a1 = seriesAt(bars, seriesA, index - 1);\n const b1 = seriesAt(bars, seriesB, index - 1);\n if (mode === 'over') return a1 <= b1 && a0 > b0 ? 1 : 0;\n return a1 >= b1 && a0 < b0 ? 1 : 0;\n}\n\nfunction indicatorAt(\n fn: 'sma' | 'ema' | 'rsi' | 'highest' | 'lowest' | 'crossover' | 'crossunder',\n bars: Bar[],\n series: string,\n index: number,\n period: number,\n series2?: string,\n): number | null {\n if (fn === 'crossover' || fn === 'crossunder') {\n if (!series2) return 0;\n return crossAt(bars, series, series2, index, fn === 'crossover' ? 'over' : 'under');\n }\n if (fn === 'highest') return highestAt(bars, series, index, period);\n if (fn === 'lowest') return lowestAt(bars, series, index, period);\n const src = barsForSeries(bars, series);\n const p = Math.max(1, Math.floor(period));\n const slice = src.slice(0, index + 1);\n if (fn === 'sma') return sma(slice, p)[index] ?? null;\n if (fn === 'ema') return ema(slice, p)[index] ?? null;\n return rsi(slice, p)[index] ?? null;\n}\n\nfunction truthy(v: number): boolean {\n return Number.isFinite(v) && v !== 0;\n}\n\nfunction execOp(\n op: IrOp,\n stack: number[],\n bars: Bar[],\n barIndex: number,\n vars: Map<string, (number | null)[]>,\n plotBuffers: Map<string, (number | null)[]>,\n): number {\n const pop = () => stack.pop() ?? NaN;\n switch (op.op) {\n case 'push':\n stack.push(op.value);\n break;\n case 'load_series':\n stack.push(seriesAt(bars, op.name, barIndex));\n break;\n case 'load_var': {\n const s = vars.get(op.name);\n stack.push(s?.[barIndex] ?? NaN);\n break;\n }\n case 'store_var': {\n const v = pop();\n const s = vars.get(op.name);\n if (s) s[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'call_ind': {\n if (op.fn === 'crossover' || op.fn === 'crossunder') {\n const v = indicatorAt(op.fn, bars, op.series, barIndex, 0, op.series2);\n stack.push(v ?? 0);\n break;\n }\n const period = pop();\n const v = indicatorAt(op.fn, bars, op.series, barIndex, period, op.series2);\n stack.push(v ?? NaN);\n break;\n }\n case 'add':\n stack.push(pop() + pop());\n break;\n case 'sub':\n stack.push(pop() - pop());\n break;\n case 'mul':\n stack.push(pop() * pop());\n break;\n case 'div': {\n const b = pop();\n const a = pop();\n stack.push(b === 0 ? NaN : a / b);\n break;\n }\n case 'neg':\n stack.push(-pop());\n break;\n case 'not':\n stack.push(truthy(pop()) ? 0 : 1);\n break;\n case 'cmp': {\n const b = pop();\n const a = pop();\n let r = false;\n switch (op.mode) {\n case 'eq':\n r = a === b;\n break;\n case 'ne':\n r = a !== b;\n break;\n case 'lt':\n r = a < b;\n break;\n case 'gt':\n r = a > b;\n break;\n case 'le':\n r = a <= b;\n break;\n case 'ge':\n r = a >= b;\n break;\n }\n stack.push(r ? 1 : 0);\n break;\n }\n case 'and': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) && truthy(b) ? 1 : 0);\n break;\n }\n case 'or': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) || truthy(b) ? 1 : 0);\n break;\n }\n case 'pop':\n pop();\n break;\n case 'plot': {\n const v = pop();\n const buf = plotBuffers.get(op.title);\n if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'jump':\n return op.target;\n case 'jump_if_false':\n return truthy(pop()) ? -1 : op.target;\n default:\n break;\n }\n return -1;\n}\n\nexport function runPineIr(ir: PineIrProgram, bars: Bar[]): PineRunResult {\n const n = bars.length;\n const vars = new Map<string, (number | null)[]>();\n for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));\n\n const plotBuffers = new Map<string, (number | null)[]>();\n for (const title of ir.plots) {\n plotBuffers.set(title, Array.from({ length: n }, () => null));\n }\n\n for (let i = 0; i < n; i++) {\n const stack: number[] = [];\n let pc = 0;\n let steps = 0;\n while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {\n steps++;\n const jmp = execOp(ir.ops[pc]!, stack, bars, i, vars, plotBuffers);\n if (jmp >= 0) pc = jmp;\n else pc++;\n }\n }\n\n return {\n plots: ir.plots.map((title) => ({\n title,\n values: plotBuffers.get(title) ?? [],\n })),\n };\n}"],"mappings":"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","names":["v"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import * as _coderyo_data from '@coderyo/data';
2
+ import { Bar } from '@coderyo/data';
3
+ import { P as PineIrProgram, a as PineRunResult } from './vm-DSG6hmZe.js';
4
+ export { b as PinePlotSeries } from './vm-DSG6hmZe.js';
2
5
 
3
6
  interface PineDiagnostic {
4
7
  line: number;
@@ -14,68 +17,6 @@ declare function offsetToLineCol(source: string, offset: number): {
14
17
  declare function diagnosticFromMessage(source: string, message: string): PineDiagnostic;
15
18
  declare function diagnosticsFromMessages(source: string, messages: string[]): PineDiagnostic[];
16
19
 
17
- type IrOp = {
18
- op: 'push';
19
- value: number;
20
- } | {
21
- op: 'load_series';
22
- name: string;
23
- } | {
24
- op: 'load_var';
25
- name: string;
26
- } | {
27
- op: 'store_var';
28
- name: string;
29
- } | {
30
- op: 'call_ind';
31
- fn: 'sma' | 'ema' | 'rsi';
32
- series: string;
33
- } | {
34
- op: 'add';
35
- } | {
36
- op: 'sub';
37
- } | {
38
- op: 'mul';
39
- } | {
40
- op: 'div';
41
- } | {
42
- op: 'neg';
43
- } | {
44
- op: 'not';
45
- } | {
46
- op: 'cmp';
47
- mode: 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge';
48
- } | {
49
- op: 'and';
50
- } | {
51
- op: 'or';
52
- } | {
53
- op: 'pop';
54
- } | {
55
- op: 'jump';
56
- target: number;
57
- } | {
58
- op: 'jump_if_false';
59
- target: number;
60
- } | {
61
- op: 'plot';
62
- title: string;
63
- };
64
- interface PineIrProgram {
65
- version: 2;
66
- ops: IrOp[];
67
- vars: string[];
68
- plots: string[];
69
- }
70
-
71
- interface PinePlotSeries {
72
- title: string;
73
- values: (number | null)[];
74
- }
75
- interface PineRunResult {
76
- plots: PinePlotSeries[];
77
- }
78
-
79
20
  type PineExpr = {
80
21
  kind: 'number';
81
22
  value: number;
@@ -138,6 +79,12 @@ interface PineProgram {
138
79
  body: PineStmt[];
139
80
  }
140
81
 
82
+ interface RunPineLiteAsyncOptions {
83
+ useWorker?: boolean;
84
+ }
85
+ declare function runPineLiteAsync(ir: PineIrProgram, bars: Bar[], opts?: RunPineLiteAsyncOptions): Promise<PineRunResult>;
86
+ declare function terminatePineWorker(): void;
87
+
141
88
  interface PineCompileResult {
142
89
  ok: boolean;
143
90
  errors: string[];
@@ -146,7 +93,8 @@ interface PineCompileResult {
146
93
  }
147
94
  declare function compilePineLite(source: string): PineCompileResult;
148
95
  declare function runPineLite(ir: PineIrProgram, bars: _coderyo_data.Bar[]): PineRunResult;
96
+
149
97
  declare const PINE_SAMPLE_SCRIPT = "// Pine-lite \u2014 if / while / for\u3001\u6BD4\u8F03\u3001and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n";
150
98
  declare const PINE_EDITOR_DEFAULT = "// Pine-lite \u2014 if / while / for\u3001\u6BD4\u8F03\u3001and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n";
151
99
 
152
- export { PINE_EDITOR_DEFAULT, PINE_SAMPLE_SCRIPT, type PineCompileResult, type PineDiagnostic, type PineIrProgram, type PinePlotSeries, type PineProgram, type PineRunResult, compilePineLite, diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol, runPineLite };
100
+ export { PINE_EDITOR_DEFAULT, PINE_SAMPLE_SCRIPT, type PineCompileResult, type PineDiagnostic, PineIrProgram, type PineProgram, PineRunResult, type RunPineLiteAsyncOptions, compilePineLite, diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol, runPineLite, runPineLiteAsync, terminatePineWorker };
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ runPineIr
3
+ } from "./chunk-JLVAE3JC.js";
4
+
1
5
  // src/builtins.ts
2
6
  var SERIES_IDENTIFIERS = /* @__PURE__ */ new Set([
3
7
  "close",
@@ -8,13 +12,24 @@ var SERIES_IDENTIFIERS = /* @__PURE__ */ new Set([
8
12
  "hl2",
9
13
  "hlc3"
10
14
  ]);
11
- var INDICATOR_BUILTINS = /* @__PURE__ */ new Set(["sma", "ema", "rsi"]);
15
+ var INDICATOR_BUILTINS = /* @__PURE__ */ new Set([
16
+ "sma",
17
+ "ema",
18
+ "rsi",
19
+ "highest",
20
+ "lowest",
21
+ "crossover",
22
+ "crossunder"
23
+ ]);
12
24
  function isBuiltin(name) {
13
25
  return SERIES_IDENTIFIERS.has(name) || INDICATOR_BUILTINS.has(name);
14
26
  }
15
27
  function builtinArity(name) {
16
28
  if (SERIES_IDENTIFIERS.has(name)) return 0;
17
- if (name === "sma" || name === "ema" || name === "rsi") return 2;
29
+ if (name === "sma" || name === "ema" || name === "rsi" || name === "highest" || name === "lowest") {
30
+ return 2;
31
+ }
32
+ if (name === "crossover" || name === "crossunder") return 2;
18
33
  return null;
19
34
  }
20
35
 
@@ -86,7 +101,16 @@ var Emitter = class {
86
101
  return false;
87
102
  }
88
103
  const fn = expr.name;
89
- if ((fn === "sma" || fn === "ema" || fn === "rsi") && expr.args[0]?.kind === "ident" && SERIES_IDENTIFIERS.has(expr.args[0].name)) {
104
+ if ((fn === "crossover" || fn === "crossunder") && expr.args[0]?.kind === "ident" && expr.args[1]?.kind === "ident" && SERIES_IDENTIFIERS.has(expr.args[0].name) && SERIES_IDENTIFIERS.has(expr.args[1].name)) {
105
+ this.emit({
106
+ op: "call_ind",
107
+ fn,
108
+ series: expr.args[0].name,
109
+ series2: expr.args[1].name
110
+ });
111
+ return true;
112
+ }
113
+ if ((fn === "sma" || fn === "ema" || fn === "rsi" || fn === "highest" || fn === "lowest") && expr.args[0]?.kind === "ident" && SERIES_IDENTIFIERS.has(expr.args[0].name)) {
90
114
  if (!this.emitExpr(expr.args[1], errors, vars)) return false;
91
115
  this.emit({ op: "call_ind", fn, series: expr.args[0].name });
92
116
  return true;
@@ -629,188 +653,51 @@ function parseProgram(tokens) {
629
653
  return { program: { kind: "program", body }, errors };
630
654
  }
631
655
 
632
- // src/vm.ts
633
- import { ema, rsi, sma } from "@coderyo/indicators";
634
- var MAX_STEPS_PER_BAR = 1e5;
635
- function barsForSeries(bars, series) {
636
- switch (series) {
637
- case "hl2":
638
- return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));
639
- case "hlc3":
640
- return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));
641
- case "open":
642
- return bars.map((b) => ({ ...b, c: b.o }));
643
- case "high":
644
- return bars.map((b) => ({ ...b, c: b.h }));
645
- case "low":
646
- return bars.map((b) => ({ ...b, c: b.l }));
647
- case "volume":
648
- return bars.map((b) => ({ ...b, c: b.v ?? 0 }));
649
- case "close":
650
- default:
651
- return bars;
652
- }
653
- }
654
- function seriesAt(bars, series, index) {
655
- const b = bars[index];
656
- switch (series) {
657
- case "open":
658
- return b.o;
659
- case "high":
660
- return b.h;
661
- case "low":
662
- return b.l;
663
- case "volume":
664
- return b.v ?? 0;
665
- case "hl2":
666
- return (b.h + b.l) / 2;
667
- case "hlc3":
668
- return (b.h + b.l + b.c) / 3;
669
- case "close":
670
- default:
671
- return b.c;
656
+ // src/worker-client.ts
657
+ var worker = null;
658
+ var seq = 0;
659
+ var pending = /* @__PURE__ */ new Map();
660
+ function ensureWorker() {
661
+ if (typeof Worker === "undefined") return null;
662
+ if (worker) return worker;
663
+ try {
664
+ worker = new Worker(new URL("./pine.worker.js", import.meta.url), { type: "module" });
665
+ worker.onmessage = (ev) => {
666
+ const msg = ev.data;
667
+ const p = pending.get(msg.id);
668
+ if (!p) return;
669
+ pending.delete(msg.id);
670
+ if (msg.ok && msg.result) p.resolve(msg.result);
671
+ else p.reject(new Error(msg.error ?? "Pine worker failed"));
672
+ };
673
+ worker.onerror = () => {
674
+ for (const [, p] of pending) p.reject(new Error("Pine worker error"));
675
+ pending.clear();
676
+ worker?.terminate();
677
+ worker = null;
678
+ };
679
+ return worker;
680
+ } catch {
681
+ return null;
672
682
  }
673
683
  }
674
- function indicatorAt(fn, bars, series, index, period) {
675
- const src = barsForSeries(bars, series);
676
- const p = Math.max(1, Math.floor(period));
677
- const slice = src.slice(0, index + 1);
678
- if (fn === "sma") return sma(slice, p)[index] ?? null;
679
- if (fn === "ema") return ema(slice, p)[index] ?? null;
680
- return rsi(slice, p)[index] ?? null;
681
- }
682
- function truthy(v) {
683
- return Number.isFinite(v) && v !== 0;
684
- }
685
- function execOp(op, stack, bars, barIndex, vars, plotBuffers) {
686
- const pop = () => stack.pop() ?? NaN;
687
- switch (op.op) {
688
- case "push":
689
- stack.push(op.value);
690
- break;
691
- case "load_series":
692
- stack.push(seriesAt(bars, op.name, barIndex));
693
- break;
694
- case "load_var": {
695
- const s = vars.get(op.name);
696
- stack.push(s?.[barIndex] ?? NaN);
697
- break;
698
- }
699
- case "store_var": {
700
- const v = pop();
701
- const s = vars.get(op.name);
702
- if (s) s[barIndex] = Number.isFinite(v) ? v : null;
703
- break;
704
- }
705
- case "call_ind": {
706
- const period = pop();
707
- const v = indicatorAt(op.fn, bars, op.series, barIndex, period);
708
- stack.push(v ?? NaN);
709
- break;
710
- }
711
- case "add":
712
- stack.push(pop() + pop());
713
- break;
714
- case "sub":
715
- stack.push(pop() - pop());
716
- break;
717
- case "mul":
718
- stack.push(pop() * pop());
719
- break;
720
- case "div": {
721
- const b = pop();
722
- const a = pop();
723
- stack.push(b === 0 ? NaN : a / b);
724
- break;
725
- }
726
- case "neg":
727
- stack.push(-pop());
728
- break;
729
- case "not":
730
- stack.push(truthy(pop()) ? 0 : 1);
731
- break;
732
- case "cmp": {
733
- const b = pop();
734
- const a = pop();
735
- let r = false;
736
- switch (op.mode) {
737
- case "eq":
738
- r = a === b;
739
- break;
740
- case "ne":
741
- r = a !== b;
742
- break;
743
- case "lt":
744
- r = a < b;
745
- break;
746
- case "gt":
747
- r = a > b;
748
- break;
749
- case "le":
750
- r = a <= b;
751
- break;
752
- case "ge":
753
- r = a >= b;
754
- break;
755
- }
756
- stack.push(r ? 1 : 0);
757
- break;
758
- }
759
- case "and": {
760
- const b = pop();
761
- const a = pop();
762
- stack.push(truthy(a) && truthy(b) ? 1 : 0);
763
- break;
764
- }
765
- case "or": {
766
- const b = pop();
767
- const a = pop();
768
- stack.push(truthy(a) || truthy(b) ? 1 : 0);
769
- break;
770
- }
771
- case "pop":
772
- pop();
773
- break;
774
- case "plot": {
775
- const v = pop();
776
- const buf = plotBuffers.get(op.title);
777
- if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;
778
- break;
779
- }
780
- case "jump":
781
- return op.target;
782
- case "jump_if_false":
783
- return truthy(pop()) ? -1 : op.target;
784
- default:
785
- break;
684
+ function runPineLiteAsync(ir, bars, opts) {
685
+ if (opts?.useWorker === false) {
686
+ return Promise.resolve(runPineIr(ir, bars));
786
687
  }
787
- return -1;
688
+ const w = ensureWorker();
689
+ if (!w) return Promise.resolve(runPineIr(ir, bars));
690
+ const id = ++seq;
691
+ const req = { id, ir, bars };
692
+ return new Promise((resolve, reject) => {
693
+ pending.set(id, { resolve, reject });
694
+ w.postMessage(req);
695
+ });
788
696
  }
789
- function runPineIr(ir, bars) {
790
- const n = bars.length;
791
- const vars = /* @__PURE__ */ new Map();
792
- for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));
793
- const plotBuffers = /* @__PURE__ */ new Map();
794
- for (const title of ir.plots) {
795
- plotBuffers.set(title, Array.from({ length: n }, () => null));
796
- }
797
- for (let i = 0; i < n; i++) {
798
- const stack = [];
799
- let pc = 0;
800
- let steps = 0;
801
- while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {
802
- steps++;
803
- const jmp = execOp(ir.ops[pc], stack, bars, i, vars, plotBuffers);
804
- if (jmp >= 0) pc = jmp;
805
- else pc++;
806
- }
807
- }
808
- return {
809
- plots: ir.plots.map((title) => ({
810
- title,
811
- values: plotBuffers.get(title) ?? []
812
- }))
813
- };
697
+ function terminatePineWorker() {
698
+ worker?.terminate();
699
+ worker = null;
700
+ pending.clear();
814
701
  }
815
702
 
816
703
  // src/index.ts
@@ -874,6 +761,8 @@ export {
874
761
  diagnosticFromMessage,
875
762
  diagnosticsFromMessages,
876
763
  offsetToLineCol,
877
- runPineLite
764
+ runPineLite,
765
+ runPineLiteAsync,
766
+ terminatePineWorker
878
767
  };
879
768
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/builtins.ts","../src/compile.ts","../src/diagnostics.ts","../src/lexer.ts","../src/parser.ts","../src/vm.ts","../src/index.ts"],"sourcesContent":["/** Built-in series accessors and indicators (Pine-lite v1 whitelist). */\nexport const SERIES_IDENTIFIERS = new Set([\n 'close',\n 'open',\n 'high',\n 'low',\n 'volume',\n 'hl2',\n 'hlc3',\n]);\n\nexport const INDICATOR_BUILTINS = new Set(['sma', 'ema', 'rsi']);\n\nexport function isBuiltin(name: string): boolean {\n return SERIES_IDENTIFIERS.has(name) || INDICATOR_BUILTINS.has(name);\n}\n\nexport function builtinArity(name: string): number | null {\n if (SERIES_IDENTIFIERS.has(name)) return 0;\n if (name === 'sma' || name === 'ema' || name === 'rsi') return 2;\n return null;\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport { builtinArity, isBuiltin, SERIES_IDENTIFIERS } from './builtins.js';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nclass Emitter {\n ops: IrOp[] = [];\n private plotIndex = 0;\n\n emit(op: IrOp): number {\n this.ops.push(op);\n return this.ops.length - 1;\n }\n\n patchJump(index: number, target: number): void {\n const op = this.ops[index]!;\n if (op.op === 'jump' || op.op === 'jump_if_false') op.target = target;\n }\n\n emitExpr(expr: PineExpr, errors: string[], vars: Set<string>): boolean {\n switch (expr.kind) {\n case 'number':\n this.emit({ op: 'push', value: expr.value });\n return true;\n case 'bool':\n this.emit({ op: 'push', value: expr.value ? 1 : 0 });\n return true;\n case 'ident':\n if (vars.has(expr.name)) {\n this.emit({ op: 'load_var', name: expr.name });\n return true;\n }\n if (isBuiltin(expr.name) && builtinArity(expr.name) === 0) {\n this.emit({ op: 'load_series', name: expr.name });\n return true;\n }\n errors.push(`Unknown identifier '${expr.name}'`);\n return false;\n case 'unary':\n if (!this.emitExpr(expr.arg, errors, vars)) return false;\n this.emit({ op: expr.op === 'not' ? 'not' : 'neg' });\n return true;\n case 'binary':\n if (expr.op === 'and' || expr.op === 'or') {\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n this.emit({ op: expr.op });\n return true;\n }\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n if (expr.op === '+' || expr.op === '-' || expr.op === '*' || expr.op === '/') {\n this.emit({\n op: expr.op === '+' ? 'add' : expr.op === '-' ? 'sub' : expr.op === '*' ? 'mul' : 'div',\n });\n return true;\n }\n this.emit({\n op: 'cmp',\n mode:\n expr.op === '=='\n ? 'eq'\n : expr.op === '!='\n ? 'ne'\n : expr.op === '<'\n ? 'lt'\n : expr.op === '>'\n ? 'gt'\n : expr.op === '<='\n ? 'le'\n : 'ge',\n });\n return true;\n case 'call': {\n const arity = builtinArity(expr.name);\n if (arity == null) {\n errors.push(`Unknown function '${expr.name}'`);\n return false;\n }\n if (expr.args.length !== arity) {\n errors.push(`'${expr.name}' expects ${arity} arguments, got ${expr.args.length}`);\n return false;\n }\n const fn = expr.name as 'sma' | 'ema' | 'rsi';\n if (\n (fn === 'sma' || fn === 'ema' || fn === 'rsi') &&\n expr.args[0]?.kind === 'ident' &&\n SERIES_IDENTIFIERS.has(expr.args[0].name)\n ) {\n if (!this.emitExpr(expr.args[1]!, errors, vars)) return false;\n this.emit({ op: 'call_ind', fn, series: expr.args[0].name });\n return true;\n }\n for (const arg of expr.args) {\n if (!this.emitExpr(arg, errors, vars)) return false;\n }\n return true;\n }\n default:\n return false;\n }\n }\n\n emitStmt(stmt: PineStmt, errors: string[], vars: Set<string>, plots: string[]): void {\n switch (stmt.kind) {\n case 'block':\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n break;\n case 'var':\n vars.add(stmt.name);\n if (this.emitExpr(stmt.init, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'assign':\n if (!vars.has(stmt.name)) vars.add(stmt.name);\n if (this.emitExpr(stmt.value, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'plot': {\n if (!this.emitExpr(stmt.expr, errors, vars)) break;\n const title = stmt.title ?? `plot_${this.plotIndex++}`;\n plots.push(title);\n this.emit({ op: 'plot', title });\n break;\n }\n case 'expr':\n if (this.emitExpr(stmt.expr, errors, vars)) this.emit({ op: 'pop' });\n break;\n case 'if': {\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpFalse = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.then) this.emitStmt(s, errors, vars, plots);\n if (stmt.else?.length) {\n const jmpEnd = this.emit({ op: 'jump', target: 0 });\n this.patchJump(jmpFalse, this.ops.length);\n for (const s of stmt.else) this.emitStmt(s, errors, vars, plots);\n this.patchJump(jmpEnd, this.ops.length);\n } else {\n this.patchJump(jmpFalse, this.ops.length);\n }\n break;\n }\n case 'while': {\n const loopStart = this.ops.length;\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n case 'for': {\n vars.add(stmt.name);\n if (!this.emitExpr(stmt.from, errors, vars)) break;\n this.emit({ op: 'store_var', name: stmt.name });\n const loopStart = this.ops.length;\n this.emit({ op: 'load_var', name: stmt.name });\n if (!this.emitExpr(stmt.to, errors, vars)) break;\n this.emit({ op: 'cmp', mode: 'le' });\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'load_var', name: stmt.name });\n this.emit({ op: 'push', value: 1 });\n this.emit({ op: 'add' });\n this.emit({ op: 'store_var', name: stmt.name });\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n }\n }\n}\n\nexport function compileAst(program: PineProgram): { ir: PineIrProgram | null; errors: string[] } {\n const errors: string[] = [];\n const vars = new Set<string>();\n const plots: string[] = [];\n const emitter = new Emitter();\n\n for (const stmt of program.body) {\n emitter.emitStmt(stmt, errors, vars, plots);\n }\n\n if (errors.length) return { ir: null, errors };\n\n return {\n ir: { version: 2, ops: emitter.ops, vars: [...vars], plots },\n errors,\n };\n}","export interface PineDiagnostic {\n line: number;\n col: number;\n message: string;\n severity: 'error' | 'warning';\n endCol?: number;\n}\n\nexport function offsetToLineCol(source: string, offset: number): { line: number; col: number } {\n let line = 1;\n let col = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === '\\n') {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, col };\n}\n\nexport function diagnosticFromMessage(source: string, message: string): PineDiagnostic {\n const at = message.match(/\\bat\\s+(\\d+)\\b/);\n if (at) {\n const pos = Number(at[1]);\n const { line, col } = offsetToLineCol(source, pos);\n return { line, col, message: message.replace(/\\s+at\\s+\\d+\\s*$/, ''), severity: 'error' };\n }\n return { line: 1, col: 1, message, severity: 'error' };\n}\n\nexport function diagnosticsFromMessages(source: string, messages: string[]): PineDiagnostic[] {\n return messages.map((m) => diagnosticFromMessage(source, m));\n}","import type { Token } from './tokens.js';\n\nconst KEYWORDS: Record<string, Token['type']> = {\n var: 'var',\n plot: 'plot',\n if: 'if',\n else: 'else',\n while: 'while',\n for: 'for',\n to: 'to',\n and: 'and',\n or: 'or',\n not: 'not',\n true: 'true',\n false: 'false',\n};\n\nexport function tokenize(source: string): { tokens: Token[]; errors: string[] } {\n const tokens: Token[] = [];\n const errors: string[] = [];\n let i = 0;\n let line = 1;\n let col = 1;\n\n const push = (type: Token['type'], value: string, pos: number, startLine: number, startCol: number) => {\n tokens.push({ type, value, pos, line: startLine, col: startCol });\n };\n\n while (i < source.length) {\n const pos = i;\n const startLine = line;\n const startCol = col;\n const ch = source[i]!;\n\n if (ch === ' ' || ch === '\\t' || ch === '\\r') {\n i++;\n col++;\n continue;\n }\n if (ch === '\\n') {\n i++;\n line++;\n col = 1;\n continue;\n }\n if (ch === '/' && source[i + 1] === '/') {\n i += 2;\n col += 2;\n while (i < source.length && source[i] !== '\\n') {\n i++;\n col++;\n }\n continue;\n }\n if (ch >= '0' && ch <= '9') {\n let j = i + 1;\n while (j < source.length && /[0-9.]/.test(source[j]!)) j++;\n const raw = source.slice(i, j);\n push('number', raw, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (/[A-Za-z_]/.test(ch)) {\n let j = i + 1;\n while (j < source.length && /[A-Za-z0-9_]/.test(source[j]!)) j++;\n const word = source.slice(i, j);\n const kw = KEYWORDS[word];\n push(kw ?? 'ident', word, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (ch === ':' && source[i + 1] === '=') {\n push('assign', ':=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '=' && source[i + 1] === '=') {\n push('eq', '==', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '!' && source[i + 1] === '=') {\n push('ne', '!=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<' && source[i + 1] === '=') {\n push('le', '<=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '>' && source[i + 1] === '=') {\n push('ge', '>=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<') {\n push('lt', '<', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '>') {\n push('gt', '>', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '{') {\n push('lbrace', '{', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '}') {\n push('rbrace', '}', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '(') {\n push('lparen', '(', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ')') {\n push('rparen', ')', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ',') {\n push('comma', ',', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '+') {\n push('plus', '+', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '-') {\n push('minus', '-', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '*') {\n push('star', '*', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '/') {\n push('slash', '/', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '=') {\n push('eq', '=', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n\n errors.push(`Unexpected '${ch}' at line ${startLine}, col ${startCol}`);\n i++;\n col++;\n }\n\n tokens.push({ type: 'eof', value: '', pos: i, line, col });\n return { tokens, errors };\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport type { Token } from './tokens.js';\n\nexport function parseProgram(tokens: Token[]): {\n program: PineProgram | null;\n errors: Array<{ message: string; line: number; col: number }>;\n} {\n const errors: Array<{ message: string; line: number; col: number }> = [];\n let i = 0;\n\n const peek = () => tokens[i]!;\n const at = (t: Token['type']) => peek().type === t;\n const err = (msg: string) => {\n errors.push({ message: msg, line: peek().line, col: peek().col });\n };\n const eat = (t: Token['type']) => {\n if (!at(t)) {\n err(`Expected ${t}, got ${peek().type}`);\n return false;\n }\n i++;\n return true;\n };\n\n const parseBlock = (): PineStmt[] => {\n if (at('lbrace')) {\n i++;\n const body: PineStmt[] = [];\n while (!at('rbrace') && !at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n if (!eat('rbrace')) return body;\n return body;\n }\n const stmt = parseStmt();\n return stmt ? [stmt] : [];\n };\n\n const parseOr = (): PineExpr | null => {\n let left = parseAnd();\n if (!left) return null;\n while (at('or')) {\n i++;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: 'binary', op: 'or', left, right };\n }\n return left;\n };\n\n const parseAnd = (): PineExpr | null => {\n let left = parseCompare();\n if (!left) return null;\n while (at('and')) {\n i++;\n const right = parseCompare();\n if (!right) return null;\n left = { kind: 'binary', op: 'and', left, right };\n }\n return left;\n };\n\n const parseCompare = (): PineExpr | null => {\n let left = parseAdd();\n if (!left) return null;\n const cmpTypes = ['eq', 'ne', 'lt', 'gt', 'le', 'ge'] as const;\n while (cmpTypes.some((t) => at(t))) {\n const t = peek().type as (typeof cmpTypes)[number];\n const opMap = {\n eq: '==',\n ne: '!=',\n lt: '<',\n gt: '>',\n le: '<=',\n ge: '>=',\n } as const;\n i++;\n const right = parseAdd();\n if (!right) return null;\n left = { kind: 'binary', op: opMap[t], left, right };\n }\n return left;\n };\n\n const parseAdd = (): PineExpr | null => {\n let left = parseMul();\n if (!left) return null;\n while (at('plus') || at('minus')) {\n const op = peek().type === 'plus' ? '+' : '-';\n i++;\n const right = parseMul();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseMul = (): PineExpr | null => {\n let left = parseUnary();\n if (!left) return null;\n while (at('star') || at('slash')) {\n const op = peek().type === 'star' ? '*' : '/';\n i++;\n const right = parseUnary();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseUnary = (): PineExpr | null => {\n if (at('not')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: 'not', arg } : null;\n }\n if (at('minus')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: '-', arg } : null;\n }\n return parsePrimary();\n };\n\n const parsePrimary = (): PineExpr | null => {\n const t = peek();\n if (t.type === 'number') {\n i++;\n return { kind: 'number', value: Number(t.value) };\n }\n if (t.type === 'true' || t.type === 'false') {\n i++;\n return { kind: 'bool', value: t.type === 'true' };\n }\n if (t.type === 'ident') {\n const name = t.value;\n i++;\n if (at('lparen')) {\n i++;\n const args: PineExpr[] = [];\n if (!at('rparen')) {\n const first = parseOr();\n if (!first) return null;\n args.push(first);\n while (at('comma')) {\n i++;\n const next = parseOr();\n if (!next) return null;\n args.push(next);\n }\n }\n if (!eat('rparen')) return null;\n return { kind: 'call', name, args };\n }\n return { kind: 'ident', name };\n }\n if (at('lparen')) {\n i++;\n const inner = parseOr();\n if (!inner || !eat('rparen')) return null;\n return inner;\n }\n err(`Unexpected token ${t.type}`);\n return null;\n };\n\n const parseStmt = (): PineStmt | null => {\n if (at('if')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const then = parseBlock();\n let elseBody: PineStmt[] | undefined;\n if (at('else')) {\n i++;\n elseBody = parseBlock();\n }\n return { kind: 'if', cond, then, else: elseBody };\n }\n if (at('while')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const body = parseBlock();\n return { kind: 'while', cond, body };\n }\n if (at('for')) {\n i++;\n if (!at('ident')) {\n err('Expected loop variable after for');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const from = parseOr();\n if (!from || !at('to')) {\n err('Expected \"to\" in for loop');\n return null;\n }\n i++;\n const to = parseOr();\n if (!to) return null;\n const body = parseBlock();\n return { kind: 'for', name, from, to, body };\n }\n if (at('var')) {\n i++;\n if (!at('ident')) {\n err('Expected identifier after var');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const init = parseOr();\n return init ? { kind: 'var', name, init } : null;\n }\n if (at('plot')) {\n i++;\n if (!eat('lparen')) return null;\n const expr = parseOr();\n if (!expr || !eat('rparen')) return null;\n return { kind: 'plot', expr };\n }\n if (at('ident')) {\n const name = peek().value;\n i++;\n if (at('assign') || at('eq')) {\n i++;\n const value = parseOr();\n return value ? { kind: 'assign', name, value } : null;\n }\n i--;\n const expr = parseOr();\n return expr ? { kind: 'expr', expr } : null;\n }\n if (at('lbrace')) {\n return { kind: 'block', body: parseBlock() };\n }\n err(`Unexpected statement ${peek().type}`);\n return null;\n };\n\n const body: PineStmt[] = [];\n while (!at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n\n if (!at('eof')) err('Unexpected tokens after program end');\n return { program: { kind: 'program', body }, errors };\n}","import type { Bar } from '@coderyo/data';\nimport { ema, rsi, sma } from '@coderyo/indicators';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nexport interface PinePlotSeries {\n title: string;\n values: (number | null)[];\n}\n\nexport interface PineRunResult {\n plots: PinePlotSeries[];\n}\n\nconst MAX_STEPS_PER_BAR = 100_000;\n\nfunction barsForSeries(bars: Bar[], series: string): Bar[] {\n switch (series) {\n case 'hl2':\n return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));\n case 'hlc3':\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n case 'open':\n return bars.map((b) => ({ ...b, c: b.o }));\n case 'high':\n return bars.map((b) => ({ ...b, c: b.h }));\n case 'low':\n return bars.map((b) => ({ ...b, c: b.l }));\n case 'volume':\n return bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n case 'close':\n default:\n return bars;\n }\n}\n\nfunction seriesAt(bars: Bar[], series: string, index: number): number {\n const b = bars[index]!;\n switch (series) {\n case 'open':\n return b.o;\n case 'high':\n return b.h;\n case 'low':\n return b.l;\n case 'volume':\n return b.v ?? 0;\n case 'hl2':\n return (b.h + b.l) / 2;\n case 'hlc3':\n return (b.h + b.l + b.c) / 3;\n case 'close':\n default:\n return b.c;\n }\n}\n\nfunction indicatorAt(\n fn: 'sma' | 'ema' | 'rsi',\n bars: Bar[],\n series: string,\n index: number,\n period: number,\n): number | null {\n const src = barsForSeries(bars, series);\n const p = Math.max(1, Math.floor(period));\n const slice = src.slice(0, index + 1);\n if (fn === 'sma') return sma(slice, p)[index] ?? null;\n if (fn === 'ema') return ema(slice, p)[index] ?? null;\n return rsi(slice, p)[index] ?? null;\n}\n\nfunction truthy(v: number): boolean {\n return Number.isFinite(v) && v !== 0;\n}\n\nfunction execOp(\n op: IrOp,\n stack: number[],\n bars: Bar[],\n barIndex: number,\n vars: Map<string, (number | null)[]>,\n plotBuffers: Map<string, (number | null)[]>,\n): number {\n const pop = () => stack.pop() ?? NaN;\n switch (op.op) {\n case 'push':\n stack.push(op.value);\n break;\n case 'load_series':\n stack.push(seriesAt(bars, op.name, barIndex));\n break;\n case 'load_var': {\n const s = vars.get(op.name);\n stack.push(s?.[barIndex] ?? NaN);\n break;\n }\n case 'store_var': {\n const v = pop();\n const s = vars.get(op.name);\n if (s) s[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'call_ind': {\n const period = pop();\n const v = indicatorAt(op.fn, bars, op.series, barIndex, period);\n stack.push(v ?? NaN);\n break;\n }\n case 'add':\n stack.push(pop() + pop());\n break;\n case 'sub':\n stack.push(pop() - pop());\n break;\n case 'mul':\n stack.push(pop() * pop());\n break;\n case 'div': {\n const b = pop();\n const a = pop();\n stack.push(b === 0 ? NaN : a / b);\n break;\n }\n case 'neg':\n stack.push(-pop());\n break;\n case 'not':\n stack.push(truthy(pop()) ? 0 : 1);\n break;\n case 'cmp': {\n const b = pop();\n const a = pop();\n let r = false;\n switch (op.mode) {\n case 'eq':\n r = a === b;\n break;\n case 'ne':\n r = a !== b;\n break;\n case 'lt':\n r = a < b;\n break;\n case 'gt':\n r = a > b;\n break;\n case 'le':\n r = a <= b;\n break;\n case 'ge':\n r = a >= b;\n break;\n }\n stack.push(r ? 1 : 0);\n break;\n }\n case 'and': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) && truthy(b) ? 1 : 0);\n break;\n }\n case 'or': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) || truthy(b) ? 1 : 0);\n break;\n }\n case 'pop':\n pop();\n break;\n case 'plot': {\n const v = pop();\n const buf = plotBuffers.get(op.title);\n if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'jump':\n return op.target;\n case 'jump_if_false':\n return truthy(pop()) ? -1 : op.target;\n default:\n break;\n }\n return -1;\n}\n\nexport function runPineIr(ir: PineIrProgram, bars: Bar[]): PineRunResult {\n const n = bars.length;\n const vars = new Map<string, (number | null)[]>();\n for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));\n\n const plotBuffers = new Map<string, (number | null)[]>();\n for (const title of ir.plots) {\n plotBuffers.set(title, Array.from({ length: n }, () => null));\n }\n\n for (let i = 0; i < n; i++) {\n const stack: number[] = [];\n let pc = 0;\n let steps = 0;\n while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {\n steps++;\n const jmp = execOp(ir.ops[pc]!, stack, bars, i, vars, plotBuffers);\n if (jmp >= 0) pc = jmp;\n else pc++;\n }\n }\n\n return {\n plots: ir.plots.map((title) => ({\n title,\n values: plotBuffers.get(title) ?? [],\n })),\n };\n}","import { compileAst } from './compile.js';\nimport { diagnosticFromMessage, type PineDiagnostic } from './diagnostics.js';\nimport { tokenize } from './lexer.js';\nimport { parseProgram } from './parser.js';\nimport type { PineIrProgram } from './ir.js';\nimport { runPineIr, type PinePlotSeries, type PineRunResult } from './vm.js';\n\nexport type { PinePlotSeries, PineRunResult, PineDiagnostic };\nexport type { PineIrProgram } from './ir.js';\nexport type { PineProgram } from './ast.js';\nexport { diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol } from './diagnostics.js';\n\nexport interface PineCompileResult {\n ok: boolean;\n errors: string[];\n diagnostics: PineDiagnostic[];\n ir?: PineIrProgram;\n}\n\nconst MAX_SOURCE_LEN = 32 * 1024;\n\nexport function compilePineLite(source: string): PineCompileResult {\n const diagnostics: PineDiagnostic[] = [];\n const pushDiag = (line: number, col: number, message: string) => {\n diagnostics.push({ line, col, message, severity: 'error' });\n };\n\n if (source.length > MAX_SOURCE_LEN) {\n const msg = `Source exceeds ${MAX_SOURCE_LEN} bytes`;\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n const { tokens, errors: lexErr } = tokenize(source);\n for (const m of lexErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (lexErr.length) {\n return { ok: false, errors: lexErr, diagnostics };\n }\n\n const { program, errors: parseErr } = parseProgram(tokens);\n for (const e of parseErr) pushDiag(e.line, e.col, e.message);\n if (parseErr.length || !program) {\n return { ok: false, errors: parseErr.map((e) => e.message), diagnostics };\n }\n\n const { ir, errors: compileErr } = compileAst(program);\n for (const m of compileErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (compileErr.length || !ir) {\n return { ok: false, errors: compileErr, diagnostics };\n }\n if (ir.plots.length > 16) {\n const msg = 'Too many plot() calls (max 16)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n if (ir.vars.length > 256) {\n const msg = 'Too many variables (max 256)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n return { ok: true, errors: [], diagnostics, ir };\n}\n\nexport function runPineLite(ir: PineIrProgram, bars: import('@coderyo/data').Bar[]): PineRunResult {\n return runPineIr(ir, bars);\n}\n\nexport const PINE_SAMPLE_SCRIPT = `// Pine-lite — if / while / for、比較、and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n`;\n\nexport const PINE_EDITOR_DEFAULT = PINE_SAMPLE_SCRIPT;"],"mappings":"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","names":["body","stmt"]}
1
+ {"version":3,"sources":["../src/builtins.ts","../src/compile.ts","../src/diagnostics.ts","../src/lexer.ts","../src/parser.ts","../src/worker-client.ts","../src/index.ts"],"sourcesContent":["/** Built-in series accessors and indicators (Pine-lite v1 whitelist). */\nexport const SERIES_IDENTIFIERS = new Set([\n 'close',\n 'open',\n 'high',\n 'low',\n 'volume',\n 'hl2',\n 'hlc3',\n]);\n\nexport const INDICATOR_BUILTINS = new Set([\n 'sma',\n 'ema',\n 'rsi',\n 'highest',\n 'lowest',\n 'crossover',\n 'crossunder',\n]);\n\nexport function isBuiltin(name: string): boolean {\n return SERIES_IDENTIFIERS.has(name) || INDICATOR_BUILTINS.has(name);\n}\n\nexport function builtinArity(name: string): number | null {\n if (SERIES_IDENTIFIERS.has(name)) return 0;\n if (name === 'sma' || name === 'ema' || name === 'rsi' || name === 'highest' || name === 'lowest') {\n return 2;\n }\n if (name === 'crossover' || name === 'crossunder') return 2;\n return null;\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport { builtinArity, isBuiltin, SERIES_IDENTIFIERS } from './builtins.js';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nclass Emitter {\n ops: IrOp[] = [];\n private plotIndex = 0;\n\n emit(op: IrOp): number {\n this.ops.push(op);\n return this.ops.length - 1;\n }\n\n patchJump(index: number, target: number): void {\n const op = this.ops[index]!;\n if (op.op === 'jump' || op.op === 'jump_if_false') op.target = target;\n }\n\n emitExpr(expr: PineExpr, errors: string[], vars: Set<string>): boolean {\n switch (expr.kind) {\n case 'number':\n this.emit({ op: 'push', value: expr.value });\n return true;\n case 'bool':\n this.emit({ op: 'push', value: expr.value ? 1 : 0 });\n return true;\n case 'ident':\n if (vars.has(expr.name)) {\n this.emit({ op: 'load_var', name: expr.name });\n return true;\n }\n if (isBuiltin(expr.name) && builtinArity(expr.name) === 0) {\n this.emit({ op: 'load_series', name: expr.name });\n return true;\n }\n errors.push(`Unknown identifier '${expr.name}'`);\n return false;\n case 'unary':\n if (!this.emitExpr(expr.arg, errors, vars)) return false;\n this.emit({ op: expr.op === 'not' ? 'not' : 'neg' });\n return true;\n case 'binary':\n if (expr.op === 'and' || expr.op === 'or') {\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n this.emit({ op: expr.op });\n return true;\n }\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n if (expr.op === '+' || expr.op === '-' || expr.op === '*' || expr.op === '/') {\n this.emit({\n op: expr.op === '+' ? 'add' : expr.op === '-' ? 'sub' : expr.op === '*' ? 'mul' : 'div',\n });\n return true;\n }\n this.emit({\n op: 'cmp',\n mode:\n expr.op === '=='\n ? 'eq'\n : expr.op === '!='\n ? 'ne'\n : expr.op === '<'\n ? 'lt'\n : expr.op === '>'\n ? 'gt'\n : expr.op === '<='\n ? 'le'\n : 'ge',\n });\n return true;\n case 'call': {\n const arity = builtinArity(expr.name);\n if (arity == null) {\n errors.push(`Unknown function '${expr.name}'`);\n return false;\n }\n if (expr.args.length !== arity) {\n errors.push(`'${expr.name}' expects ${arity} arguments, got ${expr.args.length}`);\n return false;\n }\n const fn = expr.name as\n | 'sma'\n | 'ema'\n | 'rsi'\n | 'highest'\n | 'lowest'\n | 'crossover'\n | 'crossunder';\n if (\n (fn === 'crossover' || fn === 'crossunder') &&\n expr.args[0]?.kind === 'ident' &&\n expr.args[1]?.kind === 'ident' &&\n SERIES_IDENTIFIERS.has(expr.args[0].name) &&\n SERIES_IDENTIFIERS.has(expr.args[1].name)\n ) {\n this.emit({\n op: 'call_ind',\n fn,\n series: expr.args[0].name,\n series2: expr.args[1].name,\n });\n return true;\n }\n if (\n (fn === 'sma' ||\n fn === 'ema' ||\n fn === 'rsi' ||\n fn === 'highest' ||\n fn === 'lowest') &&\n expr.args[0]?.kind === 'ident' &&\n SERIES_IDENTIFIERS.has(expr.args[0].name)\n ) {\n if (!this.emitExpr(expr.args[1]!, errors, vars)) return false;\n this.emit({ op: 'call_ind', fn, series: expr.args[0].name });\n return true;\n }\n for (const arg of expr.args) {\n if (!this.emitExpr(arg, errors, vars)) return false;\n }\n return true;\n }\n default:\n return false;\n }\n }\n\n emitStmt(stmt: PineStmt, errors: string[], vars: Set<string>, plots: string[]): void {\n switch (stmt.kind) {\n case 'block':\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n break;\n case 'var':\n vars.add(stmt.name);\n if (this.emitExpr(stmt.init, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'assign':\n if (!vars.has(stmt.name)) vars.add(stmt.name);\n if (this.emitExpr(stmt.value, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'plot': {\n if (!this.emitExpr(stmt.expr, errors, vars)) break;\n const title = stmt.title ?? `plot_${this.plotIndex++}`;\n plots.push(title);\n this.emit({ op: 'plot', title });\n break;\n }\n case 'expr':\n if (this.emitExpr(stmt.expr, errors, vars)) this.emit({ op: 'pop' });\n break;\n case 'if': {\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpFalse = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.then) this.emitStmt(s, errors, vars, plots);\n if (stmt.else?.length) {\n const jmpEnd = this.emit({ op: 'jump', target: 0 });\n this.patchJump(jmpFalse, this.ops.length);\n for (const s of stmt.else) this.emitStmt(s, errors, vars, plots);\n this.patchJump(jmpEnd, this.ops.length);\n } else {\n this.patchJump(jmpFalse, this.ops.length);\n }\n break;\n }\n case 'while': {\n const loopStart = this.ops.length;\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n case 'for': {\n vars.add(stmt.name);\n if (!this.emitExpr(stmt.from, errors, vars)) break;\n this.emit({ op: 'store_var', name: stmt.name });\n const loopStart = this.ops.length;\n this.emit({ op: 'load_var', name: stmt.name });\n if (!this.emitExpr(stmt.to, errors, vars)) break;\n this.emit({ op: 'cmp', mode: 'le' });\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'load_var', name: stmt.name });\n this.emit({ op: 'push', value: 1 });\n this.emit({ op: 'add' });\n this.emit({ op: 'store_var', name: stmt.name });\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n }\n }\n}\n\nexport function compileAst(program: PineProgram): { ir: PineIrProgram | null; errors: string[] } {\n const errors: string[] = [];\n const vars = new Set<string>();\n const plots: string[] = [];\n const emitter = new Emitter();\n\n for (const stmt of program.body) {\n emitter.emitStmt(stmt, errors, vars, plots);\n }\n\n if (errors.length) return { ir: null, errors };\n\n return {\n ir: { version: 2, ops: emitter.ops, vars: [...vars], plots },\n errors,\n };\n}","export interface PineDiagnostic {\n line: number;\n col: number;\n message: string;\n severity: 'error' | 'warning';\n endCol?: number;\n}\n\nexport function offsetToLineCol(source: string, offset: number): { line: number; col: number } {\n let line = 1;\n let col = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === '\\n') {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, col };\n}\n\nexport function diagnosticFromMessage(source: string, message: string): PineDiagnostic {\n const at = message.match(/\\bat\\s+(\\d+)\\b/);\n if (at) {\n const pos = Number(at[1]);\n const { line, col } = offsetToLineCol(source, pos);\n return { line, col, message: message.replace(/\\s+at\\s+\\d+\\s*$/, ''), severity: 'error' };\n }\n return { line: 1, col: 1, message, severity: 'error' };\n}\n\nexport function diagnosticsFromMessages(source: string, messages: string[]): PineDiagnostic[] {\n return messages.map((m) => diagnosticFromMessage(source, m));\n}","import type { Token } from './tokens.js';\n\nconst KEYWORDS: Record<string, Token['type']> = {\n var: 'var',\n plot: 'plot',\n if: 'if',\n else: 'else',\n while: 'while',\n for: 'for',\n to: 'to',\n and: 'and',\n or: 'or',\n not: 'not',\n true: 'true',\n false: 'false',\n};\n\nexport function tokenize(source: string): { tokens: Token[]; errors: string[] } {\n const tokens: Token[] = [];\n const errors: string[] = [];\n let i = 0;\n let line = 1;\n let col = 1;\n\n const push = (type: Token['type'], value: string, pos: number, startLine: number, startCol: number) => {\n tokens.push({ type, value, pos, line: startLine, col: startCol });\n };\n\n while (i < source.length) {\n const pos = i;\n const startLine = line;\n const startCol = col;\n const ch = source[i]!;\n\n if (ch === ' ' || ch === '\\t' || ch === '\\r') {\n i++;\n col++;\n continue;\n }\n if (ch === '\\n') {\n i++;\n line++;\n col = 1;\n continue;\n }\n if (ch === '/' && source[i + 1] === '/') {\n i += 2;\n col += 2;\n while (i < source.length && source[i] !== '\\n') {\n i++;\n col++;\n }\n continue;\n }\n if (ch >= '0' && ch <= '9') {\n let j = i + 1;\n while (j < source.length && /[0-9.]/.test(source[j]!)) j++;\n const raw = source.slice(i, j);\n push('number', raw, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (/[A-Za-z_]/.test(ch)) {\n let j = i + 1;\n while (j < source.length && /[A-Za-z0-9_]/.test(source[j]!)) j++;\n const word = source.slice(i, j);\n const kw = KEYWORDS[word];\n push(kw ?? 'ident', word, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (ch === ':' && source[i + 1] === '=') {\n push('assign', ':=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '=' && source[i + 1] === '=') {\n push('eq', '==', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '!' && source[i + 1] === '=') {\n push('ne', '!=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<' && source[i + 1] === '=') {\n push('le', '<=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '>' && source[i + 1] === '=') {\n push('ge', '>=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<') {\n push('lt', '<', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '>') {\n push('gt', '>', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '{') {\n push('lbrace', '{', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '}') {\n push('rbrace', '}', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '(') {\n push('lparen', '(', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ')') {\n push('rparen', ')', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ',') {\n push('comma', ',', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '+') {\n push('plus', '+', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '-') {\n push('minus', '-', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '*') {\n push('star', '*', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '/') {\n push('slash', '/', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '=') {\n push('eq', '=', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n\n errors.push(`Unexpected '${ch}' at line ${startLine}, col ${startCol}`);\n i++;\n col++;\n }\n\n tokens.push({ type: 'eof', value: '', pos: i, line, col });\n return { tokens, errors };\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport type { Token } from './tokens.js';\n\nexport function parseProgram(tokens: Token[]): {\n program: PineProgram | null;\n errors: Array<{ message: string; line: number; col: number }>;\n} {\n const errors: Array<{ message: string; line: number; col: number }> = [];\n let i = 0;\n\n const peek = () => tokens[i]!;\n const at = (t: Token['type']) => peek().type === t;\n const err = (msg: string) => {\n errors.push({ message: msg, line: peek().line, col: peek().col });\n };\n const eat = (t: Token['type']) => {\n if (!at(t)) {\n err(`Expected ${t}, got ${peek().type}`);\n return false;\n }\n i++;\n return true;\n };\n\n const parseBlock = (): PineStmt[] => {\n if (at('lbrace')) {\n i++;\n const body: PineStmt[] = [];\n while (!at('rbrace') && !at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n if (!eat('rbrace')) return body;\n return body;\n }\n const stmt = parseStmt();\n return stmt ? [stmt] : [];\n };\n\n const parseOr = (): PineExpr | null => {\n let left = parseAnd();\n if (!left) return null;\n while (at('or')) {\n i++;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: 'binary', op: 'or', left, right };\n }\n return left;\n };\n\n const parseAnd = (): PineExpr | null => {\n let left = parseCompare();\n if (!left) return null;\n while (at('and')) {\n i++;\n const right = parseCompare();\n if (!right) return null;\n left = { kind: 'binary', op: 'and', left, right };\n }\n return left;\n };\n\n const parseCompare = (): PineExpr | null => {\n let left = parseAdd();\n if (!left) return null;\n const cmpTypes = ['eq', 'ne', 'lt', 'gt', 'le', 'ge'] as const;\n while (cmpTypes.some((t) => at(t))) {\n const t = peek().type as (typeof cmpTypes)[number];\n const opMap = {\n eq: '==',\n ne: '!=',\n lt: '<',\n gt: '>',\n le: '<=',\n ge: '>=',\n } as const;\n i++;\n const right = parseAdd();\n if (!right) return null;\n left = { kind: 'binary', op: opMap[t], left, right };\n }\n return left;\n };\n\n const parseAdd = (): PineExpr | null => {\n let left = parseMul();\n if (!left) return null;\n while (at('plus') || at('minus')) {\n const op = peek().type === 'plus' ? '+' : '-';\n i++;\n const right = parseMul();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseMul = (): PineExpr | null => {\n let left = parseUnary();\n if (!left) return null;\n while (at('star') || at('slash')) {\n const op = peek().type === 'star' ? '*' : '/';\n i++;\n const right = parseUnary();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseUnary = (): PineExpr | null => {\n if (at('not')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: 'not', arg } : null;\n }\n if (at('minus')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: '-', arg } : null;\n }\n return parsePrimary();\n };\n\n const parsePrimary = (): PineExpr | null => {\n const t = peek();\n if (t.type === 'number') {\n i++;\n return { kind: 'number', value: Number(t.value) };\n }\n if (t.type === 'true' || t.type === 'false') {\n i++;\n return { kind: 'bool', value: t.type === 'true' };\n }\n if (t.type === 'ident') {\n const name = t.value;\n i++;\n if (at('lparen')) {\n i++;\n const args: PineExpr[] = [];\n if (!at('rparen')) {\n const first = parseOr();\n if (!first) return null;\n args.push(first);\n while (at('comma')) {\n i++;\n const next = parseOr();\n if (!next) return null;\n args.push(next);\n }\n }\n if (!eat('rparen')) return null;\n return { kind: 'call', name, args };\n }\n return { kind: 'ident', name };\n }\n if (at('lparen')) {\n i++;\n const inner = parseOr();\n if (!inner || !eat('rparen')) return null;\n return inner;\n }\n err(`Unexpected token ${t.type}`);\n return null;\n };\n\n const parseStmt = (): PineStmt | null => {\n if (at('if')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const then = parseBlock();\n let elseBody: PineStmt[] | undefined;\n if (at('else')) {\n i++;\n elseBody = parseBlock();\n }\n return { kind: 'if', cond, then, else: elseBody };\n }\n if (at('while')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const body = parseBlock();\n return { kind: 'while', cond, body };\n }\n if (at('for')) {\n i++;\n if (!at('ident')) {\n err('Expected loop variable after for');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const from = parseOr();\n if (!from || !at('to')) {\n err('Expected \"to\" in for loop');\n return null;\n }\n i++;\n const to = parseOr();\n if (!to) return null;\n const body = parseBlock();\n return { kind: 'for', name, from, to, body };\n }\n if (at('var')) {\n i++;\n if (!at('ident')) {\n err('Expected identifier after var');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const init = parseOr();\n return init ? { kind: 'var', name, init } : null;\n }\n if (at('plot')) {\n i++;\n if (!eat('lparen')) return null;\n const expr = parseOr();\n if (!expr || !eat('rparen')) return null;\n return { kind: 'plot', expr };\n }\n if (at('ident')) {\n const name = peek().value;\n i++;\n if (at('assign') || at('eq')) {\n i++;\n const value = parseOr();\n return value ? { kind: 'assign', name, value } : null;\n }\n i--;\n const expr = parseOr();\n return expr ? { kind: 'expr', expr } : null;\n }\n if (at('lbrace')) {\n return { kind: 'block', body: parseBlock() };\n }\n err(`Unexpected statement ${peek().type}`);\n return null;\n };\n\n const body: PineStmt[] = [];\n while (!at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n\n if (!at('eof')) err('Unexpected tokens after program end');\n return { program: { kind: 'program', body }, errors };\n}","import type { Bar } from '@coderyo/data';\nimport type { PineIrProgram } from './ir.js';\nimport { runPineIr, type PineRunResult } from './vm.js';\nimport type { PineWorkerRequest, PineWorkerResponse } from './pine.worker.js';\n\nlet worker: Worker | null = null;\nlet seq = 0;\nconst pending = new Map<number, { resolve: (r: PineRunResult) => void; reject: (e: Error) => void }>();\n\nfunction ensureWorker(): Worker | null {\n if (typeof Worker === 'undefined') return null;\n if (worker) return worker;\n\n try {\n worker = new Worker(new URL('./pine.worker.js', import.meta.url), { type: 'module' });\n worker.onmessage = (ev: MessageEvent<PineWorkerResponse>) => {\n const msg = ev.data;\n const p = pending.get(msg.id);\n if (!p) return;\n pending.delete(msg.id);\n if (msg.ok && msg.result) p.resolve(msg.result);\n else p.reject(new Error(msg.error ?? 'Pine worker failed'));\n };\n worker.onerror = () => {\n for (const [, p] of pending) p.reject(new Error('Pine worker error'));\n pending.clear();\n worker?.terminate();\n worker = null;\n };\n return worker;\n } catch {\n return null;\n }\n}\n\nexport interface RunPineLiteAsyncOptions {\n useWorker?: boolean;\n}\n\nexport function runPineLiteAsync(\n ir: PineIrProgram,\n bars: Bar[],\n opts?: RunPineLiteAsyncOptions,\n): Promise<PineRunResult> {\n if (opts?.useWorker === false) {\n return Promise.resolve(runPineIr(ir, bars));\n }\n\n const w = ensureWorker();\n if (!w) return Promise.resolve(runPineIr(ir, bars));\n\n const id = ++seq;\n const req: PineWorkerRequest = { id, ir, bars };\n return new Promise((resolve, reject) => {\n pending.set(id, { resolve, reject });\n w.postMessage(req);\n });\n}\n\nexport function terminatePineWorker(): void {\n worker?.terminate();\n worker = null;\n pending.clear();\n}","import { compileAst } from './compile.js';\nimport { diagnosticFromMessage, type PineDiagnostic } from './diagnostics.js';\nimport { tokenize } from './lexer.js';\nimport { parseProgram } from './parser.js';\nimport type { PineIrProgram } from './ir.js';\nimport { runPineIr, type PinePlotSeries, type PineRunResult } from './vm.js';\n\nexport type { PinePlotSeries, PineRunResult, PineDiagnostic };\nexport type { PineIrProgram } from './ir.js';\nexport type { PineProgram } from './ast.js';\nexport { diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol } from './diagnostics.js';\n\nexport interface PineCompileResult {\n ok: boolean;\n errors: string[];\n diagnostics: PineDiagnostic[];\n ir?: PineIrProgram;\n}\n\nconst MAX_SOURCE_LEN = 32 * 1024;\n\nexport function compilePineLite(source: string): PineCompileResult {\n const diagnostics: PineDiagnostic[] = [];\n const pushDiag = (line: number, col: number, message: string) => {\n diagnostics.push({ line, col, message, severity: 'error' });\n };\n\n if (source.length > MAX_SOURCE_LEN) {\n const msg = `Source exceeds ${MAX_SOURCE_LEN} bytes`;\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n const { tokens, errors: lexErr } = tokenize(source);\n for (const m of lexErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (lexErr.length) {\n return { ok: false, errors: lexErr, diagnostics };\n }\n\n const { program, errors: parseErr } = parseProgram(tokens);\n for (const e of parseErr) pushDiag(e.line, e.col, e.message);\n if (parseErr.length || !program) {\n return { ok: false, errors: parseErr.map((e) => e.message), diagnostics };\n }\n\n const { ir, errors: compileErr } = compileAst(program);\n for (const m of compileErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (compileErr.length || !ir) {\n return { ok: false, errors: compileErr, diagnostics };\n }\n if (ir.plots.length > 16) {\n const msg = 'Too many plot() calls (max 16)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n if (ir.vars.length > 256) {\n const msg = 'Too many variables (max 256)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n return { ok: true, errors: [], diagnostics, ir };\n}\n\nexport function runPineLite(ir: PineIrProgram, bars: import('@coderyo/data').Bar[]): PineRunResult {\n return runPineIr(ir, bars);\n}\n\nexport { runPineLiteAsync, terminatePineWorker, type RunPineLiteAsyncOptions } from './worker-client.js';\n\nexport const PINE_SAMPLE_SCRIPT = `// Pine-lite — if / while / for、比較、and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n`;\n\nexport const PINE_EDITOR_DEFAULT = PINE_SAMPLE_SCRIPT;"],"mappings":"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","names":["body","stmt"]}
@@ -0,0 +1,16 @@
1
+ import { Bar } from '@coderyo/data';
2
+ import { P as PineIrProgram, a as PineRunResult } from './vm-DSG6hmZe.js';
3
+
4
+ interface PineWorkerRequest {
5
+ id: number;
6
+ ir: PineIrProgram;
7
+ bars: Bar[];
8
+ }
9
+ interface PineWorkerResponse {
10
+ id: number;
11
+ ok: boolean;
12
+ result?: PineRunResult;
13
+ error?: string;
14
+ }
15
+
16
+ export type { PineWorkerRequest, PineWorkerResponse };
@@ -0,0 +1,21 @@
1
+ import {
2
+ runPineIr
3
+ } from "./chunk-JLVAE3JC.js";
4
+
5
+ // src/pine.worker.ts
6
+ self.onmessage = (ev) => {
7
+ const { id, ir, bars } = ev.data;
8
+ try {
9
+ const result = runPineIr(ir, bars);
10
+ const msg = { id, ok: true, result };
11
+ self.postMessage(msg);
12
+ } catch (e) {
13
+ const msg = {
14
+ id,
15
+ ok: false,
16
+ error: e instanceof Error ? e.message : String(e)
17
+ };
18
+ self.postMessage(msg);
19
+ }
20
+ };
21
+ //# sourceMappingURL=pine.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pine.worker.ts"],"sourcesContent":["import type { Bar } from '@coderyo/data';\nimport type { PineIrProgram } from './ir.js';\nimport { runPineIr, type PineRunResult } from './vm.js';\n\nexport interface PineWorkerRequest {\n id: number;\n ir: PineIrProgram;\n bars: Bar[];\n}\n\nexport interface PineWorkerResponse {\n id: number;\n ok: boolean;\n result?: PineRunResult;\n error?: string;\n}\n\nself.onmessage = (ev: MessageEvent<PineWorkerRequest>) => {\n const { id, ir, bars } = ev.data;\n try {\n const result = runPineIr(ir, bars);\n const msg: PineWorkerResponse = { id, ok: true, result };\n self.postMessage(msg);\n } catch (e) {\n const msg: PineWorkerResponse = {\n id,\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n };\n self.postMessage(msg);\n }\n};"],"mappings":";;;;;AAiBA,KAAK,YAAY,CAAC,OAAwC;AACxD,QAAM,EAAE,IAAI,IAAI,KAAK,IAAI,GAAG;AAC5B,MAAI;AACF,UAAM,SAAS,UAAU,IAAI,IAAI;AACjC,UAAM,MAA0B,EAAE,IAAI,IAAI,MAAM,OAAO;AACvD,SAAK,YAAY,GAAG;AAAA,EACtB,SAAS,GAAG;AACV,UAAM,MAA0B;AAAA,MAC9B;AAAA,MACA,IAAI;AAAA,MACJ,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,IAClD;AACA,SAAK,YAAY,GAAG;AAAA,EACtB;AACF;","names":[]}
@@ -0,0 +1,64 @@
1
+ type IrOp = {
2
+ op: 'push';
3
+ value: number;
4
+ } | {
5
+ op: 'load_series';
6
+ name: string;
7
+ } | {
8
+ op: 'load_var';
9
+ name: string;
10
+ } | {
11
+ op: 'store_var';
12
+ name: string;
13
+ } | {
14
+ op: 'call_ind';
15
+ fn: 'sma' | 'ema' | 'rsi' | 'highest' | 'lowest' | 'crossover' | 'crossunder';
16
+ series: string;
17
+ series2?: string;
18
+ } | {
19
+ op: 'add';
20
+ } | {
21
+ op: 'sub';
22
+ } | {
23
+ op: 'mul';
24
+ } | {
25
+ op: 'div';
26
+ } | {
27
+ op: 'neg';
28
+ } | {
29
+ op: 'not';
30
+ } | {
31
+ op: 'cmp';
32
+ mode: 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge';
33
+ } | {
34
+ op: 'and';
35
+ } | {
36
+ op: 'or';
37
+ } | {
38
+ op: 'pop';
39
+ } | {
40
+ op: 'jump';
41
+ target: number;
42
+ } | {
43
+ op: 'jump_if_false';
44
+ target: number;
45
+ } | {
46
+ op: 'plot';
47
+ title: string;
48
+ };
49
+ interface PineIrProgram {
50
+ version: 2;
51
+ ops: IrOp[];
52
+ vars: string[];
53
+ plots: string[];
54
+ }
55
+
56
+ interface PinePlotSeries {
57
+ title: string;
58
+ values: (number | null)[];
59
+ }
60
+ interface PineRunResult {
61
+ plots: PinePlotSeries[];
62
+ }
63
+
64
+ export type { PineIrProgram as P, PineRunResult as a, PinePlotSeries as b };
package/package.json CHANGED
@@ -1,24 +1,27 @@
1
1
  {
2
2
  "name": "@coderyo/pine-lite",
3
- "version": "1.0.0-rc.4",
3
+ "version": "1.0.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
8
  "types": "./dist/index.d.ts",
9
9
  "import": "./dist/index.js"
10
+ },
11
+ "./pine.worker": {
12
+ "import": "./dist/pine.worker.js"
10
13
  }
11
14
  },
12
15
  "dependencies": {
13
- "@coderyo/data": "1.0.0-rc.4",
14
- "@coderyo/indicators": "1.0.0-rc.4"
16
+ "@coderyo/data": "1.0.1",
17
+ "@coderyo/indicators": "1.0.1"
15
18
  },
16
19
  "devDependencies": {
17
20
  "tsup": "^8.5.0",
18
21
  "typescript": "^5.8.3",
19
22
  "vitest": "^3.2.4",
20
- "@coderyo/tsconfig": "0.0.0",
21
- "@coderyo/eslint-config": "0.0.0"
23
+ "@coderyo/eslint-config": "0.0.0",
24
+ "@coderyo/tsconfig": "0.0.0"
22
25
  },
23
26
  "files": [
24
27
  "dist"