@spakhm/ts-parsec 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.d.ts CHANGED
@@ -22,7 +22,7 @@ export declare function toParser<T extends string>(p: T): parser<T>;
22
22
  export declare function toParser<T>(p: parserlike<T>): parser<T>;
23
23
  export declare const str: <T extends string>(match: T) => parser<T>;
24
24
  export declare const lex: <T>(p: parserlike<T>) => parser<T>;
25
- export declare const keepWs: <T>(p: parserlike<T>) => parser<T>;
26
- export declare const ws: parser<{}>;
25
+ export declare const lexMode: (wsMode: "keep_all" | "keep_newlines") => <T>(p: parserlike<T>) => parser<T>;
26
+ export declare const ws: (wsMode: "drop_all" | "keep_newlines") => parser<{}>;
27
27
  export declare const fwd: <T>(thunk: (() => parserlike<T>)) => parser<T>;
28
28
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKvC,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE,CAAC;AAEtE,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,KAAK,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAA2B,CAAC;AAC1E,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAAC,KAAK,EAAE,YAAY,CAC3C,CAAC;AAK5C,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACtE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IACpC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAK7D,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AA6BzD,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAQpD,CAAC;AAEN,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAWrC,CAAC;AAEH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAOtC,CAAC;AAEL,eAAO,MAAM,EAAE,YAYb,CAAC;AAKH,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,CACL,CAAC"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKvC,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE,CAAC;AAEtE,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,KAAK,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAA2B,CAAC;AAC1E,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAAC,KAAK,EAAE,YAAY,CAC3C,CAAC;AAK5C,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACtE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IACpC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAK7D,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AA6BzD,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAQpD,CAAC;AAEN,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAUrC,CAAC;AAEH,eAAO,MAAM,OAAO,GAAI,QAAQ,UAAU,GAAG,eAAe,MACzD,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,cAOhB,CAAC;AAEP,eAAO,MAAM,EAAE,GAAI,QAAQ,UAAU,GAAG,eAAe,eAqBnD,CAAC;AAKL,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,CACL,CAAC"}
package/dist/index.js CHANGED
@@ -30,32 +30,35 @@ var str = (match) => lex(toParser((source) => {
30
30
  return ok(match);
31
31
  }));
32
32
  var lex = (p) => toParser((source) => {
33
- if (!source.drop_ws) {
33
+ if (source.ws_mode === "keep_all") {
34
34
  return toParser(p)(source);
35
35
  } else {
36
- return keepWs((source2) => {
37
- ws(source2);
36
+ return lexMode("keep_all")((source2) => {
37
+ ws("drop_all")(source2);
38
38
  return toParser(p)(source2);
39
39
  })(source);
40
40
  }
41
41
  });
42
- var keepWs = (p) => toParser((source) => {
43
- const prev_drop_ws = source.drop_ws;
44
- source.drop_ws = false;
42
+ var lexMode = (wsMode) => (p) => toParser((source) => {
43
+ const prev_ws_mode = source.ws_mode;
44
+ source.ws_mode = wsMode;
45
45
  const res = toParser(p)(source);
46
- source.drop_ws = prev_drop_ws;
46
+ source.ws_mode = prev_ws_mode;
47
47
  return res;
48
48
  });
49
- var ws = toParser((source) => {
49
+ var ws = (wsMode) => toParser((source) => {
50
50
  while (true) {
51
51
  source.push();
52
52
  const ch = source.next();
53
- if (ch?.trim() === "") {
54
- source.pop_continue();
55
- } else {
53
+ if (wsMode == "keep_newlines" && ch == "\n") {
54
+ source.pop_rollback();
55
+ break;
56
+ }
57
+ if (ch === null || ch.trim() !== "") {
56
58
  source.pop_rollback();
57
59
  break;
58
60
  }
61
+ source.pop_continue();
59
62
  }
60
63
  return ok({});
61
64
  });
@@ -211,33 +214,55 @@ var anych = (opts) => toParser((source) => {
211
214
  return res ? ok(res) : err(0, 0, "");
212
215
  });
213
216
  var eof = not(anych());
217
+ var eol = str("\n");
214
218
  // src/stream.ts
215
219
  class string_stream {
216
220
  source;
217
- drop_ws;
221
+ ws_mode;
218
222
  row = 1;
219
223
  col = 1;
220
224
  idx = 0;
221
225
  stack = [];
222
- constructor(source, drop_ws = true) {
226
+ constructor(source, ws_mode = "drop_all") {
223
227
  this.source = source;
224
- this.drop_ws = drop_ws;
228
+ this.ws_mode = ws_mode;
225
229
  }
226
230
  next() {
227
231
  if (this.idx == this.source.length) {
228
232
  return null;
229
233
  }
230
- const ch = this.source[this.idx++];
231
- this.col++;
234
+ const ch = this.normalizeNewline(this.source[this.idx++]);
232
235
  if (ch == "\n") {
233
236
  this.row++;
234
237
  this.col = 1;
235
- }
236
- if (this.drop_ws && ch.trim() === "") {
237
- return this.next();
238
238
  } else {
239
+ this.col++;
240
+ }
241
+ if (this.ws_mode === "keep_all") {
239
242
  return ch;
240
243
  }
244
+ if (this.ws_mode === "drop_all" && ch.trim() === "") {
245
+ return this.next();
246
+ }
247
+ if (this.ws_mode === "keep_newlines") {
248
+ if (ch === "\n") {
249
+ return ch;
250
+ }
251
+ if (ch.trim() === "") {
252
+ return this.next();
253
+ }
254
+ }
255
+ return ch;
256
+ }
257
+ normalizeNewline(ch) {
258
+ const peek2 = () => this.idx == this.source.length ? null : this.source[this.idx];
259
+ if (ch == "\r") {
260
+ if (peek2() == "\n") {
261
+ this.idx++;
262
+ }
263
+ ch = "\n";
264
+ }
265
+ return ch;
241
266
  }
242
267
  push() {
243
268
  this.stack.push({
@@ -256,8 +281,8 @@ class string_stream {
256
281
  this.idx = x.idx;
257
282
  }
258
283
  }
259
- var fromString = (source) => {
260
- return new string_stream(source);
284
+ var fromString = (source, ws_mode = "drop_all") => {
285
+ return new string_stream(source, ws_mode);
261
286
  };
262
287
  export {
263
288
  ws,
@@ -277,12 +302,13 @@ export {
277
302
  maybe,
278
303
  many,
279
304
  lower,
305
+ lexMode,
280
306
  lex,
281
- keepWs,
282
307
  int,
283
308
  fwd,
284
309
  fromString,
285
310
  err,
311
+ eol,
286
312
  eof,
287
313
  either,
288
314
  digit,
package/dist/lib.d.ts CHANGED
@@ -27,4 +27,5 @@ export declare const anych: (opts?: {
27
27
  but: parserlike<unknown>;
28
28
  }) => parser<string>;
29
29
  export declare const eof: parser<null>;
30
+ export declare const eol: parser<"\n">;
30
31
  //# sourceMappingURL=lib.d.ts.map
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
package/dist/stream.d.ts CHANGED
@@ -1,11 +1,12 @@
1
+ export type ws_mode = 'keep_all' | 'drop_all' | 'keep_newlines';
1
2
  export type stream = {
2
3
  row: number;
3
4
  col: number;
4
- drop_ws: boolean;
5
+ ws_mode: ws_mode;
5
6
  next: () => string | null;
6
7
  push: () => void;
7
8
  pop_continue: () => void;
8
9
  pop_rollback: () => void;
9
10
  };
10
- export declare const fromString: (source: string) => stream;
11
+ export declare const fromString: (source: string, ws_mode?: ws_mode) => stream;
11
12
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAmDF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,KAAG,MAE3C,CAAA"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;AAEhE,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AA+EF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,UAAS,OAAoB,KAAG,MAE1E,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spakhm/ts-parsec",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "license": "MIT",
5
5
  "author": "Slava Akhmechet",
6
6
  "type": "module",
package/src/base.ts CHANGED
@@ -63,40 +63,49 @@ export const str = <T extends string>(match: T): parser<T> =>
63
63
  }));
64
64
 
65
65
  export const lex = <T>(p: parserlike<T>) => toParser((source: stream) => {
66
- if (!source.drop_ws) {
67
- // this call to lex is nested (i.e. we're in lex mode already)
68
- // don't drop more whitespace
66
+ if (source.ws_mode === 'keep_all') {
67
+ // nested lex call, don't drop more whitespace
69
68
  return toParser(p)(source);
70
69
  } else {
71
- return keepWs((source: stream) => {
72
- ws(source);
70
+ return lexMode('keep_all')((source: stream) => {
71
+ ws('drop_all')(source); // lex always drops all ws including newlines
73
72
  return toParser(p)(source);
74
73
  })(source);
75
74
  }
76
75
  });
77
76
 
78
- export const keepWs = <T>(p: parserlike<T>) =>
77
+ export const lexMode = (wsMode: 'keep_all' | 'keep_newlines') =>
78
+ <T>(p: parserlike<T>) =>
79
+ toParser((source: stream) => {
80
+ const prev_ws_mode = source.ws_mode;
81
+ source.ws_mode = wsMode;
82
+ const res = toParser(p)(source);
83
+ source.ws_mode = prev_ws_mode;
84
+ return res;
85
+ });
86
+
87
+ export const ws = (wsMode: 'drop_all' | 'keep_newlines') =>
79
88
  toParser((source: stream) => {
80
- const prev_drop_ws = source.drop_ws;
81
- source.drop_ws = false;
82
- const res = toParser(p)(source);
83
- source.drop_ws = prev_drop_ws;
84
- return res;
85
- });
89
+ while (true) {
90
+ source.push();
91
+ const ch = source.next();
92
+
93
+ // If we gotta keep newlines and we hit one, return it
94
+ if (wsMode == 'keep_newlines' && ch == '\n') {
95
+ source.pop_rollback();
96
+ break;
97
+ }
98
+
99
+ // If we hit eof or a non-whitespace character, return it
100
+ if (ch === null || ch.trim() !== '') {
101
+ source.pop_rollback();
102
+ break;
103
+ }
86
104
 
87
- export const ws = toParser((source: stream) => {
88
- while (true) {
89
- source.push();
90
- const ch = source.next();
91
- if (ch?.trim() === "") {
92
105
  source.pop_continue();
93
- } else {
94
- source.pop_rollback();
95
- break;
96
106
  }
97
- }
98
- return ok({});
99
- });
107
+ return ok({});
108
+ });
100
109
 
101
110
  /*
102
111
  Laziness helper
package/src/lib.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { stream } from './stream';
2
2
  import type { parser, parserlike } from './base';
3
- import { err, ok, toParser, lex } from './base';
3
+ import { err, ok, toParser, lex, str } from './base';
4
4
 
5
5
  export const attempt = <T>(parser: parserlike<T>): parser<T> =>
6
6
  toParser((source: stream) => {
@@ -198,3 +198,5 @@ export const anych = (opts?: { but: parserlike<unknown> }) => toParser((source:
198
198
  });
199
199
 
200
200
  export const eof = not(anych());
201
+
202
+ export const eol = str('\n');
package/src/stream.ts CHANGED
@@ -1,8 +1,10 @@
1
1
 
2
+ export type ws_mode = 'keep_all' | 'drop_all' | 'keep_newlines';
3
+
2
4
  export type stream = {
3
5
  row: number,
4
6
  col: number,
5
- drop_ws: boolean,
7
+ ws_mode: ws_mode,
6
8
  next: () => string | null,
7
9
  push: () => void,
8
10
  pop_continue: () => void,
@@ -20,24 +22,52 @@ class string_stream {
20
22
  idx: number,
21
23
  }[] = [];
22
24
 
23
- constructor(public source: string, public drop_ws: boolean = true) {}
25
+ constructor(public source: string, public ws_mode: ws_mode = 'drop_all') {}
24
26
 
25
27
  next(): string | null {
26
28
  if (this.idx == this.source.length) {
27
29
  return null;
28
30
  }
29
- const ch = this.source[this.idx++];
30
- this.col++;
31
+
32
+ const ch = this.normalizeNewline(this.source[this.idx++]);
31
33
  if (ch == '\n') {
32
34
  this.row++;
33
35
  this.col = 1;
36
+ } else {
37
+ this.col++;
34
38
  }
35
39
 
36
- if (this.drop_ws && ch.trim() === "") {
37
- return this.next();
38
- } else {
40
+ if (this.ws_mode === 'keep_all') {
39
41
  return ch;
40
42
  }
43
+
44
+ if (this.ws_mode === 'drop_all' && ch.trim() === '') {
45
+ return this.next();
46
+ }
47
+
48
+ if (this.ws_mode === 'keep_newlines') {
49
+ if (ch === '\n') {
50
+ return ch;
51
+ }
52
+ if (ch.trim() === '') {
53
+ return this.next();
54
+ }
55
+ }
56
+
57
+ return ch;
58
+ }
59
+
60
+ private normalizeNewline(ch: string) {
61
+ const peek = () =>
62
+ this.idx == this.source.length ? null : this.source[this.idx];
63
+
64
+ if (ch == '\r') {
65
+ if (peek() == '\n') {
66
+ this.idx++;
67
+ }
68
+ ch = '\n';
69
+ }
70
+ return ch;
41
71
  }
42
72
 
43
73
  push() {
@@ -58,6 +88,6 @@ class string_stream {
58
88
  }
59
89
  }
60
90
 
61
- export const fromString = (source: string): stream => {
62
- return new string_stream(source);
91
+ export const fromString = (source: string, ws_mode: ws_mode = 'drop_all'): stream => {
92
+ return new string_stream(source, ws_mode);
63
93
  }