securemark 0.299.4 → 0.300.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/design.md +0 -6
- package/dist/index.js +2847 -1993
- package/index.d.ts +2 -1
- package/markdown.d.ts +209 -183
- package/package.json +1 -1
- package/src/api/bind.test.ts +0 -22
- package/src/api/bind.ts +15 -10
- package/src/api/header.ts +8 -5
- package/src/api/parse.test.ts +118 -122
- package/src/api/parse.ts +13 -31
- package/src/api/run.ts +6 -0
- package/src/api.ts +1 -0
- package/src/combinator/control/inits.ts +35 -0
- package/src/combinator/control/sequence.test.ts +38 -0
- package/src/combinator/control/sequence.ts +19 -0
- package/src/combinator/control/some.test.ts +41 -0
- package/src/combinator/{data/parser → control}/some.ts +39 -26
- package/src/combinator/control/state.ts +33 -0
- package/src/combinator/control/subsequence.test.ts +47 -0
- package/src/combinator/control/subsequence.ts +16 -0
- package/src/combinator/control/tails.ts +8 -0
- package/src/combinator/control/union.test.ts +37 -0
- package/src/combinator/control/union.ts +31 -0
- package/src/combinator/{data/delimiter.ts → delimiter.ts} +40 -60
- package/src/combinator/effect/backtrack.ts +64 -0
- package/src/combinator/effect/clock.ts +10 -0
- package/src/combinator/effect/precedence.ts +50 -0
- package/src/combinator/effect/recursion.ts +30 -0
- package/src/combinator/effect/scope.ts +100 -0
- package/src/combinator/effect/state.ts +72 -0
- package/src/combinator/{data/list → parser}/list.ts +35 -10
- package/src/combinator/parser.ts +303 -0
- package/src/combinator/process/bind.ts +34 -0
- package/src/combinator/process/block.test.ts +20 -0
- package/src/combinator/process/block.ts +33 -0
- package/src/combinator/process/clear.ts +16 -0
- package/src/combinator/process/contract.ts +35 -0
- package/src/combinator/process/duplicate.ts +7 -0
- package/src/combinator/process/error.ts +13 -0
- package/src/combinator/{control/manipulation → process}/fallback.ts +3 -3
- package/src/combinator/process/fence.ts +59 -0
- package/src/combinator/process/fmap.ts +10 -0
- package/src/combinator/process/indent.test.ts +31 -0
- package/src/combinator/process/indent.ts +51 -0
- package/src/combinator/process/lazy.ts +8 -0
- package/src/combinator/process/line.test.ts +21 -0
- package/src/combinator/process/line.ts +55 -0
- package/src/combinator/process/match.ts +37 -0
- package/src/combinator/process/reverse.ts +7 -0
- package/src/combinator/process/scope.ts +102 -0
- package/src/combinator/process/surround.ts +273 -0
- package/src/combinator.ts +28 -24
- package/src/debug.test.ts +11 -8
- package/src/parser/autolink.test.ts +17 -18
- package/src/parser/block/blockquote.test.ts +78 -79
- package/src/parser/block/blockquote.ts +32 -25
- package/src/parser/block/codeblock.test.ts +54 -57
- package/src/parser/block/codeblock.ts +44 -26
- package/src/parser/block/dlist.test.ts +56 -57
- package/src/parser/block/dlist.ts +5 -5
- package/src/parser/block/extension/aside.test.ts +7 -9
- package/src/parser/block/extension/aside.ts +76 -47
- package/src/parser/block/extension/example.test.ts +16 -19
- package/src/parser/block/extension/example.ts +88 -48
- package/src/parser/block/extension/fig.test.ts +37 -36
- package/src/parser/block/extension/fig.ts +20 -25
- package/src/parser/block/extension/figbase.test.ts +18 -19
- package/src/parser/block/extension/figbase.ts +3 -3
- package/src/parser/block/extension/figure.test.ts +58 -63
- package/src/parser/block/extension/figure.ts +23 -21
- package/src/parser/block/extension/message.test.ts +12 -14
- package/src/parser/block/extension/message.ts +52 -39
- package/src/parser/block/extension/placeholder.test.ts +13 -13
- package/src/parser/block/extension/placeholder.ts +23 -21
- package/src/parser/block/extension/table.test.ts +69 -71
- package/src/parser/block/extension/table.ts +43 -31
- package/src/parser/block/extension.test.ts +24 -24
- package/src/parser/block/extension.ts +3 -3
- package/src/parser/block/heading.test.ts +58 -59
- package/src/parser/block/heading.ts +19 -18
- package/src/parser/block/ilist.test.ts +8 -8
- package/src/parser/block/ilist.ts +9 -7
- package/src/parser/block/mathblock.test.ts +29 -32
- package/src/parser/block/mathblock.ts +24 -23
- package/src/parser/block/mediablock.ts +7 -7
- package/src/parser/block/olist.test.ts +102 -103
- package/src/parser/block/olist.ts +11 -12
- package/src/parser/block/pagebreak.test.ts +15 -16
- package/src/parser/block/pagebreak.ts +5 -5
- package/src/parser/block/paragraph.test.ts +57 -58
- package/src/parser/block/paragraph.ts +1 -1
- package/src/parser/block/reply/cite.test.ts +39 -40
- package/src/parser/block/reply/cite.ts +5 -5
- package/src/parser/block/reply/quote.test.ts +50 -51
- package/src/parser/block/reply/quote.ts +8 -7
- package/src/parser/block/reply.test.ts +19 -20
- package/src/parser/block/reply.ts +2 -2
- package/src/parser/block/sidefence.test.ts +41 -48
- package/src/parser/block/sidefence.ts +17 -11
- package/src/parser/block/table.test.ts +48 -49
- package/src/parser/block/table.ts +10 -9
- package/src/parser/block/ulist.test.ts +52 -53
- package/src/parser/block/ulist.ts +9 -8
- package/src/parser/block.ts +63 -51
- package/src/parser/context.ts +40 -40
- package/src/parser/document.ts +48 -0
- package/src/parser/header.test.ts +19 -20
- package/src/parser/header.ts +31 -25
- package/src/parser/inline/annotation.test.ts +49 -50
- package/src/parser/inline/annotation.ts +14 -16
- package/src/parser/inline/autolink/account.test.ts +32 -33
- package/src/parser/inline/autolink/account.ts +18 -19
- package/src/parser/inline/autolink/anchor.test.ts +21 -22
- package/src/parser/inline/autolink/anchor.ts +7 -8
- package/src/parser/inline/autolink/channel.test.ts +14 -15
- package/src/parser/inline/autolink/email.test.ts +36 -37
- package/src/parser/inline/autolink/email.ts +6 -6
- package/src/parser/inline/autolink/hashnum.test.ts +32 -33
- package/src/parser/inline/autolink/hashnum.ts +7 -8
- package/src/parser/inline/autolink/hashtag.test.ts +59 -60
- package/src/parser/inline/autolink/hashtag.ts +8 -9
- package/src/parser/inline/autolink/url.test.ts +75 -76
- package/src/parser/inline/autolink/url.ts +17 -18
- package/src/parser/inline/autolink.ts +24 -11
- package/src/parser/inline/bracket.test.ts +73 -74
- package/src/parser/inline/bracket.ts +88 -63
- package/src/parser/inline/code.test.ts +30 -31
- package/src/parser/inline/code.ts +6 -6
- package/src/parser/inline/deletion.test.ts +27 -28
- package/src/parser/inline/deletion.ts +5 -5
- package/src/parser/inline/emphasis.test.ts +39 -40
- package/src/parser/inline/emphasis.ts +5 -5
- package/src/parser/inline/emstrong.test.ts +101 -102
- package/src/parser/inline/emstrong.ts +103 -85
- package/src/parser/inline/extension/index.test.ts +91 -92
- package/src/parser/inline/extension/index.ts +17 -13
- package/src/parser/inline/extension/indexee.ts +4 -4
- package/src/parser/inline/extension/indexer.test.ts +23 -24
- package/src/parser/inline/extension/indexer.ts +6 -5
- package/src/parser/inline/extension/label.test.ts +32 -33
- package/src/parser/inline/extension/label.ts +14 -5
- package/src/parser/inline/extension/placeholder.test.ts +42 -43
- package/src/parser/inline/extension/placeholder.ts +8 -9
- package/src/parser/inline/html.test.ts +109 -109
- package/src/parser/inline/html.ts +27 -27
- package/src/parser/inline/htmlentity.test.ts +37 -38
- package/src/parser/inline/htmlentity.ts +6 -7
- package/src/parser/inline/insertion.test.ts +27 -28
- package/src/parser/inline/insertion.ts +5 -5
- package/src/parser/inline/italic.test.ts +55 -56
- package/src/parser/inline/italic.ts +5 -5
- package/src/parser/inline/link.test.ts +186 -187
- package/src/parser/inline/link.ts +29 -30
- package/src/parser/inline/mark.test.ts +31 -32
- package/src/parser/inline/mark.ts +6 -6
- package/src/parser/inline/math.test.ts +140 -141
- package/src/parser/inline/math.ts +7 -8
- package/src/parser/inline/media.test.ts +92 -93
- package/src/parser/inline/media.ts +35 -41
- package/src/parser/inline/reference.test.ts +111 -112
- package/src/parser/inline/reference.ts +61 -32
- package/src/parser/inline/remark.test.ts +49 -50
- package/src/parser/inline/remark.ts +13 -13
- package/src/parser/inline/ruby.test.ts +49 -50
- package/src/parser/inline/ruby.ts +100 -52
- package/src/parser/inline/shortmedia.test.ts +9 -10
- package/src/parser/inline/shortmedia.ts +11 -9
- package/src/parser/inline/strong.test.ts +36 -37
- package/src/parser/inline/strong.ts +5 -5
- package/src/parser/inline/template.test.ts +22 -23
- package/src/parser/inline/template.ts +17 -20
- package/src/parser/inline.test.ts +225 -226
- package/src/parser/inline.ts +68 -34
- package/src/parser/parser.ts +51 -0
- package/src/parser/repeat.ts +118 -91
- package/src/parser/segment.test.ts +0 -11
- package/src/parser/segment.ts +25 -28
- package/src/parser/source/escapable.test.ts +23 -24
- package/src/parser/source/escapable.ts +19 -20
- package/src/parser/source/line.test.ts +17 -18
- package/src/parser/source/line.ts +19 -24
- package/src/parser/source/str.ts +17 -10
- package/src/parser/source/text.test.ts +88 -89
- package/src/parser/source/text.ts +32 -62
- package/src/parser/source/unescapable.test.ts +23 -24
- package/src/parser/source/unescapable.ts +15 -16
- package/src/parser/source/whitespace.ts +36 -0
- package/src/parser/source.ts +1 -0
- package/src/parser/util.ts +1 -1
- package/src/parser/visibility.ts +37 -15
- package/src/processor/figure.test.ts +20 -20
- package/src/processor/figure.ts +18 -10
- package/src/processor/note.test.ts +13 -13
- package/src/processor/note.ts +4 -2
- package/src/renderer/render/media/pdf.ts +2 -2
- package/src/renderer/render/media/twitter.ts +2 -2
- package/src/renderer/render/media.test.ts +12 -12
- package/src/renderer/render.test.ts +11 -11
- package/src/util/info.test.ts +2 -2
- package/src/util/quote.test.ts +3 -3
- package/src/util/quote.ts +6 -5
- package/src/util/toc.test.ts +12 -12
- package/src/combinator/control/constraint/block.test.ts +0 -20
- package/src/combinator/control/constraint/block.ts +0 -28
- package/src/combinator/control/constraint/contract.ts +0 -27
- package/src/combinator/control/constraint/line.test.ts +0 -21
- package/src/combinator/control/constraint/line.ts +0 -42
- package/src/combinator/control/manipulation/clear.ts +0 -5
- package/src/combinator/control/manipulation/convert.ts +0 -22
- package/src/combinator/control/manipulation/duplicate.ts +0 -7
- package/src/combinator/control/manipulation/fence.ts +0 -54
- package/src/combinator/control/manipulation/indent.test.ts +0 -31
- package/src/combinator/control/manipulation/indent.ts +0 -39
- package/src/combinator/control/manipulation/lazy.ts +0 -8
- package/src/combinator/control/manipulation/match.ts +0 -27
- package/src/combinator/control/manipulation/recovery.ts +0 -18
- package/src/combinator/control/manipulation/reverse.ts +0 -8
- package/src/combinator/control/manipulation/scope.ts +0 -61
- package/src/combinator/control/manipulation/surround.ts +0 -223
- package/src/combinator/control/monad/bind.ts +0 -26
- package/src/combinator/control/monad/fmap.ts +0 -10
- package/src/combinator/data/parser/context.ts +0 -96
- package/src/combinator/data/parser/inits.ts +0 -20
- package/src/combinator/data/parser/sequence.test.ts +0 -33
- package/src/combinator/data/parser/sequence.ts +0 -20
- package/src/combinator/data/parser/some.test.ts +0 -37
- package/src/combinator/data/parser/subsequence.test.ts +0 -41
- package/src/combinator/data/parser/subsequence.ts +0 -13
- package/src/combinator/data/parser/tails.ts +0 -8
- package/src/combinator/data/parser/union.test.ts +0 -33
- package/src/combinator/data/parser/union.ts +0 -18
- package/src/combinator/data/parser.ts +0 -144
|
@@ -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,
|
|
1
|
+
import { Parser, Input } from '../parser';
|
|
2
2
|
|
|
3
|
-
export class List<N extends List.Node = List.Node,
|
|
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):
|
|
46
|
+
public unshift(node: N): this {
|
|
47
47
|
assert(!node.next && !node.prev);
|
|
48
48
|
if (++this.length === 1) {
|
|
49
|
-
|
|
49
|
+
this.head = this.last = node;
|
|
50
|
+
return this;
|
|
50
51
|
}
|
|
51
52
|
node.next = this.head;
|
|
52
|
-
|
|
53
|
+
this.head = this.head!.prev = node;
|
|
54
|
+
return this;
|
|
53
55
|
}
|
|
54
|
-
public push(node: N):
|
|
56
|
+
public push(node: N): this {
|
|
55
57
|
assert(!node.next && !node.prev);
|
|
56
58
|
if (++this.length === 1) {
|
|
57
|
-
|
|
59
|
+
this.head = this.last = node;
|
|
60
|
+
return this;
|
|
58
61
|
}
|
|
59
62
|
node.prev = this.last;
|
|
60
|
-
|
|
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;
|
|
@@ -139,3 +155,12 @@ export namespace List {
|
|
|
139
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
|
+
}
|