binja 0.4.2 → 0.4.4
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 +21 -58
- package/dist/cli.js +44 -354
- package/dist/filters/index.d.ts.map +1 -1
- package/dist/index.js +105 -390
- package/dist/lexer/hybrid.d.ts +1 -1
- package/dist/lexer/hybrid.d.ts.map +1 -1
- package/dist/lexer/index.d.ts.map +1 -1
- package/dist/native/index.d.ts +10 -1
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +76 -1
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/native/darwin-arm64/libbinja.dylib +0 -0
- package/native/darwin-x64/libbinja.dylib +0 -0
- package/native/linux-arm64/libbinja.so +0 -0
- package/native/linux-x64/libbinja.so +0 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,287 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
-
var __toCommonJS = (from) => {
|
|
8
|
-
var entry = __moduleCache.get(from), desc;
|
|
9
|
-
if (entry)
|
|
10
|
-
return entry;
|
|
11
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
-
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
-
get: () => from[key],
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
}));
|
|
17
|
-
__moduleCache.set(from, entry);
|
|
18
|
-
return entry;
|
|
19
|
-
};
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, {
|
|
23
|
-
get: all[name],
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
set: (newValue) => all[name] = () => newValue
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
2
|
var __require = import.meta.require;
|
|
31
3
|
|
|
32
|
-
// src/native/index.ts
|
|
33
|
-
var exports_native = {};
|
|
34
|
-
__export(exports_native, {
|
|
35
|
-
tokenizeCount: () => tokenizeCount,
|
|
36
|
-
tokenize: () => tokenize,
|
|
37
|
-
nativeVersion: () => nativeVersion,
|
|
38
|
-
isNativeAvailable: () => isNativeAvailable,
|
|
39
|
-
TokenType: () => TokenType2,
|
|
40
|
-
NativeLexer: () => NativeLexer
|
|
41
|
-
});
|
|
42
|
-
import { dlopen, FFIType, ptr, CString } from "bun:ffi";
|
|
43
|
-
import { join, basename } from "path";
|
|
44
|
-
import { existsSync } from "fs";
|
|
45
|
-
function getLibraryPath() {
|
|
46
|
-
const platform = process.platform;
|
|
47
|
-
const arch = process.arch;
|
|
48
|
-
const libExt = platform === "darwin" ? "dylib" : platform === "win32" ? "dll" : "so";
|
|
49
|
-
const libName = `libbinja.${libExt}`;
|
|
50
|
-
const dirName = basename(import.meta.dir);
|
|
51
|
-
const projectRoot = dirName === "native" ? join(import.meta.dir, "..", "..") : join(import.meta.dir, "..");
|
|
52
|
-
const searchPaths = [
|
|
53
|
-
join(projectRoot, "native", `${platform}-${arch}`, libName),
|
|
54
|
-
join(projectRoot, "native", libName),
|
|
55
|
-
join(projectRoot, "zig-native", "zig-out", "lib", libName),
|
|
56
|
-
join(projectRoot, "zig-native", libName),
|
|
57
|
-
join(import.meta.dir, libName)
|
|
58
|
-
];
|
|
59
|
-
for (const p of searchPaths) {
|
|
60
|
-
if (existsSync(p)) {
|
|
61
|
-
return p;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
function loadLibrary() {
|
|
67
|
-
if (_loadAttempted) {
|
|
68
|
-
return _lib;
|
|
69
|
-
}
|
|
70
|
-
_loadAttempted = true;
|
|
71
|
-
const libPath = getLibraryPath();
|
|
72
|
-
if (!libPath) {
|
|
73
|
-
console.warn("[binja] Native library not found, using pure JS fallback");
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
try {
|
|
77
|
-
_lib = dlopen(libPath, symbols);
|
|
78
|
-
_nativeAvailable = true;
|
|
79
|
-
return _lib;
|
|
80
|
-
} catch (e) {
|
|
81
|
-
console.warn(`[binja] Failed to load native library: ${e}`);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function isNativeAvailable() {
|
|
86
|
-
loadLibrary();
|
|
87
|
-
return _nativeAvailable;
|
|
88
|
-
}
|
|
89
|
-
function nativeVersion() {
|
|
90
|
-
const lib = loadLibrary();
|
|
91
|
-
if (!lib)
|
|
92
|
-
return null;
|
|
93
|
-
const versionPtr = lib.symbols.binja_version();
|
|
94
|
-
if (!versionPtr)
|
|
95
|
-
return null;
|
|
96
|
-
return new CString(versionPtr).toString();
|
|
97
|
-
}
|
|
98
|
-
function tokenizeCount(source) {
|
|
99
|
-
if (source.length === 0) {
|
|
100
|
-
return 1;
|
|
101
|
-
}
|
|
102
|
-
const lib = loadLibrary();
|
|
103
|
-
if (!lib) {
|
|
104
|
-
throw new Error("Native library not available");
|
|
105
|
-
}
|
|
106
|
-
const bytes = new TextEncoder().encode(source);
|
|
107
|
-
return Number(lib.symbols.binja_tokenize_count(ptr(bytes), bytes.length));
|
|
108
|
-
}
|
|
109
|
-
function tokenize(source) {
|
|
110
|
-
const lexer = new NativeLexer(source);
|
|
111
|
-
try {
|
|
112
|
-
return lexer.getAllTokens();
|
|
113
|
-
} finally {
|
|
114
|
-
lexer.free();
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
var TokenType2, symbols, _lib = null, _loadAttempted = false, _nativeAvailable = false, NativeLexer;
|
|
118
|
-
var init_native = __esm(() => {
|
|
119
|
-
TokenType2 = {
|
|
120
|
-
TEXT: 0,
|
|
121
|
-
VAR_START: 1,
|
|
122
|
-
VAR_END: 2,
|
|
123
|
-
BLOCK_START: 3,
|
|
124
|
-
BLOCK_END: 4,
|
|
125
|
-
COMMENT_START: 5,
|
|
126
|
-
COMMENT_END: 6,
|
|
127
|
-
IDENTIFIER: 7,
|
|
128
|
-
STRING: 8,
|
|
129
|
-
NUMBER: 9,
|
|
130
|
-
OPERATOR: 10,
|
|
131
|
-
DOT: 11,
|
|
132
|
-
COMMA: 12,
|
|
133
|
-
PIPE: 13,
|
|
134
|
-
COLON: 14,
|
|
135
|
-
LPAREN: 15,
|
|
136
|
-
RPAREN: 16,
|
|
137
|
-
LBRACKET: 17,
|
|
138
|
-
RBRACKET: 18,
|
|
139
|
-
LBRACE: 19,
|
|
140
|
-
RBRACE: 20,
|
|
141
|
-
ASSIGN: 21,
|
|
142
|
-
EOF: 22
|
|
143
|
-
};
|
|
144
|
-
symbols = {
|
|
145
|
-
binja_lexer_new: {
|
|
146
|
-
args: [FFIType.ptr, FFIType.u64],
|
|
147
|
-
returns: FFIType.ptr
|
|
148
|
-
},
|
|
149
|
-
binja_lexer_free: {
|
|
150
|
-
args: [FFIType.ptr],
|
|
151
|
-
returns: FFIType.void
|
|
152
|
-
},
|
|
153
|
-
binja_lexer_token_count: {
|
|
154
|
-
args: [FFIType.ptr],
|
|
155
|
-
returns: FFIType.u64
|
|
156
|
-
},
|
|
157
|
-
binja_lexer_token_type: {
|
|
158
|
-
args: [FFIType.ptr, FFIType.u64],
|
|
159
|
-
returns: FFIType.u8
|
|
160
|
-
},
|
|
161
|
-
binja_lexer_token_start: {
|
|
162
|
-
args: [FFIType.ptr, FFIType.u64],
|
|
163
|
-
returns: FFIType.u32
|
|
164
|
-
},
|
|
165
|
-
binja_lexer_token_end: {
|
|
166
|
-
args: [FFIType.ptr, FFIType.u64],
|
|
167
|
-
returns: FFIType.u32
|
|
168
|
-
},
|
|
169
|
-
binja_lexer_has_error: {
|
|
170
|
-
args: [FFIType.ptr],
|
|
171
|
-
returns: FFIType.bool
|
|
172
|
-
},
|
|
173
|
-
binja_lexer_error_code: {
|
|
174
|
-
args: [FFIType.ptr],
|
|
175
|
-
returns: FFIType.u8
|
|
176
|
-
},
|
|
177
|
-
binja_lexer_error_line: {
|
|
178
|
-
args: [FFIType.ptr],
|
|
179
|
-
returns: FFIType.u32
|
|
180
|
-
},
|
|
181
|
-
binja_tokenize_count: {
|
|
182
|
-
args: [FFIType.ptr, FFIType.u64],
|
|
183
|
-
returns: FFIType.u64
|
|
184
|
-
},
|
|
185
|
-
binja_version: {
|
|
186
|
-
args: [],
|
|
187
|
-
returns: FFIType.ptr
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
NativeLexer = class NativeLexer {
|
|
191
|
-
lexerPtr = 0;
|
|
192
|
-
source;
|
|
193
|
-
sourceBuffer;
|
|
194
|
-
lib;
|
|
195
|
-
_tokenCount = 0;
|
|
196
|
-
_isEmpty = false;
|
|
197
|
-
constructor(source) {
|
|
198
|
-
const lib = loadLibrary();
|
|
199
|
-
if (!lib) {
|
|
200
|
-
throw new Error("Native library not available. Use isNativeAvailable() to check first.");
|
|
201
|
-
}
|
|
202
|
-
this.lib = lib;
|
|
203
|
-
this.source = source;
|
|
204
|
-
if (source.length === 0) {
|
|
205
|
-
this._isEmpty = true;
|
|
206
|
-
this._tokenCount = 1;
|
|
207
|
-
this.sourceBuffer = new Uint8Array(0);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
this.sourceBuffer = new TextEncoder().encode(source);
|
|
211
|
-
const result = this.lib.symbols.binja_lexer_new(ptr(this.sourceBuffer), this.sourceBuffer.length);
|
|
212
|
-
if (!result) {
|
|
213
|
-
throw new Error("Failed to create native lexer");
|
|
214
|
-
}
|
|
215
|
-
this.lexerPtr = result;
|
|
216
|
-
this._tokenCount = Number(this.lib.symbols.binja_lexer_token_count(this.lexerPtr));
|
|
217
|
-
}
|
|
218
|
-
get tokenCount() {
|
|
219
|
-
return this._tokenCount;
|
|
220
|
-
}
|
|
221
|
-
getTokenType(index) {
|
|
222
|
-
if (this._isEmpty)
|
|
223
|
-
return TokenType2.EOF;
|
|
224
|
-
return Number(this.lib.symbols.binja_lexer_token_type(this.lexerPtr, index));
|
|
225
|
-
}
|
|
226
|
-
getTokenStart(index) {
|
|
227
|
-
if (this._isEmpty)
|
|
228
|
-
return 0;
|
|
229
|
-
return Number(this.lib.symbols.binja_lexer_token_start(this.lexerPtr, index));
|
|
230
|
-
}
|
|
231
|
-
getTokenEnd(index) {
|
|
232
|
-
if (this._isEmpty)
|
|
233
|
-
return 0;
|
|
234
|
-
return Number(this.lib.symbols.binja_lexer_token_end(this.lexerPtr, index));
|
|
235
|
-
}
|
|
236
|
-
hasError() {
|
|
237
|
-
if (this._isEmpty)
|
|
238
|
-
return false;
|
|
239
|
-
return Boolean(this.lib.symbols.binja_lexer_has_error(this.lexerPtr));
|
|
240
|
-
}
|
|
241
|
-
getErrorCode() {
|
|
242
|
-
if (this._isEmpty)
|
|
243
|
-
return 0;
|
|
244
|
-
return Number(this.lib.symbols.binja_lexer_error_code(this.lexerPtr));
|
|
245
|
-
}
|
|
246
|
-
getErrorLine() {
|
|
247
|
-
if (this._isEmpty)
|
|
248
|
-
return 1;
|
|
249
|
-
return Number(this.lib.symbols.binja_lexer_error_line(this.lexerPtr));
|
|
250
|
-
}
|
|
251
|
-
getTokenValue(index) {
|
|
252
|
-
if (this._isEmpty)
|
|
253
|
-
return "";
|
|
254
|
-
const start = this.getTokenStart(index);
|
|
255
|
-
const end = this.getTokenEnd(index);
|
|
256
|
-
return new TextDecoder().decode(this.sourceBuffer.slice(start, end));
|
|
257
|
-
}
|
|
258
|
-
getToken(index) {
|
|
259
|
-
return {
|
|
260
|
-
type: this.getTokenType(index),
|
|
261
|
-
start: this.getTokenStart(index),
|
|
262
|
-
end: this.getTokenEnd(index),
|
|
263
|
-
value: this.getTokenValue(index)
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
getAllTokens() {
|
|
267
|
-
const tokens = [];
|
|
268
|
-
for (let i = 0;i < this._tokenCount; i++) {
|
|
269
|
-
tokens.push(this.getToken(i));
|
|
270
|
-
}
|
|
271
|
-
return tokens;
|
|
272
|
-
}
|
|
273
|
-
free() {
|
|
274
|
-
if (this.lexerPtr) {
|
|
275
|
-
this.lib.symbols.binja_lexer_free(this.lexerPtr);
|
|
276
|
-
this.lexerPtr = null;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
[Symbol.dispose]() {
|
|
280
|
-
this.free();
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
});
|
|
284
|
-
|
|
285
4
|
// src/lexer/tokens.ts
|
|
286
5
|
var TokenType;
|
|
287
6
|
((TokenType2) => {
|
|
@@ -338,21 +57,8 @@ var KEYWORDS = {
|
|
|
338
57
|
};
|
|
339
58
|
|
|
340
59
|
// src/lexer/hybrid.ts
|
|
341
|
-
var
|
|
342
|
-
var _nativeAvailable2 = false;
|
|
343
|
-
var NativeLexerClass = null;
|
|
60
|
+
var _tokenizeBatchFn = null;
|
|
344
61
|
function checkNative() {
|
|
345
|
-
if (_nativeChecked)
|
|
346
|
-
return _nativeAvailable2;
|
|
347
|
-
_nativeChecked = true;
|
|
348
|
-
try {
|
|
349
|
-
const native = (init_native(), __toCommonJS(exports_native));
|
|
350
|
-
if (typeof native.isNativeAvailable === "function" && native.isNativeAvailable()) {
|
|
351
|
-
_nativeAvailable2 = true;
|
|
352
|
-
NativeLexerClass = native.NativeLexer;
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
} catch {}
|
|
356
62
|
return false;
|
|
357
63
|
}
|
|
358
64
|
var NATIVE_TO_TS = {
|
|
@@ -399,71 +105,52 @@ var KEYWORD_TO_TYPE = {
|
|
|
399
105
|
or: "OR" /* OR */,
|
|
400
106
|
not: "NOT" /* NOT */
|
|
401
107
|
};
|
|
402
|
-
var ERROR_MESSAGES = {
|
|
403
|
-
1: "Unterminated string",
|
|
404
|
-
2: "Unclosed template tag",
|
|
405
|
-
3: "Invalid operator",
|
|
406
|
-
4: "Unexpected character"
|
|
407
|
-
};
|
|
408
108
|
function isNativeAccelerated() {
|
|
409
109
|
return checkNative();
|
|
410
110
|
}
|
|
411
111
|
function tokenizeNative(source) {
|
|
412
|
-
if (!checkNative() || !
|
|
112
|
+
if (!checkNative() || !_tokenizeBatchFn)
|
|
413
113
|
return null;
|
|
414
114
|
if (source.length === 0) {
|
|
415
115
|
return [{ type: "EOF" /* EOF */, value: "", line: 1, column: 1 }];
|
|
416
116
|
}
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const errorLine = lexer.getErrorLine();
|
|
422
|
-
const message = ERROR_MESSAGES[errorCode] ?? "Unknown error";
|
|
423
|
-
throw new Error(`${message} at line ${errorLine}`);
|
|
424
|
-
}
|
|
425
|
-
const tokens = [];
|
|
426
|
-
const count = lexer.tokenCount;
|
|
427
|
-
const lineStarts = [0];
|
|
428
|
-
for (let i = 0;i < source.length; i++) {
|
|
429
|
-
if (source[i] === `
|
|
117
|
+
const rawTokens = _tokenizeBatchFn(source);
|
|
118
|
+
const lineStarts = [0];
|
|
119
|
+
for (let i = 0;i < source.length; i++) {
|
|
120
|
+
if (source[i] === `
|
|
430
121
|
`)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
finalValue = finalValue.slice(1, -1);
|
|
459
|
-
}
|
|
122
|
+
lineStarts.push(i + 1);
|
|
123
|
+
}
|
|
124
|
+
const tokens = new Array(rawTokens.length);
|
|
125
|
+
for (let i = 0;i < rawTokens.length; i++) {
|
|
126
|
+
const [nativeType, start, end] = rawTokens[i];
|
|
127
|
+
let value = source.slice(start, end);
|
|
128
|
+
let lo = 0, hi = lineStarts.length - 1;
|
|
129
|
+
while (lo < hi) {
|
|
130
|
+
const mid = lo + hi + 1 >> 1;
|
|
131
|
+
if (lineStarts[mid] <= start)
|
|
132
|
+
lo = mid;
|
|
133
|
+
else
|
|
134
|
+
hi = mid - 1;
|
|
135
|
+
}
|
|
136
|
+
const line = lo + 1;
|
|
137
|
+
const column = start - lineStarts[lo] + 1;
|
|
138
|
+
let type = NATIVE_TO_TS[nativeType] ?? "NAME" /* NAME */;
|
|
139
|
+
if (nativeType === 10 && OPERATOR_TO_TYPE[value]) {
|
|
140
|
+
type = OPERATOR_TO_TYPE[value];
|
|
141
|
+
} else if (type === "NAME" /* NAME */ && KEYWORD_TO_TYPE[value]) {
|
|
142
|
+
type = KEYWORD_TO_TYPE[value];
|
|
143
|
+
}
|
|
144
|
+
if (type === "STRING" /* STRING */ && value.length >= 2) {
|
|
145
|
+
const first = value[0];
|
|
146
|
+
const last = value[value.length - 1];
|
|
147
|
+
if (first === '"' && last === '"' || first === "'" && last === "'") {
|
|
148
|
+
value = value.slice(1, -1);
|
|
460
149
|
}
|
|
461
|
-
tokens.push({ type, value: finalValue, line, column });
|
|
462
150
|
}
|
|
463
|
-
|
|
464
|
-
} finally {
|
|
465
|
-
lexer.free();
|
|
151
|
+
tokens[i] = { type, value, line, column };
|
|
466
152
|
}
|
|
153
|
+
return tokens;
|
|
467
154
|
}
|
|
468
155
|
|
|
469
156
|
// src/lexer/index.ts
|
|
@@ -863,13 +550,16 @@ class Lexer {
|
|
|
863
550
|
` || c === "\r";
|
|
864
551
|
}
|
|
865
552
|
isDigit(c) {
|
|
866
|
-
|
|
553
|
+
const code = c.charCodeAt(0);
|
|
554
|
+
return code >= 48 && code <= 57;
|
|
867
555
|
}
|
|
868
556
|
isAlpha(c) {
|
|
869
|
-
|
|
557
|
+
const code = c.charCodeAt(0);
|
|
558
|
+
return code >= 97 && code <= 122 || code >= 65 && code <= 90;
|
|
870
559
|
}
|
|
871
560
|
isAlphaNumeric(c) {
|
|
872
|
-
|
|
561
|
+
const code = c.charCodeAt(0);
|
|
562
|
+
return code >= 48 && code <= 57 || code >= 97 && code <= 122 || code >= 65 && code <= 90;
|
|
873
563
|
}
|
|
874
564
|
addToken(type, value) {
|
|
875
565
|
this.state.tokens.push({
|
|
@@ -1777,7 +1467,7 @@ class Context {
|
|
|
1777
1467
|
_currentScope;
|
|
1778
1468
|
constructor(data = {}, parent = null) {
|
|
1779
1469
|
this.parent = parent;
|
|
1780
|
-
this._currentScope =
|
|
1470
|
+
this._currentScope = { ...data };
|
|
1781
1471
|
this.scopes.push(this._currentScope);
|
|
1782
1472
|
}
|
|
1783
1473
|
get(name) {
|
|
@@ -1803,7 +1493,7 @@ class Context {
|
|
|
1803
1493
|
return this.parent ? this.parent.has(name) : false;
|
|
1804
1494
|
}
|
|
1805
1495
|
push(data = {}) {
|
|
1806
|
-
this._currentScope =
|
|
1496
|
+
this._currentScope = { ...data };
|
|
1807
1497
|
this.scopes.push(this._currentScope);
|
|
1808
1498
|
}
|
|
1809
1499
|
pop() {
|
|
@@ -2007,7 +1697,7 @@ var last = (value) => {
|
|
|
2007
1697
|
return value[value.length - 1];
|
|
2008
1698
|
return value;
|
|
2009
1699
|
};
|
|
2010
|
-
var
|
|
1700
|
+
var join = (value, separator = "") => {
|
|
2011
1701
|
if (Array.isArray(value))
|
|
2012
1702
|
return value.join(separator);
|
|
2013
1703
|
return String(value);
|
|
@@ -2285,15 +1975,26 @@ var indent = (value, width = 4, first2 = false, blank = false) => {
|
|
|
2285
1975
|
};
|
|
2286
1976
|
var replace = (value, old, newStr, count) => {
|
|
2287
1977
|
const str = String(value);
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
let remaining = Number(count);
|
|
2293
|
-
while (remaining > 0 && result.includes(String(old))) {
|
|
2294
|
-
result = result.replace(String(old), String(newStr));
|
|
2295
|
-
remaining--;
|
|
1978
|
+
const oldStr = String(old);
|
|
1979
|
+
const newString = String(newStr);
|
|
1980
|
+
if (count === undefined || count < 0) {
|
|
1981
|
+
return str.replaceAll(oldStr, newString);
|
|
2296
1982
|
}
|
|
1983
|
+
const maxCount = Number(count);
|
|
1984
|
+
if (maxCount === 0)
|
|
1985
|
+
return str;
|
|
1986
|
+
let result = "";
|
|
1987
|
+
let pos = 0;
|
|
1988
|
+
let replaced = 0;
|
|
1989
|
+
while (pos < str.length && replaced < maxCount) {
|
|
1990
|
+
const idx = str.indexOf(oldStr, pos);
|
|
1991
|
+
if (idx === -1)
|
|
1992
|
+
break;
|
|
1993
|
+
result += str.slice(pos, idx) + newString;
|
|
1994
|
+
pos = idx + oldStr.length;
|
|
1995
|
+
replaced++;
|
|
1996
|
+
}
|
|
1997
|
+
result += str.slice(pos);
|
|
2297
1998
|
return result;
|
|
2298
1999
|
};
|
|
2299
2000
|
var format = (value, ...args) => {
|
|
@@ -2473,11 +2174,12 @@ var PHONE_MAP = {
|
|
|
2473
2174
|
};
|
|
2474
2175
|
var phone2numeric = (value) => {
|
|
2475
2176
|
const str = String(value).toLowerCase();
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2177
|
+
const len = str.length;
|
|
2178
|
+
const chars = new Array(len);
|
|
2179
|
+
for (let i = 0;i < len; i++) {
|
|
2180
|
+
chars[i] = PHONE_MAP[str[i]] ?? str[i];
|
|
2479
2181
|
}
|
|
2480
|
-
return
|
|
2182
|
+
return chars.join("");
|
|
2481
2183
|
};
|
|
2482
2184
|
var linenumbers = (value) => {
|
|
2483
2185
|
const lines = String(value).split(`
|
|
@@ -2559,7 +2261,7 @@ var builtinFilters = {
|
|
|
2559
2261
|
length_is,
|
|
2560
2262
|
first,
|
|
2561
2263
|
last,
|
|
2562
|
-
join
|
|
2264
|
+
join,
|
|
2563
2265
|
slice,
|
|
2564
2266
|
reverse,
|
|
2565
2267
|
sort,
|
|
@@ -2940,14 +2642,15 @@ class Runtime {
|
|
|
2940
2642
|
return this.renderNodesSync(node.else_, ctx);
|
|
2941
2643
|
}
|
|
2942
2644
|
const parts = new Array(len);
|
|
2943
|
-
const isUnpacking = Array.isArray(node.target);
|
|
2944
2645
|
ctx.push();
|
|
2945
2646
|
ctx.pushForLoop(items, 0);
|
|
2946
|
-
|
|
2947
|
-
const
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2647
|
+
if (Array.isArray(node.target)) {
|
|
2648
|
+
const targets = node.target;
|
|
2649
|
+
const targetsLen = targets.length;
|
|
2650
|
+
for (let i = 0;i < len; i++) {
|
|
2651
|
+
const item = items[i];
|
|
2652
|
+
if (i > 0)
|
|
2653
|
+
ctx.updateForLoop(i, items);
|
|
2951
2654
|
let values;
|
|
2952
2655
|
if (Array.isArray(item)) {
|
|
2953
2656
|
values = item;
|
|
@@ -2956,14 +2659,19 @@ class Runtime {
|
|
|
2956
2659
|
} else {
|
|
2957
2660
|
values = [item, item];
|
|
2958
2661
|
}
|
|
2959
|
-
|
|
2960
|
-
for (let j = 0;j < targets.length; j++) {
|
|
2662
|
+
for (let j = 0;j < targetsLen; j++) {
|
|
2961
2663
|
ctx.set(targets[j], values[j]);
|
|
2962
2664
|
}
|
|
2963
|
-
|
|
2964
|
-
|
|
2665
|
+
parts[i] = this.renderNodesSync(node.body, ctx);
|
|
2666
|
+
}
|
|
2667
|
+
} else {
|
|
2668
|
+
const target = node.target;
|
|
2669
|
+
for (let i = 0;i < len; i++) {
|
|
2670
|
+
if (i > 0)
|
|
2671
|
+
ctx.updateForLoop(i, items);
|
|
2672
|
+
ctx.set(target, items[i]);
|
|
2673
|
+
parts[i] = this.renderNodesSync(node.body, ctx);
|
|
2965
2674
|
}
|
|
2966
|
-
parts[i] = this.renderNodesSync(node.body, ctx);
|
|
2967
2675
|
}
|
|
2968
2676
|
ctx.popForLoop();
|
|
2969
2677
|
ctx.pop();
|
|
@@ -3179,17 +2887,20 @@ class Runtime {
|
|
|
3179
2887
|
const obj = this.eval(node.object, ctx);
|
|
3180
2888
|
if (obj == null)
|
|
3181
2889
|
return;
|
|
3182
|
-
const
|
|
3183
|
-
if (
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
2890
|
+
const attr2 = node.attribute;
|
|
2891
|
+
if (Array.isArray(obj)) {
|
|
2892
|
+
const numIndex = parseInt(attr2, 10);
|
|
2893
|
+
if (!isNaN(numIndex))
|
|
2894
|
+
return obj[numIndex];
|
|
2895
|
+
}
|
|
2896
|
+
const value = obj[attr2];
|
|
2897
|
+
if (value === undefined && !(attr2 in Object(obj))) {
|
|
2898
|
+
return;
|
|
3188
2899
|
}
|
|
3189
|
-
if (typeof
|
|
3190
|
-
return
|
|
2900
|
+
if (typeof value === "function") {
|
|
2901
|
+
return value.bind(obj);
|
|
3191
2902
|
}
|
|
3192
|
-
return;
|
|
2903
|
+
return value;
|
|
3193
2904
|
}
|
|
3194
2905
|
evalGetItem(node, ctx) {
|
|
3195
2906
|
const obj = this.eval(node.object, ctx);
|
|
@@ -3542,9 +3253,13 @@ class Runtime {
|
|
|
3542
3253
|
if (typeof value[Symbol.iterator] === "function") {
|
|
3543
3254
|
return Array.from(value);
|
|
3544
3255
|
}
|
|
3545
|
-
const
|
|
3546
|
-
|
|
3547
|
-
|
|
3256
|
+
const keys = Object.keys(value);
|
|
3257
|
+
const len = keys.length;
|
|
3258
|
+
const result = new Array(len);
|
|
3259
|
+
for (let i = 0;i < len; i++) {
|
|
3260
|
+
const key = keys[i];
|
|
3261
|
+
const val = value[key];
|
|
3262
|
+
result[i] = { key, value: val, 0: key, 1: val };
|
|
3548
3263
|
}
|
|
3549
3264
|
return result;
|
|
3550
3265
|
}
|
package/dist/lexer/hybrid.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Token } from './tokens';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare function isNativeAccelerated(): boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Tokenize using native FFI
|
|
10
|
+
* Tokenize using native FFI with batch API (single FFI call)
|
|
11
11
|
*/
|
|
12
12
|
export declare function tokenizeNative(source: string): Token[] | null;
|
|
13
13
|
//# sourceMappingURL=hybrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/lexer/hybrid.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,EAAa,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/lexer/hybrid.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,EAAa,MAAM,UAAU,CAAA;AAiE3C;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,CAqD7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lexer/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,EAAmC,MAAM,UAAU,CAAA;AAGjE,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,UAAU,CAAC,EAAE,MAAM,CAAA;KACf;IA8BR,QAAQ,IAAI,KAAK,EAAE;IAgBnB,OAAO,CAAC,SAAS;IAsCjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,YAAY;IA0EpB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;IAuDpB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lexer/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,EAAmC,MAAM,UAAU,CAAA;AAGjE,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,UAAU,CAAC,EAAE,MAAM,CAAA;KACf;IA8BR,QAAQ,IAAI,KAAK,EAAE;IAgBnB,OAAO,CAAC,SAAS;IAsCjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,YAAY;IA0EpB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;IAuDpB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,QAAQ;CAQjB;AAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/native/index.d.ts
CHANGED
|
@@ -66,7 +66,16 @@ export declare class NativeLexer {
|
|
|
66
66
|
*/
|
|
67
67
|
export declare function tokenizeCount(source: string): number;
|
|
68
68
|
/**
|
|
69
|
-
* Tokenize with native lexer, auto-cleanup
|
|
69
|
+
* Tokenize with native lexer, auto-cleanup (OLD - per-token FFI calls)
|
|
70
70
|
*/
|
|
71
71
|
export declare function tokenize(source: string): NativeToken[];
|
|
72
|
+
/**
|
|
73
|
+
* Batch tokenize - single FFI call for all tokens (FAST)
|
|
74
|
+
* Returns array of [type, start, end] tuples for maximum performance
|
|
75
|
+
*/
|
|
76
|
+
export declare function tokenizeBatch(source: string): Array<[number, number, number]>;
|
|
77
|
+
/**
|
|
78
|
+
* Batch tokenize with full token objects (includes value extraction)
|
|
79
|
+
*/
|
|
80
|
+
export declare function tokenizeBatchFull(source: string): NativeToken[];
|
|
72
81
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;CAwBZ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;CAwBZ,CAAA;AA+IV;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAO7C;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAiB;gBAErB,MAAM,EAAE,MAAM;IAgC1B,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAKnC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAKpC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAKlC,QAAQ,IAAI,OAAO;IAKnB,YAAY,IAAI,MAAM;IAKtB,YAAY,IAAI,MAAM;IAKtB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAQpC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IASpC,YAAY,IAAI,WAAW,EAAE;IAQ7B,IAAI,IAAI,IAAI;IAOZ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGzB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAOtD;AAUD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CA2D7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAQ/D"}
|