@jondotsoy/don 0.0.2

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 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/document.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { LexerEncoder, Lexema, Token, TokenExpression } from "./lexer.js";
2
+ export { Directive, Document, DocumentEncoder } from "./document.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { LexerEncoder, Lexema, Token, TokenExpression } from "./lexer.js";
2
+ export { Directive, Document, DocumentEncoder } from "./document.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { ChunkList } from "./chunk";
2
+ export declare class Token {
3
+ readonly type: string;
4
+ readonly raw: string;
5
+ constructor(type: string, raw: string);
6
+ }
7
+ export declare class Lexema {
8
+ readonly length: number;
9
+ readonly tokens: Iterable<Token>;
10
+ constructor(length: number, tokens: Iterable<Token>);
11
+ }
12
+ declare class MatchTokenExpressionResult {
13
+ readonly matched: ChunkList;
14
+ readonly length: number;
15
+ constructor(matched: ChunkList, length: number);
16
+ }
17
+ export declare class TokenExpression {
18
+ readonly test: (chunks: ChunkList, fromIndex: number) => () => null | MatchTokenExpressionResult;
19
+ constructor(test: (chunks: ChunkList, fromIndex: number) => () => null | MatchTokenExpressionResult);
20
+ match(chunks: ChunkList, fromIndex: number): null | MatchTokenExpressionResult;
21
+ static stringLiteral: TokenExpression;
22
+ static keyword: TokenExpression;
23
+ static punctuator: TokenExpression;
24
+ static newline: TokenExpression;
25
+ static booleanLiteral: TokenExpression;
26
+ static nullLiteral: TokenExpression;
27
+ static numberLiteral: TokenExpression;
28
+ static singleComment: TokenExpression;
29
+ static multilineComment: TokenExpression;
30
+ static heredoc: TokenExpression;
31
+ static whitespace: TokenExpression;
32
+ }
33
+ export declare class LexerEncoder {
34
+ encode(inpt: string | Iterable<number> | ChunkList): Lexema;
35
+ private findMatchingExpression;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=lexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/lexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,SAAS,EAAE,MAAM,SAAS,CAAC;AAElD,qBAAa,KAAK;IAEd,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM;gBADX,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM;CAEvB;AAED,qBAAa,MAAM;IAEf,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC;gBADvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC;CAEnC;AAED,cAAM,0BAA0B;IAE5B,QAAQ,CAAC,OAAO,EAAE,SAAS;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADd,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,MAAM;CAE1B;AAED,qBAAa,eAAe;IAExB,QAAQ,CAAC,IAAI,EAAE,CACb,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,KACd,MAAM,IAAI,GAAG,0BAA0B;gBAHnC,IAAI,EAAE,CACb,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,KACd,MAAM,IAAI,GAAG,0BAA0B;IAG9C,KAAK,CACH,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,GAChB,IAAI,GAAG,0BAA0B;IAKpC,MAAM,CAAC,aAAa,kBAqElB;IAEF,MAAM,CAAC,OAAO,kBAmEZ;IAEF,MAAM,CAAC,UAAU,kBA4Bf;IAEF,MAAM,CAAC,OAAO,kBA0BZ;IAEF,MAAM,CAAC,cAAc,kBA0BnB;IAEF,MAAM,CAAC,WAAW,kBA0BhB;IAEF,MAAM,CAAC,aAAa,kBA8DlB;IAEF,MAAM,CAAC,aAAa,kBA+ElB;IAEF,MAAM,CAAC,gBAAgB,kBAqFrB;IAEF,MAAM,CAAC,OAAO,kBA4KZ;IAEF,MAAM,CAAC,UAAU,kBA2Bf;CACH;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM;IAwE3D,OAAO,CAAC,sBAAsB;CAiB/B"}
@@ -0,0 +1,600 @@
1
+ import { ChunkEncoder, ChunkList } from "./chunk";
2
+ export class Token {
3
+ type;
4
+ raw;
5
+ constructor(type, raw) {
6
+ this.type = type;
7
+ this.raw = raw;
8
+ }
9
+ }
10
+ export class Lexema {
11
+ length;
12
+ tokens;
13
+ constructor(length, tokens) {
14
+ this.length = length;
15
+ this.tokens = tokens;
16
+ }
17
+ }
18
+ class MatchTokenExpressionResult {
19
+ matched;
20
+ length;
21
+ constructor(matched, length) {
22
+ this.matched = matched;
23
+ this.length = length;
24
+ }
25
+ }
26
+ export class TokenExpression {
27
+ test;
28
+ constructor(test) {
29
+ this.test = test;
30
+ }
31
+ match(chunks, fromIndex) {
32
+ const result = this.test(chunks, fromIndex)();
33
+ return result;
34
+ }
35
+ static stringLiteral = new TokenExpression((chunks, fromIndex) => {
36
+ return () => {
37
+ const chunksArray = Array.from(chunks.chunks);
38
+ // Verificar que hay al menos un chunk en fromIndex
39
+ if (fromIndex >= chunksArray.length) {
40
+ return null;
41
+ }
42
+ const firstChunk = chunksArray[fromIndex];
43
+ if (!firstChunk) {
44
+ return null;
45
+ }
46
+ // Verificar que el primer chunk es una comilla de apertura (doble o simple)
47
+ const firstValue = Array.from(firstChunk.value);
48
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
49
+ if (firstStr !== '"' && firstStr !== "'") {
50
+ return null;
51
+ }
52
+ const quoteType = firstStr; // Guardar el tipo de comilla para buscar la misma al cerrar
53
+ // Buscar la comilla de cierre del mismo tipo
54
+ let endIndex = fromIndex + 1;
55
+ let escaped = false;
56
+ while (endIndex < chunksArray.length) {
57
+ const chunk = chunksArray[endIndex];
58
+ if (!chunk)
59
+ break;
60
+ const value = Array.from(chunk.value);
61
+ const str = new TextDecoder().decode(new Uint8Array(value));
62
+ if (escaped) {
63
+ // El carácter anterior era un backslash, este está escapado
64
+ escaped = false;
65
+ endIndex++;
66
+ continue;
67
+ }
68
+ if (str === "\\") {
69
+ // Backslash - el siguiente carácter estará escapado
70
+ escaped = true;
71
+ endIndex++;
72
+ continue;
73
+ }
74
+ if (str === quoteType) {
75
+ // Encontramos la comilla de cierre del mismo tipo (no escapada)
76
+ const matchedChunks = chunksArray.slice(fromIndex, endIndex + 1);
77
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
78
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
79
+ }
80
+ endIndex++;
81
+ }
82
+ // No se encontró comilla de cierre
83
+ return null;
84
+ };
85
+ });
86
+ static keyword = new TokenExpression((chunks, fromIndex) => {
87
+ return () => {
88
+ const chunksArray = Array.from(chunks.chunks);
89
+ // Verificar que hay al menos un chunk en fromIndex
90
+ if (fromIndex >= chunksArray.length) {
91
+ return null;
92
+ }
93
+ const firstChunk = chunksArray[fromIndex];
94
+ if (!firstChunk) {
95
+ return null;
96
+ }
97
+ // Verificar que el primer chunk contiene un keyword válido
98
+ const firstValue = Array.from(firstChunk.value);
99
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
100
+ // Un keyword debe empezar con letras, guión bajo, o ciertos símbolos (/, -)
101
+ const startsWithKeywordChar = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(firstStr);
102
+ const startsWithSymbol = /^[\/\-]$/.test(firstStr);
103
+ if (!startsWithKeywordChar && !startsWithSymbol) {
104
+ return null;
105
+ }
106
+ // Consumir chunks consecutivos (sin espacios) para formar un keyword compuesto
107
+ const matchedChunks = [firstChunk];
108
+ let currentIndex = fromIndex + 1;
109
+ while (currentIndex < chunksArray.length) {
110
+ const nextChunk = chunksArray[currentIndex];
111
+ if (!nextChunk)
112
+ break;
113
+ const nextValue = Array.from(nextChunk.value);
114
+ const nextStr = new TextDecoder().decode(new Uint8Array(nextValue));
115
+ // Si es un espacio o salto de línea, terminamos
116
+ if (nextStr.trim() === "" || nextStr === "\n") {
117
+ break;
118
+ }
119
+ // Si es un keyword válido o un símbolo (excepto delimitadores), lo agregamos
120
+ const isKeywordPart = /^[a-zA-Z0-9_]+$/.test(nextStr);
121
+ const isSymbol = nextStr.length === 1 && !/[\s\n{}[\],]/.test(nextStr);
122
+ if (isKeywordPart || isSymbol) {
123
+ matchedChunks.push(nextChunk);
124
+ currentIndex++;
125
+ }
126
+ else {
127
+ // Es un delimitador, terminamos
128
+ break;
129
+ }
130
+ }
131
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
132
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
133
+ };
134
+ });
135
+ static punctuator = new TokenExpression((chunks, fromIndex) => {
136
+ return () => {
137
+ const chunksArray = Array.from(chunks.chunks);
138
+ if (fromIndex >= chunksArray.length) {
139
+ return null;
140
+ }
141
+ const chunk = chunksArray[fromIndex];
142
+ if (!chunk) {
143
+ return null;
144
+ }
145
+ const value = Array.from(chunk.value);
146
+ const str = new TextDecoder().decode(new Uint8Array(value));
147
+ if (["[", "]", "{", "}", ",", "+", "-", "/", "*", "<", ">"].includes(str)) {
148
+ const matchedChunks = [chunk];
149
+ const matchedChunkList = new ChunkList(1, matchedChunks);
150
+ return new MatchTokenExpressionResult(matchedChunkList, 1);
151
+ }
152
+ return null;
153
+ };
154
+ });
155
+ static newline = new TokenExpression((chunks, fromIndex) => {
156
+ return () => {
157
+ const chunksArray = Array.from(chunks.chunks);
158
+ if (fromIndex >= chunksArray.length) {
159
+ return null;
160
+ }
161
+ const chunk = chunksArray[fromIndex];
162
+ if (!chunk) {
163
+ return null;
164
+ }
165
+ const value = Array.from(chunk.value);
166
+ const str = new TextDecoder().decode(new Uint8Array(value));
167
+ if (str === "\n") {
168
+ const matchedChunks = [chunk];
169
+ const matchedChunkList = new ChunkList(1, matchedChunks);
170
+ return new MatchTokenExpressionResult(matchedChunkList, 1);
171
+ }
172
+ return null;
173
+ };
174
+ });
175
+ static booleanLiteral = new TokenExpression((chunks, fromIndex) => {
176
+ return () => {
177
+ const chunksArray = Array.from(chunks.chunks);
178
+ if (fromIndex >= chunksArray.length) {
179
+ return null;
180
+ }
181
+ const chunk = chunksArray[fromIndex];
182
+ if (!chunk) {
183
+ return null;
184
+ }
185
+ const value = Array.from(chunk.value);
186
+ const str = new TextDecoder().decode(new Uint8Array(value));
187
+ if (str === "true" || str === "false") {
188
+ const matchedChunks = [chunk];
189
+ const matchedChunkList = new ChunkList(1, matchedChunks);
190
+ return new MatchTokenExpressionResult(matchedChunkList, 1);
191
+ }
192
+ return null;
193
+ };
194
+ });
195
+ static nullLiteral = new TokenExpression((chunks, fromIndex) => {
196
+ return () => {
197
+ const chunksArray = Array.from(chunks.chunks);
198
+ if (fromIndex >= chunksArray.length) {
199
+ return null;
200
+ }
201
+ const chunk = chunksArray[fromIndex];
202
+ if (!chunk) {
203
+ return null;
204
+ }
205
+ const value = Array.from(chunk.value);
206
+ const str = new TextDecoder().decode(new Uint8Array(value));
207
+ if (str === "null") {
208
+ const matchedChunks = [chunk];
209
+ const matchedChunkList = new ChunkList(1, matchedChunks);
210
+ return new MatchTokenExpressionResult(matchedChunkList, 1);
211
+ }
212
+ return null;
213
+ };
214
+ });
215
+ static numberLiteral = new TokenExpression((chunks, fromIndex) => {
216
+ return () => {
217
+ const chunksArray = Array.from(chunks.chunks);
218
+ if (fromIndex >= chunksArray.length) {
219
+ return null;
220
+ }
221
+ const firstChunk = chunksArray[fromIndex];
222
+ if (!firstChunk) {
223
+ return null;
224
+ }
225
+ const firstValue = Array.from(firstChunk.value);
226
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
227
+ // Debe empezar con un dígito
228
+ if (!/^[0-9][0-9_]*$/.test(firstStr)) {
229
+ return null;
230
+ }
231
+ let matchedChunks = [firstChunk];
232
+ let currentIndex = fromIndex + 1;
233
+ // Verificar si hay un punto decimal
234
+ if (currentIndex < chunksArray.length) {
235
+ const dotChunk = chunksArray[currentIndex];
236
+ if (dotChunk) {
237
+ const dotValue = Array.from(dotChunk.value);
238
+ const dotStr = new TextDecoder().decode(new Uint8Array(dotValue));
239
+ if (dotStr === ".") {
240
+ // Verificar que hay dígitos después del punto
241
+ if (currentIndex + 1 < chunksArray.length) {
242
+ const decimalChunk = chunksArray[currentIndex + 1];
243
+ if (decimalChunk) {
244
+ const decimalValue = Array.from(decimalChunk.value);
245
+ const decimalStr = new TextDecoder().decode(new Uint8Array(decimalValue));
246
+ if (/^[0-9_]+$/.test(decimalStr)) {
247
+ matchedChunks.push(dotChunk);
248
+ matchedChunks.push(decimalChunk);
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
256
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
257
+ };
258
+ });
259
+ static singleComment = new TokenExpression((chunks, fromIndex) => {
260
+ return () => {
261
+ const chunksArray = Array.from(chunks.chunks);
262
+ if (fromIndex >= chunksArray.length) {
263
+ return null;
264
+ }
265
+ const firstChunk = chunksArray[fromIndex];
266
+ if (!firstChunk) {
267
+ return null;
268
+ }
269
+ const firstValue = Array.from(firstChunk.value);
270
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
271
+ let matchedChunks = [];
272
+ let currentIndex = fromIndex;
273
+ // Verificar si empieza con # (comentario de una sola línea)
274
+ if (firstStr === "#") {
275
+ matchedChunks = [firstChunk];
276
+ currentIndex = fromIndex + 1;
277
+ }
278
+ // Verificar si empieza con // (comentario de una sola línea)
279
+ else if (firstStr === "/") {
280
+ // Verificar que el siguiente chunk también es /
281
+ if (fromIndex + 1 >= chunksArray.length) {
282
+ return null;
283
+ }
284
+ const secondChunk = chunksArray[fromIndex + 1];
285
+ if (!secondChunk) {
286
+ return null;
287
+ }
288
+ const secondValue = Array.from(secondChunk.value);
289
+ const secondStr = new TextDecoder().decode(new Uint8Array(secondValue));
290
+ if (secondStr !== "/") {
291
+ return null;
292
+ }
293
+ matchedChunks = [firstChunk, secondChunk];
294
+ currentIndex = fromIndex + 2;
295
+ }
296
+ else {
297
+ return null;
298
+ }
299
+ // Capturar todo hasta el final de la línea (sin incluir \n)
300
+ while (currentIndex < chunksArray.length) {
301
+ const chunk = chunksArray[currentIndex];
302
+ if (!chunk)
303
+ break;
304
+ const value = Array.from(chunk.value);
305
+ const str = new TextDecoder().decode(new Uint8Array(value));
306
+ // Si encontramos un salto de línea, terminamos (sin incluirlo)
307
+ if (str === "\n") {
308
+ break;
309
+ }
310
+ matchedChunks.push(chunk);
311
+ currentIndex++;
312
+ }
313
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
314
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
315
+ };
316
+ });
317
+ static multilineComment = new TokenExpression((chunks, fromIndex) => {
318
+ return () => {
319
+ const chunksArray = Array.from(chunks.chunks);
320
+ if (fromIndex >= chunksArray.length) {
321
+ return null;
322
+ }
323
+ const firstChunk = chunksArray[fromIndex];
324
+ if (!firstChunk) {
325
+ return null;
326
+ }
327
+ const firstValue = Array.from(firstChunk.value);
328
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
329
+ // Debe empezar con /*
330
+ if (firstStr !== "/") {
331
+ return null;
332
+ }
333
+ // Verificar que el siguiente chunk es *
334
+ if (fromIndex + 1 >= chunksArray.length) {
335
+ return null;
336
+ }
337
+ const secondChunk = chunksArray[fromIndex + 1];
338
+ if (!secondChunk) {
339
+ return null;
340
+ }
341
+ const secondValue = Array.from(secondChunk.value);
342
+ const secondStr = new TextDecoder().decode(new Uint8Array(secondValue));
343
+ if (secondStr !== "*") {
344
+ return null;
345
+ }
346
+ // Capturar todo hasta encontrar */
347
+ let matchedChunks = [firstChunk, secondChunk];
348
+ let currentIndex = fromIndex + 2;
349
+ while (currentIndex < chunksArray.length) {
350
+ const chunk = chunksArray[currentIndex];
351
+ if (!chunk)
352
+ break;
353
+ const value = Array.from(chunk.value);
354
+ const str = new TextDecoder().decode(new Uint8Array(value));
355
+ matchedChunks.push(chunk);
356
+ // Si encontramos *, verificar si el siguiente es /
357
+ if (str === "*") {
358
+ if (currentIndex + 1 < chunksArray.length) {
359
+ const nextChunk = chunksArray[currentIndex + 1];
360
+ if (nextChunk) {
361
+ const nextValue = Array.from(nextChunk.value);
362
+ const nextStr = new TextDecoder().decode(new Uint8Array(nextValue));
363
+ if (nextStr === "/") {
364
+ // Encontramos el cierre */
365
+ matchedChunks.push(nextChunk);
366
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
367
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
368
+ }
369
+ }
370
+ }
371
+ }
372
+ currentIndex++;
373
+ }
374
+ // No se encontró el cierre */
375
+ return null;
376
+ };
377
+ });
378
+ static heredoc = new TokenExpression((chunks, fromIndex) => {
379
+ return () => {
380
+ const chunksArray = Array.from(chunks.chunks);
381
+ if (fromIndex >= chunksArray.length) {
382
+ return null;
383
+ }
384
+ const firstChunk = chunksArray[fromIndex];
385
+ if (!firstChunk) {
386
+ return null;
387
+ }
388
+ const firstValue = Array.from(firstChunk.value);
389
+ const firstStr = new TextDecoder().decode(new Uint8Array(firstValue));
390
+ // Debe empezar con <<
391
+ if (firstStr !== "<") {
392
+ return null;
393
+ }
394
+ // Verificar que el siguiente chunk también es <
395
+ if (fromIndex + 1 >= chunksArray.length) {
396
+ return null;
397
+ }
398
+ const secondChunk = chunksArray[fromIndex + 1];
399
+ if (!secondChunk) {
400
+ return null;
401
+ }
402
+ const secondValue = Array.from(secondChunk.value);
403
+ const secondStr = new TextDecoder().decode(new Uint8Array(secondValue));
404
+ if (secondStr !== "<") {
405
+ return null;
406
+ }
407
+ let matchedChunks = [firstChunk, secondChunk];
408
+ let currentIndex = fromIndex + 2;
409
+ // Capturar el tag opcional (si existe)
410
+ if (currentIndex < chunksArray.length) {
411
+ const tagChunk = chunksArray[currentIndex];
412
+ if (tagChunk) {
413
+ const tagValue = Array.from(tagChunk.value);
414
+ const tagStr = new TextDecoder().decode(new Uint8Array(tagValue));
415
+ // Si es un keyword (letras/números/guiones bajos), es el tag
416
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tagStr)) {
417
+ matchedChunks.push(tagChunk);
418
+ currentIndex++;
419
+ }
420
+ }
421
+ }
422
+ // Debe haber un salto de línea después del << o <<TAG
423
+ if (currentIndex >= chunksArray.length) {
424
+ return null;
425
+ }
426
+ const newlineChunk = chunksArray[currentIndex];
427
+ if (!newlineChunk) {
428
+ return null;
429
+ }
430
+ const newlineValue = Array.from(newlineChunk.value);
431
+ const newlineStr = new TextDecoder().decode(new Uint8Array(newlineValue));
432
+ if (newlineStr !== "\n") {
433
+ return null;
434
+ }
435
+ matchedChunks.push(newlineChunk);
436
+ currentIndex++;
437
+ // Determinar la indentación de la línea donde está el <<
438
+ let directiveIndentation = 0;
439
+ for (let i = fromIndex - 1; i >= 0; i--) {
440
+ const prevChunk = chunksArray[i];
441
+ if (!prevChunk)
442
+ break;
443
+ const prevValue = Array.from(prevChunk.value);
444
+ const prevStr = new TextDecoder().decode(new Uint8Array(prevValue));
445
+ if (prevStr === "\n") {
446
+ // Encontramos el inicio de la línea, contar espacios después
447
+ let spaceIndex = i + 1;
448
+ while (spaceIndex < fromIndex) {
449
+ const spaceChunk = chunksArray[spaceIndex];
450
+ if (!spaceChunk)
451
+ break;
452
+ const spaceValue = Array.from(spaceChunk.value);
453
+ const spaceStr = new TextDecoder().decode(new Uint8Array(spaceValue));
454
+ if (spaceStr.trim() === "" && spaceStr !== "\n") {
455
+ directiveIndentation += spaceStr.length;
456
+ spaceIndex++;
457
+ }
458
+ else {
459
+ break;
460
+ }
461
+ }
462
+ break;
463
+ }
464
+ }
465
+ // Capturar contenido hasta encontrar una línea con indentación <= directiveIndentation
466
+ while (currentIndex < chunksArray.length) {
467
+ const chunk = chunksArray[currentIndex];
468
+ if (!chunk)
469
+ break;
470
+ const value = Array.from(chunk.value);
471
+ const str = new TextDecoder().decode(new Uint8Array(value));
472
+ // Si encontramos un salto de línea, verificar la siguiente línea
473
+ if (str === "\n") {
474
+ matchedChunks.push(chunk);
475
+ currentIndex++;
476
+ // Verificar la indentación de la siguiente línea
477
+ let lineIndentation = 0;
478
+ let checkIndex = currentIndex;
479
+ let hasContent = false;
480
+ // Contar espacios al inicio de la línea
481
+ while (checkIndex < chunksArray.length) {
482
+ const checkChunk = chunksArray[checkIndex];
483
+ if (!checkChunk)
484
+ break;
485
+ const checkValue = Array.from(checkChunk.value);
486
+ const checkStr = new TextDecoder().decode(new Uint8Array(checkValue));
487
+ if (checkStr.trim() === "" && checkStr !== "\n") {
488
+ lineIndentation += checkStr.length;
489
+ checkIndex++;
490
+ }
491
+ else if (checkStr === "\n") {
492
+ // Línea vacía, continuar con el contenido
493
+ break;
494
+ }
495
+ else {
496
+ // Hay contenido en esta línea
497
+ hasContent = true;
498
+ break;
499
+ }
500
+ }
501
+ // Si hay contenido y la indentación es <= a la de la directiva, terminar
502
+ if (hasContent && lineIndentation <= directiveIndentation) {
503
+ break;
504
+ }
505
+ }
506
+ else {
507
+ matchedChunks.push(chunk);
508
+ currentIndex++;
509
+ }
510
+ }
511
+ const matchedChunkList = new ChunkList(matchedChunks.length, matchedChunks);
512
+ return new MatchTokenExpressionResult(matchedChunkList, matchedChunks.length);
513
+ };
514
+ });
515
+ static whitespace = new TokenExpression((chunks, fromIndex) => {
516
+ return () => {
517
+ const chunksArray = Array.from(chunks.chunks);
518
+ if (fromIndex >= chunksArray.length) {
519
+ return null;
520
+ }
521
+ const chunk = chunksArray[fromIndex];
522
+ if (!chunk) {
523
+ return null;
524
+ }
525
+ const value = Array.from(chunk.value);
526
+ const str = new TextDecoder().decode(new Uint8Array(value));
527
+ // Verificar si es un espacio en blanco (sin incluir saltos de línea)
528
+ if (str.trim() === "" && !str.includes("\n")) {
529
+ const matchedChunks = [chunk];
530
+ const matchedChunkList = new ChunkList(1, matchedChunks);
531
+ return new MatchTokenExpressionResult(matchedChunkList, 1);
532
+ }
533
+ return null;
534
+ };
535
+ });
536
+ }
537
+ export class LexerEncoder {
538
+ encode(inpt) {
539
+ const chunkList = inpt instanceof ChunkList ? inpt : new ChunkEncoder().encode(inpt);
540
+ const expressions = {
541
+ singleComment: TokenExpression.singleComment,
542
+ multilineComment: TokenExpression.multilineComment,
543
+ whitespace: TokenExpression.whitespace,
544
+ heredoc: TokenExpression.heredoc,
545
+ string: TokenExpression.stringLiteral,
546
+ boolean: TokenExpression.booleanLiteral,
547
+ null: TokenExpression.nullLiteral,
548
+ number: TokenExpression.numberLiteral,
549
+ keyword: TokenExpression.keyword,
550
+ punctuator: TokenExpression.punctuator,
551
+ newline: TokenExpression.newline,
552
+ };
553
+ const hiddenExpressions = [
554
+ TokenExpression.singleComment,
555
+ TokenExpression.multilineComment,
556
+ TokenExpression.whitespace,
557
+ ];
558
+ const tokens = [];
559
+ const chunksArray = Array.from(chunkList.chunks);
560
+ let currentIndex = 0;
561
+ while (currentIndex < chunksArray.length) {
562
+ const chunk = chunksArray[currentIndex];
563
+ if (!chunk)
564
+ break;
565
+ // Intentar hacer match con cada expresión
566
+ const expressionResult = this.findMatchingExpression(expressions, chunkList, currentIndex);
567
+ if (!expressionResult) {
568
+ // Chunk desconocido - generar error
569
+ const unknownValue = new TextDecoder().decode(new Uint8Array(Array.from(chunk.value)));
570
+ throw new Error(`Unknown token at position ${chunk.pos}: "${unknownValue}"`);
571
+ }
572
+ const { tokenType, expression, result } = expressionResult;
573
+ const isHidden = hiddenExpressions.includes(expression);
574
+ // Extraer el valor del token
575
+ const matchedChunks = Array.from(result.matched.chunks);
576
+ const tokenValue = matchedChunks
577
+ .map((c) => {
578
+ const v = Array.from(c.value);
579
+ return new TextDecoder().decode(new Uint8Array(v));
580
+ })
581
+ .join("");
582
+ // Solo agregar el token si no está oculto
583
+ if (!isHidden) {
584
+ tokens.push(new Token(tokenType, tokenValue));
585
+ }
586
+ currentIndex += result.length;
587
+ }
588
+ return new Lexema(tokens.length, tokens);
589
+ }
590
+ findMatchingExpression(expressions, chunkList, currentIndex) {
591
+ for (const [tokenType, expression] of Object.entries(expressions)) {
592
+ const result = expression.match(chunkList, currentIndex);
593
+ if (result !== null) {
594
+ return { tokenType, expression, result };
595
+ }
596
+ }
597
+ return null;
598
+ }
599
+ }
600
+ //# sourceMappingURL=lexer.js.map