securemark 0.299.3 → 0.300.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.
Files changed (241) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/design.md +0 -6
  3. package/dist/index.js +3479 -2750
  4. package/index.d.ts +2 -1
  5. package/index.ts +2 -2
  6. package/markdown.d.ts +209 -183
  7. package/package.json +1 -1
  8. package/src/{parser/api → api}/bind.test.ts +2 -24
  9. package/src/{parser/api → api}/bind.ts +18 -13
  10. package/src/{parser/api → api}/body.test.ts +1 -1
  11. package/src/{parser/api → api}/cache.ts +1 -1
  12. package/src/{parser/api → api}/header.test.ts +1 -1
  13. package/src/{parser/api → api}/header.ts +9 -6
  14. package/src/{parser/api → api}/normalize.test.ts +1 -1
  15. package/src/{parser/api → api}/parse.test.ts +120 -124
  16. package/src/api/parse.ts +30 -0
  17. package/src/api/run.ts +6 -0
  18. package/src/{parser/api.ts → api.ts} +1 -0
  19. package/src/combinator/control/inits.ts +26 -0
  20. package/src/combinator/control/sequence.test.ts +38 -0
  21. package/src/combinator/control/sequence.ts +17 -0
  22. package/src/combinator/control/some.test.ts +41 -0
  23. package/src/combinator/{data/parser → control}/some.ts +39 -26
  24. package/src/combinator/control/state.ts +42 -0
  25. package/src/combinator/control/subsequence.test.ts +47 -0
  26. package/src/combinator/control/subsequence.ts +16 -0
  27. package/src/combinator/control/tails.ts +8 -0
  28. package/src/combinator/control/union.test.ts +37 -0
  29. package/src/combinator/control/union.ts +18 -0
  30. package/src/combinator/{data/delimiter.ts → delimiter.ts} +40 -60
  31. package/src/combinator/effect/backtrack.ts +64 -0
  32. package/src/combinator/effect/clock.ts +10 -0
  33. package/src/combinator/effect/precedence.ts +50 -0
  34. package/src/combinator/effect/recursion.ts +30 -0
  35. package/src/combinator/effect/scope.ts +100 -0
  36. package/src/combinator/effect/state.ts +72 -0
  37. package/src/combinator/{data/node.ts → parser/list.ts} +38 -13
  38. package/src/combinator/parser.ts +293 -0
  39. package/src/combinator/process/bind.ts +34 -0
  40. package/src/combinator/process/block.test.ts +20 -0
  41. package/src/combinator/process/block.ts +33 -0
  42. package/src/combinator/process/clear.ts +16 -0
  43. package/src/combinator/process/contract.ts +35 -0
  44. package/src/combinator/process/duplicate.ts +7 -0
  45. package/src/combinator/process/error.ts +13 -0
  46. package/src/combinator/{control/manipulation → process}/fallback.ts +3 -3
  47. package/src/combinator/process/fence.ts +59 -0
  48. package/src/combinator/process/fmap.ts +10 -0
  49. package/src/combinator/process/indent.test.ts +31 -0
  50. package/src/combinator/process/indent.ts +51 -0
  51. package/src/combinator/process/lazy.ts +8 -0
  52. package/src/combinator/process/line.test.ts +21 -0
  53. package/src/combinator/process/line.ts +55 -0
  54. package/src/combinator/process/match.ts +37 -0
  55. package/src/combinator/process/reverse.ts +7 -0
  56. package/src/combinator/process/scope.ts +102 -0
  57. package/src/combinator/process/surround.ts +271 -0
  58. package/src/combinator.ts +28 -24
  59. package/src/debug.test.ts +11 -8
  60. package/src/parser/autolink.test.ts +17 -18
  61. package/src/parser/block/blockquote.test.ts +78 -79
  62. package/src/parser/block/blockquote.ts +32 -25
  63. package/src/parser/block/codeblock.test.ts +56 -57
  64. package/src/parser/block/codeblock.ts +44 -26
  65. package/src/parser/block/dlist.test.ts +56 -57
  66. package/src/parser/block/dlist.ts +5 -5
  67. package/src/parser/block/extension/aside.test.ts +8 -9
  68. package/src/parser/block/extension/aside.ts +76 -47
  69. package/src/parser/block/extension/example.test.ts +18 -19
  70. package/src/parser/block/extension/example.ts +88 -48
  71. package/src/parser/block/extension/fig.test.ts +37 -36
  72. package/src/parser/block/extension/fig.ts +20 -25
  73. package/src/parser/block/extension/figbase.test.ts +18 -19
  74. package/src/parser/block/extension/figbase.ts +3 -3
  75. package/src/parser/block/extension/figure.test.ts +62 -63
  76. package/src/parser/block/extension/figure.ts +23 -21
  77. package/src/parser/block/extension/message.test.ts +13 -14
  78. package/src/parser/block/extension/message.ts +52 -39
  79. package/src/parser/block/extension/placeholder.test.ts +13 -13
  80. package/src/parser/block/extension/placeholder.ts +23 -21
  81. package/src/parser/block/extension/table.test.ts +70 -71
  82. package/src/parser/block/extension/table.ts +43 -31
  83. package/src/parser/block/extension.test.ts +24 -24
  84. package/src/parser/block/extension.ts +3 -3
  85. package/src/parser/block/heading.test.ts +58 -59
  86. package/src/parser/block/heading.ts +19 -18
  87. package/src/parser/block/ilist.test.ts +8 -8
  88. package/src/parser/block/ilist.ts +9 -7
  89. package/src/parser/block/mathblock.test.ts +31 -32
  90. package/src/parser/block/mathblock.ts +24 -23
  91. package/src/parser/block/mediablock.ts +7 -7
  92. package/src/parser/block/olist.test.ts +102 -103
  93. package/src/parser/block/olist.ts +11 -12
  94. package/src/parser/block/pagebreak.test.ts +15 -16
  95. package/src/parser/block/pagebreak.ts +5 -5
  96. package/src/parser/block/paragraph.test.ts +57 -58
  97. package/src/parser/block/paragraph.ts +1 -1
  98. package/src/parser/block/reply/cite.test.ts +39 -40
  99. package/src/parser/block/reply/cite.ts +5 -5
  100. package/src/parser/block/reply/quote.test.ts +50 -51
  101. package/src/parser/block/reply/quote.ts +8 -7
  102. package/src/parser/block/reply.test.ts +19 -20
  103. package/src/parser/block/reply.ts +2 -2
  104. package/src/parser/block/sidefence.test.ts +41 -48
  105. package/src/parser/block/sidefence.ts +17 -11
  106. package/src/parser/block/table.test.ts +48 -49
  107. package/src/parser/block/table.ts +10 -9
  108. package/src/parser/block/ulist.test.ts +52 -53
  109. package/src/parser/block/ulist.ts +9 -8
  110. package/src/parser/block.ts +63 -51
  111. package/src/parser/context.ts +35 -32
  112. package/src/parser/document.ts +48 -0
  113. package/src/parser/header.test.ts +19 -20
  114. package/src/parser/header.ts +31 -25
  115. package/src/parser/inline/annotation.test.ts +49 -50
  116. package/src/parser/inline/annotation.ts +14 -16
  117. package/src/parser/inline/autolink/account.test.ts +32 -33
  118. package/src/parser/inline/autolink/account.ts +18 -19
  119. package/src/parser/inline/autolink/anchor.test.ts +21 -22
  120. package/src/parser/inline/autolink/anchor.ts +7 -8
  121. package/src/parser/inline/autolink/channel.test.ts +14 -15
  122. package/src/parser/inline/autolink/email.test.ts +36 -37
  123. package/src/parser/inline/autolink/email.ts +6 -6
  124. package/src/parser/inline/autolink/hashnum.test.ts +32 -33
  125. package/src/parser/inline/autolink/hashnum.ts +7 -8
  126. package/src/parser/inline/autolink/hashtag.test.ts +59 -60
  127. package/src/parser/inline/autolink/hashtag.ts +8 -9
  128. package/src/parser/inline/autolink/url.test.ts +75 -76
  129. package/src/parser/inline/autolink/url.ts +13 -14
  130. package/src/parser/inline/autolink.ts +24 -11
  131. package/src/parser/inline/bracket.test.ts +73 -74
  132. package/src/parser/inline/bracket.ts +88 -63
  133. package/src/parser/inline/code.test.ts +30 -31
  134. package/src/parser/inline/code.ts +6 -6
  135. package/src/parser/inline/deletion.test.ts +27 -28
  136. package/src/parser/inline/deletion.ts +5 -5
  137. package/src/parser/inline/emphasis.test.ts +39 -40
  138. package/src/parser/inline/emphasis.ts +5 -5
  139. package/src/parser/inline/emstrong.test.ts +101 -102
  140. package/src/parser/inline/emstrong.ts +103 -85
  141. package/src/parser/inline/extension/index.test.ts +91 -92
  142. package/src/parser/inline/extension/index.ts +17 -13
  143. package/src/parser/inline/extension/indexee.ts +4 -4
  144. package/src/parser/inline/extension/indexer.test.ts +23 -24
  145. package/src/parser/inline/extension/indexer.ts +6 -5
  146. package/src/parser/inline/extension/label.test.ts +32 -33
  147. package/src/parser/inline/extension/label.ts +14 -5
  148. package/src/parser/inline/extension/placeholder.test.ts +42 -43
  149. package/src/parser/inline/extension/placeholder.ts +8 -9
  150. package/src/parser/inline/html.test.ts +109 -109
  151. package/src/parser/inline/html.ts +27 -27
  152. package/src/parser/inline/htmlentity.test.ts +37 -38
  153. package/src/parser/inline/htmlentity.ts +6 -7
  154. package/src/parser/inline/insertion.test.ts +27 -28
  155. package/src/parser/inline/insertion.ts +5 -5
  156. package/src/parser/inline/italic.test.ts +55 -56
  157. package/src/parser/inline/italic.ts +5 -5
  158. package/src/parser/inline/link.test.ts +186 -187
  159. package/src/parser/inline/link.ts +31 -32
  160. package/src/parser/inline/mark.test.ts +31 -32
  161. package/src/parser/inline/mark.ts +6 -6
  162. package/src/parser/inline/math.test.ts +140 -141
  163. package/src/parser/inline/math.ts +6 -7
  164. package/src/parser/inline/media.test.ts +92 -93
  165. package/src/parser/inline/media.ts +32 -38
  166. package/src/parser/inline/reference.test.ts +111 -112
  167. package/src/parser/inline/reference.ts +61 -32
  168. package/src/parser/inline/remark.test.ts +49 -50
  169. package/src/parser/inline/remark.ts +13 -13
  170. package/src/parser/inline/ruby.test.ts +49 -50
  171. package/src/parser/inline/ruby.ts +60 -49
  172. package/src/parser/inline/shortmedia.test.ts +9 -10
  173. package/src/parser/inline/shortmedia.ts +11 -9
  174. package/src/parser/inline/strong.test.ts +36 -37
  175. package/src/parser/inline/strong.ts +5 -5
  176. package/src/parser/inline/template.test.ts +22 -23
  177. package/src/parser/inline/template.ts +13 -16
  178. package/src/parser/inline.test.ts +225 -226
  179. package/src/parser/inline.ts +68 -34
  180. package/src/parser/node.ts +1 -1
  181. package/src/parser/parser.ts +51 -0
  182. package/src/parser/repeat.ts +118 -91
  183. package/src/parser/segment.test.ts +0 -11
  184. package/src/parser/segment.ts +25 -28
  185. package/src/parser/source/escapable.test.ts +23 -24
  186. package/src/parser/source/escapable.ts +20 -20
  187. package/src/parser/source/line.test.ts +17 -18
  188. package/src/parser/source/line.ts +19 -24
  189. package/src/parser/source/str.ts +17 -10
  190. package/src/parser/source/text.test.ts +88 -89
  191. package/src/parser/source/text.ts +19 -20
  192. package/src/parser/source/unescapable.test.ts +23 -24
  193. package/src/parser/source/unescapable.ts +16 -16
  194. package/src/parser/util.ts +1 -1
  195. package/src/parser/visibility.ts +36 -15
  196. package/src/{parser/processor → processor}/figure.test.ts +23 -23
  197. package/src/{parser/processor → processor}/figure.ts +20 -12
  198. package/src/{parser/processor → processor}/note.test.ts +15 -15
  199. package/src/{parser/processor → processor}/note.ts +6 -4
  200. package/src/renderer/render/media/pdf.ts +2 -2
  201. package/src/renderer/render/media/twitter.ts +2 -2
  202. package/src/renderer/render/media.test.ts +12 -13
  203. package/src/renderer/render.test.ts +11 -11
  204. package/src/util/info.test.ts +2 -2
  205. package/src/util/quote.test.ts +3 -3
  206. package/src/util/quote.ts +6 -5
  207. package/src/util/toc.test.ts +12 -12
  208. package/src/combinator/control/constraint/block.test.ts +0 -20
  209. package/src/combinator/control/constraint/block.ts +0 -28
  210. package/src/combinator/control/constraint/contract.ts +0 -27
  211. package/src/combinator/control/constraint/line.test.ts +0 -21
  212. package/src/combinator/control/constraint/line.ts +0 -42
  213. package/src/combinator/control/manipulation/clear.ts +0 -5
  214. package/src/combinator/control/manipulation/convert.ts +0 -22
  215. package/src/combinator/control/manipulation/duplicate.ts +0 -7
  216. package/src/combinator/control/manipulation/fence.ts +0 -54
  217. package/src/combinator/control/manipulation/indent.test.ts +0 -31
  218. package/src/combinator/control/manipulation/indent.ts +0 -39
  219. package/src/combinator/control/manipulation/lazy.ts +0 -8
  220. package/src/combinator/control/manipulation/match.ts +0 -27
  221. package/src/combinator/control/manipulation/recovery.ts +0 -18
  222. package/src/combinator/control/manipulation/reverse.ts +0 -8
  223. package/src/combinator/control/manipulation/scope.ts +0 -61
  224. package/src/combinator/control/manipulation/surround.ts +0 -223
  225. package/src/combinator/control/monad/bind.ts +0 -26
  226. package/src/combinator/control/monad/fmap.ts +0 -10
  227. package/src/combinator/data/parser/context.ts +0 -96
  228. package/src/combinator/data/parser/inits.ts +0 -20
  229. package/src/combinator/data/parser/sequence.test.ts +0 -33
  230. package/src/combinator/data/parser/sequence.ts +0 -20
  231. package/src/combinator/data/parser/some.test.ts +0 -37
  232. package/src/combinator/data/parser/subsequence.test.ts +0 -41
  233. package/src/combinator/data/parser/subsequence.ts +0 -13
  234. package/src/combinator/data/parser/tails.ts +0 -8
  235. package/src/combinator/data/parser/union.test.ts +0 -33
  236. package/src/combinator/data/parser/union.ts +0 -18
  237. package/src/combinator/data/parser.ts +0 -144
  238. package/src/parser/api/parse.ts +0 -48
  239. package/src/parser.ts +0 -1
  240. /package/src/{parser/api → api}/body.ts +0 -0
  241. /package/src/{parser/api → api}/normalize.ts +0 -0
@@ -0,0 +1,64 @@
1
+ import { always } from '../control/state';
2
+ import { Parser, Input } from '../parser';
3
+ import { Scope } from './scope';
4
+
5
+ interface Data {
6
+ readonly segment: number;
7
+ readonly position: number;
8
+ readonly range: number;
9
+ readonly linebreak: number;
10
+ }
11
+
12
+ export class Backtrack {
13
+ constructor(
14
+ private readonly scope: Scope<Input>,
15
+ ) {
16
+ }
17
+ private readonly stack: Data[] = [];
18
+ public memory(data: Data): void {
19
+ this.stack.push(data);
20
+ }
21
+ private unmemory(): void {
22
+ this.stack.pop();
23
+ }
24
+ private backtrack(): void {
25
+ assert(this.stack.length > 0);
26
+ const { segment, position, range, linebreak } = this.stack.pop()!;
27
+ const input = this.scope.peek();
28
+ input.segment = segment;
29
+ input.position = position;
30
+ input.range = range;
31
+ input.linebreak = linebreak;
32
+ }
33
+ public handle(state: boolean): void {
34
+ state
35
+ ? this.unmemory()
36
+ : this.backtrack();
37
+ }
38
+ }
39
+
40
+ export function backtrack<P extends Parser>(parser: P): P;
41
+ export function backtrack<T>(parser: Parser<T>): Parser<T> {
42
+ assert(parser);
43
+ return always([
44
+ (input, output) => {
45
+ const { backtrack, segment, position, range, linebreak } = input;
46
+ backtrack.memory({
47
+ segment,
48
+ position,
49
+ range,
50
+ linebreak,
51
+ });
52
+ output.push();
53
+ return output.context;
54
+ },
55
+ parser,
56
+ ({ backtrack }, output) => {
57
+ output.state
58
+ ? output.flat()
59
+ : output.pop();
60
+ backtrack.handle(output.state);
61
+ return output.context;
62
+ },
63
+ ]);
64
+ }
@@ -0,0 +1,10 @@
1
+ import { Input, Output } from '../parser';
2
+
3
+ export function spend(input: Input, output: Output<unknown>, cost: number): void {
4
+ assert(cost >= 0);
5
+ const resources = input.resources ?? { clock: cost, recursions: [1] };
6
+ if (resources.clock >= 0 && resources.clock - cost < 0) {
7
+ output.error ??= new Error('Too many creations');
8
+ }
9
+ resources.clock -= cost;
10
+ }
@@ -0,0 +1,50 @@
1
+ import { Parser, Input } from '../parser';
2
+ import { Delimiters } from '../delimiter';
3
+ import { always } from '../control/state';
4
+
5
+ export class Precedence {
6
+ constructor(input: Input) {
7
+ this.delimiters = input.delimiters;
8
+ }
9
+ private readonly stack: number[] = [];
10
+ private readonly delimiters: Delimiters;
11
+ public get(): number {
12
+ return this.stack.at(-1) ?? 0;
13
+ }
14
+ public modify(precedence: number): void {
15
+ const p = this.get();
16
+ this.stack.push(precedence);
17
+ precedence > p && this.delimiters.shift(precedence);
18
+ }
19
+ public revert(precedence: number): void {
20
+ assert(this.stack.length > 0);
21
+ const p = this.stack.pop()!;
22
+ precedence > p && this.delimiters.unshift();
23
+ }
24
+ }
25
+
26
+ export function precedence<P extends Parser>(precedence: number, parser: P): P;
27
+ export function precedence<T>(precedence: number, parser: Parser<T>): Parser<T> {
28
+ assert(precedence >= 0);
29
+ interface Memory {
30
+ readonly precedence: number;
31
+ }
32
+ return always<Parser<T, Input<Memory>>>([
33
+ (input, output) => {
34
+ const p = input.precedence;
35
+ precedence > p && input.delimiters.shift(precedence);
36
+ input.memory = {
37
+ precedence: p,
38
+ };
39
+ input.precedence = precedence;
40
+ return output.context;
41
+ },
42
+ parser,
43
+ (input, output) => {
44
+ const p = input.memory.precedence;
45
+ input.precedence = p;
46
+ precedence > p && input.delimiters.unshift();
47
+ return output.context;
48
+ },
49
+ ]);
50
+ }
@@ -0,0 +1,30 @@
1
+ import { Parser, Output } from '../parser';
2
+ import { always } from '../control/state';
3
+ import { min } from 'spica/alias';
4
+
5
+ export function recursion<P extends Parser>(index: number, parser: P): P;
6
+ export function recursion<T>(index: number, parser: Parser<T>): Parser<T> {
7
+ assert(index >= 0);
8
+ return always([
9
+ (input, output) => {
10
+ const resources = input.resources ?? { clock: 1, recursions: [1] };
11
+ const { recursions } = resources;
12
+ recur(output, recursions, index, 1);
13
+ return output.context;
14
+ },
15
+ parser,
16
+ (input, output) => {
17
+ const resources = input.resources ?? { clock: 1, recursions: [1] };
18
+ const { recursions } = resources;
19
+ recur(output, recursions, index, -1);
20
+ return output.context;
21
+ },
22
+ ]);
23
+ }
24
+ export function recur(output: Output<unknown>, recursions: number[], index: number, size: number, force: boolean = false): void {
25
+ index = min(index, recursions.length && recursions.length - 1);
26
+ if (recursions[index] < size - +force) {
27
+ output.error ??= new Error('Too much recursion');
28
+ }
29
+ recursions[index] -= size;
30
+ }
@@ -0,0 +1,100 @@
1
+ import { Parser, Input, Output, subinput } from '../parser';
2
+ import { always } from '../control/state';
3
+
4
+ interface Memory {
5
+ readonly SID: number;
6
+ readonly source: string;
7
+ readonly position: number;
8
+ readonly offset: number;
9
+ readonly linebreak: number;
10
+ readonly range: number;
11
+ }
12
+
13
+ export class Scope<I extends Input> {
14
+ constructor(input: I) {
15
+ this.inputs.push(input);
16
+ }
17
+ private readonly inputs: I[] = [];
18
+ private readonly memories: Memory[] = [];
19
+ public peek(): I {
20
+ //assert(this.inputs.length > 0);
21
+ return this.inputs.at(-1)!;
22
+ }
23
+ public focus(subsource: string): void {
24
+ const input = this.peek();
25
+ assert(subsource.length <= input.source.length);
26
+ assert(input.position - subsource.length >= 0);
27
+ input.position -= subsource.length;
28
+ const { SID, source, position, offset, linebreak, range } = input;
29
+ this.memories.push({
30
+ SID,
31
+ source,
32
+ position,
33
+ offset,
34
+ linebreak,
35
+ range,
36
+ });
37
+ subinput(subsource, input);
38
+ }
39
+ public unfocus(state = true, continuous = false): void {
40
+ assert(this.memories.length > 0);
41
+ const input = this.peek();
42
+ const { source, position } = input;
43
+ const memory = this.memories.pop()!;
44
+ input.SID = memory.SID;
45
+ input.position = state
46
+ ? continuous && position > 0
47
+ ? memory.position + position
48
+ : memory.position + source.length
49
+ : memory.position;
50
+ input.source = memory.source;
51
+ assert(position <= source.length);
52
+ input.offset = memory.offset;
53
+ input.linebreak = memory.linebreak;
54
+ input.range = memory.range;
55
+ }
56
+ public push(source: string): I {
57
+ const input = this.peek().clone(source);
58
+ this.inputs.push(input);
59
+ return input;
60
+ }
61
+ public pop(): I {
62
+ this.inputs.pop();
63
+ return this.peek();
64
+ }
65
+ }
66
+
67
+ export function scope<P extends Parser>(
68
+ conv: (input: Parser.Input<P>, output: Output<Parser.Node<P>>) => string,
69
+ parser: P,
70
+ isolation: boolean,
71
+ ): P;
72
+ export function scope<T>(
73
+ conv: (input: Input, output: Output<T>) => string,
74
+ parser: Parser<T>,
75
+ isolation: boolean,
76
+ ): Parser<T> {
77
+ assert(parser);
78
+ return always([
79
+ (input, output) => {
80
+ const { source, position } = input;
81
+ const src = conv(input, output);
82
+ !isolation && input.position === position
83
+ ? input.position = source.length
84
+ : 0;
85
+ isolation
86
+ ? input.scope.push(src)
87
+ : input.scope.focus(src);
88
+ return output.context;
89
+ },
90
+ parser,
91
+ (input, output) => {
92
+ isolation
93
+ ? input.scope.pop()
94
+ : input.scope.unfocus();
95
+ if (!output.state) return;
96
+ assert(input.position <= input.source.length);
97
+ return output.context;
98
+ },
99
+ ]);
100
+ }
@@ -0,0 +1,72 @@
1
+ import { Parser, Result, Input } from '../parser';
2
+ import { always } from '../control/state';
3
+
4
+ export class State<T> {
5
+ constructor(private readonly initial: T) {
6
+ }
7
+ private readonly stack: T[] = [];
8
+ public get(): T {
9
+ return this.stack.at(-1) ?? this.initial;
10
+ }
11
+ public put(state: T): void {
12
+ this.stack.push(state);
13
+ }
14
+ public delete(): T {
15
+ assert(this.stack.length > 0);
16
+ const state = this.stack.pop()!;
17
+ return state;
18
+ }
19
+ }
20
+
21
+ export function state<P extends Parser>(state: number, parser: P): P;
22
+ export function state<P extends Parser>(state: number, positive: boolean, parser: P): P;
23
+ export function state<T>(state: number, positive: boolean | Parser<T>, parser?: Parser<T>): Parser<T> {
24
+ if (typeof positive === 'function') {
25
+ parser = positive;
26
+ positive = true;
27
+ }
28
+ assert(state);
29
+ assert(parser = parser!);
30
+ interface Memory {
31
+ readonly state: number;
32
+ }
33
+ return always<Parser<T, Input<Memory>>>([
34
+ (input, output) => {
35
+ const s = input.state;
36
+ input.state = positive
37
+ ? s | state
38
+ : s & ~state;
39
+ input.memory = {
40
+ state: s,
41
+ };
42
+ return output.context;
43
+ },
44
+ parser,
45
+ (input, output) => {
46
+ input.state = input.memory.state;
47
+ return output.context;
48
+ },
49
+ ]);
50
+ }
51
+
52
+ export function constraint<P extends Parser>(state: number, parser: P): P;
53
+ //export function constraint<P extends Parser>(state: number, positive: boolean, parser: P): P;
54
+ export function constraint<T>(state: number, positive: boolean | Parser<T>, parser?: Parser<T>): Parser<T> {
55
+ if (typeof positive === 'function') {
56
+ parser = positive;
57
+ positive = false;
58
+ }
59
+ assert(state);
60
+ assert(parser = parser!);
61
+ return always([
62
+ (input, output) => {
63
+ const s = positive
64
+ ? state & input.state
65
+ : state & ~input.state;
66
+ return s === state
67
+ ? output.context
68
+ : Result.skip;
69
+ },
70
+ parser,
71
+ ]);
72
+ }
@@ -1,6 +1,6 @@
1
- import { Parser, Context } from './parser';
1
+ import { Parser, Input } from '../parser';
2
2
 
3
- export class List<N extends List.Node = List.Node, C extends Context = Context, D extends Parser<unknown, C>[] = any> {
3
+ export class List<N extends List.Node = List.Node, I extends Input = Input, S extends readonly Parser<unknown, I>[] = Parser<unknown, I, any[]>[]> {
4
4
  constructor(nodes?: ArrayLike<N>) {
5
5
  if (nodes === undefined) return;
6
6
  for (let i = 0; i < nodes.length; ++i) {
@@ -15,8 +15,8 @@ export class List<N extends List.Node = List.Node, C extends Context = Context,
15
15
  }
16
16
  public insert(node: N, before?: N): N {
17
17
  assert(!node.next && !node.prev);
18
- if (before === undefined) return this.push(node);
19
- if (before === this.head) return this.unshift(node);
18
+ if (before === undefined) return this.push(node), node;
19
+ if (before === this.head) return this.unshift(node), node;
20
20
  if (++this.length === 1) {
21
21
  return this.head = this.last = node;
22
22
  }
@@ -43,21 +43,25 @@ export class List<N extends List.Node = List.Node, C extends Context = Context,
43
43
  node.next = node.prev = undefined;
44
44
  return node;
45
45
  }
46
- public unshift(node: N): N {
46
+ public unshift(node: N): this {
47
47
  assert(!node.next && !node.prev);
48
48
  if (++this.length === 1) {
49
- return this.head = this.last = node;
49
+ this.head = this.last = node;
50
+ return this;
50
51
  }
51
52
  node.next = this.head;
52
- return this.head = this.head!.prev = node;
53
+ this.head = this.head!.prev = node;
54
+ return this;
53
55
  }
54
- public push(node: N): N {
56
+ public push(node: N): this {
55
57
  assert(!node.next && !node.prev);
56
58
  if (++this.length === 1) {
57
- return this.head = this.last = node;
59
+ this.head = this.last = node;
60
+ return this;
58
61
  }
59
62
  node.prev = this.last;
60
- return this.last = this.last!.next = node;
63
+ this.last = this.last!.next = node;
64
+ return this;
61
65
  }
62
66
  public shift(): N | undefined {
63
67
  if (this.length === 0) return;
@@ -89,6 +93,18 @@ export class List<N extends List.Node = List.Node, C extends Context = Context,
89
93
  list.clear();
90
94
  return this;
91
95
  }
96
+ public truncateBefore(node: N): void {
97
+ assert(node.next || node.prev || this.head === this.last);
98
+ if (node.prev === undefined) return;
99
+ this.delete(node.prev);
100
+ this.head = node;
101
+ }
102
+ public truncateAfter(node: N): void {
103
+ assert(node.next || node.prev || this.head === this.last);
104
+ if (node.next === undefined) return;
105
+ this.delete(node.next);
106
+ this.last = node;
107
+ }
92
108
  public clear(): void {
93
109
  this.length = 0;
94
110
  this.head = this.last = undefined;
@@ -134,8 +150,17 @@ export class List<N extends List.Node = List.Node, C extends Context = Context,
134
150
  }
135
151
  }
136
152
  export namespace List {
137
- export class Node {
138
- public next?: this = undefined;
139
- public prev?: this = undefined;
153
+ export interface Node {
154
+ next?: this;
155
+ prev?: this;
140
156
  }
141
157
  }
158
+ export class Node<N> implements List.Node {
159
+ constructor(
160
+ public value: N,
161
+ public flags: number = 0,
162
+ ) {
163
+ }
164
+ public next?: this = undefined;
165
+ public prev?: this = undefined;
166
+ }