@cavelang/parser 0.32.3 → 0.34.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/README.md +12 -4
- package/dist/src/ast.d.ts +11 -3
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast.js.map +1 -1
- package/dist/src/document.d.ts +9 -0
- package/dist/src/document.d.ts.map +1 -1
- package/dist/src/document.js +48 -8
- package/dist/src/document.js.map +1 -1
- package/dist/src/token.d.ts +25 -2
- package/dist/src/token.d.ts.map +1 -1
- package/dist/src/token.js +34 -3
- package/dist/src/token.js.map +1 -1
- package/package.json +2 -2
- package/src/ast.ts +11 -3
- package/src/document.ts +51 -9
- package/src/token.ts +40 -3
package/README.md
CHANGED
|
@@ -29,7 +29,13 @@ parse('a USES b') // strict variant: throws on any diagnostic
|
|
|
29
29
|
|
|
30
30
|
1. **Split physical lines**, measure indentation (`document.ts`).
|
|
31
31
|
2. **Split off the comment** at the first `;` outside quotes/backticks
|
|
32
|
-
(`Token.splitComment`)
|
|
32
|
+
(`Token.splitComment`), and join it with the block of full-line `;`
|
|
33
|
+
comments directly above the line (§6.4): the block's lines and the
|
|
34
|
+
trailing comment, newline-separated, trailing last. Each line keeps its
|
|
35
|
+
text after `;` and one space (`Token.commentText`), trailing whitespace
|
|
36
|
+
trimmed, so indented text inside a comment survives. A blank line after
|
|
37
|
+
the block leaves it documentary; a `;@ tx` annotation (`Token.txOfLine`)
|
|
38
|
+
passes through. `Token.joinComment` is the inverse, used by emitters.
|
|
33
39
|
3. **Tokenize** into words / `"text"` literals / `` `code` `` literals
|
|
34
40
|
(`token.ts`, `@prelude/parser` combinators).
|
|
35
41
|
4. **Expand incomplete prefixes** (§8.5): prepend every incomplete ancestor's
|
|
@@ -106,10 +112,12 @@ examples and are tried in order:
|
|
|
106
112
|
only when its accumulated tokens are incomplete and it has indented
|
|
107
113
|
content. Complete lines retain the established qualifier, continuation,
|
|
108
114
|
and grouped-claim semantics. Prefixes compose recursively; blank and
|
|
109
|
-
full-line comments are transparent. A prefix's trailing comment
|
|
110
|
-
|
|
115
|
+
full-line comments are transparent. A prefix's trailing comment, and the
|
|
116
|
+
comment block directly above the header, are documentary and not
|
|
117
|
+
inherited, while a leaf comment — block included — remains persisted.
|
|
111
118
|
`raw` preserves the physical leaf and `expanded` carries the self-contained
|
|
112
|
-
logical
|
|
119
|
+
logical text used as stored `raw_line`: the prefix-expanded line, or the
|
|
120
|
+
comment block together with the line it belongs to.
|
|
113
121
|
|
|
114
122
|
## Tests
|
|
115
123
|
|
package/dist/src/ast.d.ts
CHANGED
|
@@ -19,7 +19,12 @@ export type Meta = {
|
|
|
19
19
|
readonly delta?: Value.t;
|
|
20
20
|
/** `(Nσ)` override (spec §7.2). */
|
|
21
21
|
readonly sigmaLevel?: number;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* The persisted comment (spec §6.4): the full-line `;` block directly
|
|
24
|
+
* above the line and its trailing `; comment`, joined with newlines,
|
|
25
|
+
* trailing last. Each line keeps its text after `;` and one space, so
|
|
26
|
+
* indentation inside the comment is preserved.
|
|
27
|
+
*/
|
|
23
28
|
readonly comment?: string;
|
|
24
29
|
};
|
|
25
30
|
/** Empty metadata. */
|
|
@@ -69,8 +74,11 @@ export type QualifierPayload = {
|
|
|
69
74
|
* A parsed line. `depth` is the indentation width in characters; `parent` is
|
|
70
75
|
* the index (into the document's `lines`) of the nearest less-indented
|
|
71
76
|
* materialized claim above (spec §8). `raw` is the physical line exactly as
|
|
72
|
-
* written. A
|
|
73
|
-
*
|
|
77
|
+
* written. A line whose logical text is more than its physical line also
|
|
78
|
+
* carries `expanded`: the self-contained line a shorthand leaf assembles
|
|
79
|
+
* from its incomplete prefix ancestors (§8.5), or the comment block above
|
|
80
|
+
* a line together with the line itself (§6.4). `comment` lines stay in the
|
|
81
|
+
* tree whether or not the line below absorbed them.
|
|
74
82
|
*/
|
|
75
83
|
export type Line = {
|
|
76
84
|
readonly kind: 'blank';
|
package/dist/src/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAEtE,sDAAsD;AACtD,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,CAAC,CAAC,EAAE,CAAA;IACvC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,EAAE,CAAA;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;IACxB,mCAAmC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"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"}
|
package/dist/src/ast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwBH,sBAAsB;AACtB,MAAM,CAAC,MAAM,SAAS,GACpB,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAA;AAkB/C,MAAM,CAAC,MAAM,aAAa,GACxB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA"}
|
package/dist/src/document.d.ts
CHANGED
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
* compose recursively. Complete lines never become prefixes, preserving the
|
|
19
19
|
* three existing indentation meanings above.
|
|
20
20
|
*
|
|
21
|
+
* A block of full-line `;` comments directly above a line is that line's
|
|
22
|
+
* comment (§6.4): the block's lines and the trailing `; comment` join with
|
|
23
|
+
* newlines, trailing last. Each line keeps everything after `;` and one
|
|
24
|
+
* space, so indented text inside a comment survives. A blank line after the block leaves it
|
|
25
|
+
* documentary — file headers stay out of the store — and a §28.4 `;@ tx`
|
|
26
|
+
* annotation is transparent to the block. A block above a prefix header
|
|
27
|
+
* is documentary like the header's trailing comment; a block above an
|
|
28
|
+
* invalid line is dropped with it.
|
|
29
|
+
*
|
|
21
30
|
* One ambiguity needs a tiebreak: `API NEEDS auth` starts with a token that
|
|
22
31
|
* is lexically verb-shaped. A two-token `VERB VERB` line is a continuation:
|
|
23
32
|
* it has a verb and object but no third token for a full claim's payload.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/document.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAA;AA6FpC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,GAAG,CAAC,QAkKjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,SAAS,GAAG,CAAC,IAAI,EAStD,CAAA"}
|
package/dist/src/document.js
CHANGED
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
* compose recursively. Complete lines never become prefixes, preserving the
|
|
19
19
|
* three existing indentation meanings above.
|
|
20
20
|
*
|
|
21
|
+
* A block of full-line `;` comments directly above a line is that line's
|
|
22
|
+
* comment (§6.4): the block's lines and the trailing `; comment` join with
|
|
23
|
+
* newlines, trailing last. Each line keeps everything after `;` and one
|
|
24
|
+
* space, so indented text inside a comment survives. A blank line after the block leaves it
|
|
25
|
+
* documentary — file headers stay out of the store — and a §28.4 `;@ tx`
|
|
26
|
+
* annotation is transparent to the block. A block above a prefix header
|
|
27
|
+
* is documentary like the header's trailing comment; a block above an
|
|
28
|
+
* invalid line is dropped with it.
|
|
29
|
+
*
|
|
21
30
|
* One ambiguity needs a tiebreak: `API NEEDS auth` starts with a token that
|
|
22
31
|
* is lexically verb-shaped. A two-token `VERB VERB` line is a continuation:
|
|
23
32
|
* it has a verb and object but no third token for a full claim's payload.
|
|
@@ -80,7 +89,23 @@ const hasIndentedContent = (rawLines, at, depth) => {
|
|
|
80
89
|
}
|
|
81
90
|
return false;
|
|
82
91
|
};
|
|
83
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Joins a comment block and a trailing comment into one persisted comment
|
|
94
|
+
* (§6.4), trailing last. Empty lines at either end are dropped, so a block
|
|
95
|
+
* of bare `;` lines is no comment at all; interior empty lines survive as
|
|
96
|
+
* paragraph breaks.
|
|
97
|
+
*/
|
|
98
|
+
const combineComment = (leading, trailing) => {
|
|
99
|
+
const lines = [...leading, ...trailing === undefined ? [] : [trailing]];
|
|
100
|
+
while (lines[0] === '') {
|
|
101
|
+
lines.shift();
|
|
102
|
+
}
|
|
103
|
+
while (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
104
|
+
lines.pop();
|
|
105
|
+
}
|
|
106
|
+
return lines.length === 0 ? undefined : lines.join('\n');
|
|
107
|
+
};
|
|
108
|
+
const emptyBlock = () => ({ texts: [], raws: [] });
|
|
84
109
|
/**
|
|
85
110
|
* Parses a CAVE document. Never throws; problems surface as diagnostics and
|
|
86
111
|
* `invalid` lines.
|
|
@@ -93,6 +118,15 @@ export const parseDocument = (input) => {
|
|
|
93
118
|
const problem = (line, raw, message) => {
|
|
94
119
|
diagnostics.push({ line, message, raw });
|
|
95
120
|
};
|
|
121
|
+
/** The comment block accumulating above the next line (§6.4). */
|
|
122
|
+
let block = emptyBlock();
|
|
123
|
+
const commentLine = (lineNo, raw, text) => {
|
|
124
|
+
lines.push({ kind: 'comment', line: lineNo, raw, text });
|
|
125
|
+
if (Token.txOfLine(raw) === undefined) {
|
|
126
|
+
block.texts.push(text);
|
|
127
|
+
block.raws.push(raw);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
96
130
|
rawLines.forEach((raw, at) => {
|
|
97
131
|
const lineNo = at + 1;
|
|
98
132
|
const { depth, rest, tabs } = indentOf(raw);
|
|
@@ -101,19 +135,23 @@ export const parseDocument = (input) => {
|
|
|
101
135
|
}
|
|
102
136
|
if (rest === '') {
|
|
103
137
|
lines.push({ kind: 'blank', line: lineNo, raw });
|
|
138
|
+
block = emptyBlock();
|
|
104
139
|
return;
|
|
105
140
|
}
|
|
106
141
|
if (rest.startsWith(';')) {
|
|
107
|
-
|
|
142
|
+
commentLine(lineNo, raw, Token.commentText(rest.slice(1)));
|
|
108
143
|
return;
|
|
109
144
|
}
|
|
110
145
|
const split = Token.splitComment(rest);
|
|
111
146
|
const ownHead = split.head.trim();
|
|
112
147
|
const ownTokens = Token.tokenize(ownHead);
|
|
113
148
|
if (ownTokens.length === 0) {
|
|
114
|
-
|
|
149
|
+
commentLine(lineNo, raw, split.comment ?? '');
|
|
115
150
|
return;
|
|
116
151
|
}
|
|
152
|
+
const leading = block;
|
|
153
|
+
block = emptyBlock();
|
|
154
|
+
const comment = combineComment(leading.texts, split.comment);
|
|
117
155
|
while (stack.length > 0 && stack[stack.length - 1].depth >= depth) {
|
|
118
156
|
stack.pop();
|
|
119
157
|
}
|
|
@@ -127,7 +165,9 @@ export const parseDocument = (input) => {
|
|
|
127
165
|
`${inherited.head} ${ownHead}`;
|
|
128
166
|
const semanticDepth = inherited?.semanticDepth ?? depth;
|
|
129
167
|
const parent = inherited === undefined ? frame?.index : inherited.parent;
|
|
130
|
-
const expanded = inherited
|
|
168
|
+
const expanded = inherited !== undefined ?
|
|
169
|
+
Token.joinComment(head, comment) :
|
|
170
|
+
leading.raws.length > 0 ? [...leading.raws, raw].join('\n') : undefined;
|
|
131
171
|
const asPrefix = (message) => {
|
|
132
172
|
if (!hasIndentedContent(rawLines, at, depth)) {
|
|
133
173
|
problem(lineNo, raw, message);
|
|
@@ -143,7 +183,7 @@ export const parseDocument = (input) => {
|
|
|
143
183
|
depth,
|
|
144
184
|
expanded: head,
|
|
145
185
|
...parent === undefined ? {} : { parent },
|
|
146
|
-
...
|
|
186
|
+
...comment === undefined ? {} : { comment }
|
|
147
187
|
});
|
|
148
188
|
stack.push({ index, depth, prefix });
|
|
149
189
|
return true;
|
|
@@ -168,7 +208,7 @@ export const parseDocument = (input) => {
|
|
|
168
208
|
};
|
|
169
209
|
switch (kind) {
|
|
170
210
|
case 'claim': {
|
|
171
|
-
const result = Line.parseClaim(tokens,
|
|
211
|
+
const result = Line.parseClaim(tokens, comment);
|
|
172
212
|
if (!result.ok) {
|
|
173
213
|
asPrefix(result.message);
|
|
174
214
|
return;
|
|
@@ -185,7 +225,7 @@ export const parseDocument = (input) => {
|
|
|
185
225
|
return;
|
|
186
226
|
}
|
|
187
227
|
case 'continuation': {
|
|
188
|
-
const result = Line.parseBody(tokens,
|
|
228
|
+
const result = Line.parseBody(tokens, comment);
|
|
189
229
|
if (!result.ok) {
|
|
190
230
|
asPrefix(result.message);
|
|
191
231
|
return;
|
|
@@ -203,7 +243,7 @@ export const parseDocument = (input) => {
|
|
|
203
243
|
}
|
|
204
244
|
case 'qualifier': {
|
|
205
245
|
const qualifier = tokens[0].text;
|
|
206
|
-
const result = Line.parseQualifierPayload(tokens.slice(1),
|
|
246
|
+
const result = Line.parseQualifierPayload(tokens.slice(1), comment);
|
|
207
247
|
if (!result.ok) {
|
|
208
248
|
asPrefix(result.message);
|
|
209
249
|
return;
|
package/dist/src/document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/document.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/document.ts"],"names":[],"mappings":"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"}
|
package/dist/src/token.d.ts
CHANGED
|
@@ -25,13 +25,36 @@ export declare const text: (value: string) => Token;
|
|
|
25
25
|
export declare const code: (value: string) => Token;
|
|
26
26
|
/** @returns tokens of a single line. Total — any input tokenizes. */
|
|
27
27
|
export declare const tokenize: (line: string) => Token[];
|
|
28
|
+
/**
|
|
29
|
+
* The text of a comment after its `;` (spec §6.4): exactly one following
|
|
30
|
+
* space is dropped and trailing whitespace is trimmed, so the rest of the
|
|
31
|
+
* line — including any indentation the author wrote — survives verbatim.
|
|
32
|
+
* That is what lets a comment carry indented text such as code.
|
|
33
|
+
*/
|
|
34
|
+
export declare const commentText: (afterSemicolon: string) => string;
|
|
28
35
|
/**
|
|
29
36
|
* Splits a line at the first `;` that sits outside quotes and backticks
|
|
30
|
-
* (spec §6.4). @returns the head and the
|
|
31
|
-
* when there is no comment or it is empty.
|
|
37
|
+
* (spec §6.4). @returns the head and the comment text ({@link commentText}),
|
|
38
|
+
* `undefined` when there is no comment or it is empty.
|
|
32
39
|
*/
|
|
33
40
|
export declare const splitComment: (line: string) => {
|
|
34
41
|
head: string;
|
|
35
42
|
comment?: string;
|
|
36
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Inverse of {@link splitComment} for a persisted comment (spec §6.4): a
|
|
46
|
+
* comment is one or more lines, and every line but the last is rendered as a
|
|
47
|
+
* full-line `;` comment directly above the claim while the last rides on the
|
|
48
|
+
* claim line itself. Each line is written as `; ` plus its text, so the
|
|
49
|
+
* text's own indentation survives a round trip; an empty line renders as a
|
|
50
|
+
* bare `;`.
|
|
51
|
+
*/
|
|
52
|
+
export declare const joinComment: (head: string, comment?: string) => string;
|
|
53
|
+
/**
|
|
54
|
+
* @returns the transaction id carried by a physical line when it is a spec
|
|
55
|
+
* §28.4 annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
56
|
+
* caller validates the id shape. An annotation is never comment prose: it
|
|
57
|
+
* neither joins nor interrupts the comment block above a claim (§6.4).
|
|
58
|
+
*/
|
|
59
|
+
export declare const txOfLine: (raw: string) => undefined | string;
|
|
37
60
|
//# sourceMappingURL=token.d.ts.map
|
package/dist/src/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,MAAM,MAAM,CAAC,GAAG,KAAK,CAAA;AAErB,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,KACV,CAAA;AAE1B,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,KAAG,KACJ,CAAA;AAEjC,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,KAAG,KACJ,CAAA;AAoBjC,qEAAqE;AACrE,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,KAAK,EAClB,CAAA;AAE3B;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAsB3E,CAAA"}
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,MAAM,MAAM,CAAC,GAAG,KAAK,CAAA;AAErB,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,KACV,CAAA;AAE1B,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,KAAG,KACJ,CAAA;AAEjC,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,KAAG,KACJ,CAAA;AAoBjC,qEAAqE;AACrE,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,KAAK,EAClB,CAAA;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,gBAAgB,MAAM,KAAG,MACkC,CAAA;AAEvF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAsB3E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAO5D,CAAA;AAID;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,KAAG,SAAS,GAAG,MAC1B,CAAA"}
|
package/dist/src/token.js
CHANGED
|
@@ -20,10 +20,17 @@ const anyToken = P.first(codeToken, textToken, wordToken);
|
|
|
20
20
|
const lineTokens = P.map(P.seq(P.star(P.map(P.seq(P.ws0, anyToken), ([, token]) => token)), P.ws0), ([tokens]) => tokens);
|
|
21
21
|
/** @returns tokens of a single line. Total — any input tokenizes. */
|
|
22
22
|
export const tokenize = (line) => P.parse(lineTokens, line);
|
|
23
|
+
/**
|
|
24
|
+
* The text of a comment after its `;` (spec §6.4): exactly one following
|
|
25
|
+
* space is dropped and trailing whitespace is trimmed, so the rest of the
|
|
26
|
+
* line — including any indentation the author wrote — survives verbatim.
|
|
27
|
+
* That is what lets a comment carry indented text such as code.
|
|
28
|
+
*/
|
|
29
|
+
export const commentText = (afterSemicolon) => (afterSemicolon.startsWith(' ') ? afterSemicolon.slice(1) : afterSemicolon).trimEnd();
|
|
23
30
|
/**
|
|
24
31
|
* Splits a line at the first `;` that sits outside quotes and backticks
|
|
25
|
-
* (spec §6.4). @returns the head and the
|
|
26
|
-
* when there is no comment or it is empty.
|
|
32
|
+
* (spec §6.4). @returns the head and the comment text ({@link commentText}),
|
|
33
|
+
* `undefined` when there is no comment or it is empty.
|
|
27
34
|
*/
|
|
28
35
|
export const splitComment = (line) => {
|
|
29
36
|
let quote;
|
|
@@ -40,7 +47,7 @@ export const splitComment = (line) => {
|
|
|
40
47
|
continue;
|
|
41
48
|
}
|
|
42
49
|
if (char === ';') {
|
|
43
|
-
const comment = line.slice(i + 1)
|
|
50
|
+
const comment = commentText(line.slice(i + 1));
|
|
44
51
|
return comment === '' ?
|
|
45
52
|
{ head: line.slice(0, i) } :
|
|
46
53
|
{ head: line.slice(0, i), comment };
|
|
@@ -48,4 +55,28 @@ export const splitComment = (line) => {
|
|
|
48
55
|
}
|
|
49
56
|
return { head: line };
|
|
50
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Inverse of {@link splitComment} for a persisted comment (spec §6.4): a
|
|
60
|
+
* comment is one or more lines, and every line but the last is rendered as a
|
|
61
|
+
* full-line `;` comment directly above the claim while the last rides on the
|
|
62
|
+
* claim line itself. Each line is written as `; ` plus its text, so the
|
|
63
|
+
* text's own indentation survives a round trip; an empty line renders as a
|
|
64
|
+
* bare `;`.
|
|
65
|
+
*/
|
|
66
|
+
export const joinComment = (head, comment) => {
|
|
67
|
+
if (comment === undefined) {
|
|
68
|
+
return head;
|
|
69
|
+
}
|
|
70
|
+
const lines = comment.split('\n');
|
|
71
|
+
const last = lines.pop();
|
|
72
|
+
return [...lines.map(line => line === '' ? ';' : `; ${line}`), `${head} ; ${last}`].join('\n');
|
|
73
|
+
};
|
|
74
|
+
const txLineRe = /^\s*;@\s+(\S+)\s*$/;
|
|
75
|
+
/**
|
|
76
|
+
* @returns the transaction id carried by a physical line when it is a spec
|
|
77
|
+
* §28.4 annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
78
|
+
* caller validates the id shape. An annotation is never comment prose: it
|
|
79
|
+
* neither joins nor interrupts the comment block above a claim (§6.4).
|
|
80
|
+
*/
|
|
81
|
+
export const txOfLine = (raw) => txLineRe.exec(raw)?.[1];
|
|
51
82
|
//# sourceMappingURL=token.js.map
|
package/dist/src/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cavelang/parser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CAVE text to AST parser built on @prelude/parser combinators.",
|
|
6
6
|
"keywords": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@prelude/parser": "^8.0.1",
|
|
47
|
-
"@cavelang/core": "0.
|
|
47
|
+
"@cavelang/core": "0.34.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc -b",
|
package/src/ast.ts
CHANGED
|
@@ -21,7 +21,12 @@ export type Meta = {
|
|
|
21
21
|
readonly delta?: Value.t
|
|
22
22
|
/** `(Nσ)` override (spec §7.2). */
|
|
23
23
|
readonly sigmaLevel?: number
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The persisted comment (spec §6.4): the full-line `;` block directly
|
|
26
|
+
* above the line and its trailing `; comment`, joined with newlines,
|
|
27
|
+
* trailing last. Each line keeps its text after `;` and one space, so
|
|
28
|
+
* indentation inside the comment is preserved.
|
|
29
|
+
*/
|
|
25
30
|
readonly comment?: string
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -67,8 +72,11 @@ export type QualifierPayload =
|
|
|
67
72
|
* A parsed line. `depth` is the indentation width in characters; `parent` is
|
|
68
73
|
* the index (into the document's `lines`) of the nearest less-indented
|
|
69
74
|
* materialized claim above (spec §8). `raw` is the physical line exactly as
|
|
70
|
-
* written. A
|
|
71
|
-
*
|
|
75
|
+
* written. A line whose logical text is more than its physical line also
|
|
76
|
+
* carries `expanded`: the self-contained line a shorthand leaf assembles
|
|
77
|
+
* from its incomplete prefix ancestors (§8.5), or the comment block above
|
|
78
|
+
* a line together with the line itself (§6.4). `comment` lines stay in the
|
|
79
|
+
* tree whether or not the line below absorbed them.
|
|
72
80
|
*/
|
|
73
81
|
export type Line =
|
|
74
82
|
| { readonly kind: 'blank', readonly line: number, readonly raw: string }
|
package/src/document.ts
CHANGED
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
* compose recursively. Complete lines never become prefixes, preserving the
|
|
19
19
|
* three existing indentation meanings above.
|
|
20
20
|
*
|
|
21
|
+
* A block of full-line `;` comments directly above a line is that line's
|
|
22
|
+
* comment (§6.4): the block's lines and the trailing `; comment` join with
|
|
23
|
+
* newlines, trailing last. Each line keeps everything after `;` and one
|
|
24
|
+
* space, so indented text inside a comment survives. A blank line after the block leaves it
|
|
25
|
+
* documentary — file headers stay out of the store — and a §28.4 `;@ tx`
|
|
26
|
+
* annotation is transparent to the block. A block above a prefix header
|
|
27
|
+
* is documentary like the header's trailing comment; a block above an
|
|
28
|
+
* invalid line is dropped with it.
|
|
29
|
+
*
|
|
21
30
|
* One ambiguity needs a tiebreak: `API NEEDS auth` starts with a token that
|
|
22
31
|
* is lexically verb-shaped. A two-token `VERB VERB` line is a continuation:
|
|
23
32
|
* it has a verb and object but no third token for a full claim's payload.
|
|
@@ -101,8 +110,26 @@ const hasIndentedContent = (rawLines: readonly string[], at: number, depth: numb
|
|
|
101
110
|
return false
|
|
102
111
|
}
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Joins a comment block and a trailing comment into one persisted comment
|
|
115
|
+
* (§6.4), trailing last. Empty lines at either end are dropped, so a block
|
|
116
|
+
* of bare `;` lines is no comment at all; interior empty lines survive as
|
|
117
|
+
* paragraph breaks.
|
|
118
|
+
*/
|
|
119
|
+
const combineComment = (leading: readonly string[], trailing?: string): undefined | string => {
|
|
120
|
+
const lines = [...leading, ...trailing === undefined ? [] : [trailing]]
|
|
121
|
+
while (lines[0] === '') {
|
|
122
|
+
lines.shift()
|
|
123
|
+
}
|
|
124
|
+
while (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
125
|
+
lines.pop()
|
|
126
|
+
}
|
|
127
|
+
return lines.length === 0 ? undefined : lines.join('\n')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type CommentBlock = { readonly texts: string[], readonly raws: string[] }
|
|
131
|
+
|
|
132
|
+
const emptyBlock = (): CommentBlock => ({ texts: [], raws: [] })
|
|
106
133
|
|
|
107
134
|
/**
|
|
108
135
|
* Parses a CAVE document. Never throws; problems surface as diagnostics and
|
|
@@ -116,6 +143,15 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
116
143
|
const problem = (line: number, raw: string, message: string): void => {
|
|
117
144
|
diagnostics.push({ line, message, raw })
|
|
118
145
|
}
|
|
146
|
+
/** The comment block accumulating above the next line (§6.4). */
|
|
147
|
+
let block = emptyBlock()
|
|
148
|
+
const commentLine = (lineNo: number, raw: string, text: string): void => {
|
|
149
|
+
lines.push({ kind: 'comment', line: lineNo, raw, text })
|
|
150
|
+
if (Token.txOfLine(raw) === undefined) {
|
|
151
|
+
block.texts.push(text)
|
|
152
|
+
block.raws.push(raw)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
119
155
|
rawLines.forEach((raw, at) => {
|
|
120
156
|
const lineNo = at + 1
|
|
121
157
|
const { depth, rest, tabs } = indentOf(raw)
|
|
@@ -124,19 +160,23 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
124
160
|
}
|
|
125
161
|
if (rest === '') {
|
|
126
162
|
lines.push({ kind: 'blank', line: lineNo, raw })
|
|
163
|
+
block = emptyBlock()
|
|
127
164
|
return
|
|
128
165
|
}
|
|
129
166
|
if (rest.startsWith(';')) {
|
|
130
|
-
|
|
167
|
+
commentLine(lineNo, raw, Token.commentText(rest.slice(1)))
|
|
131
168
|
return
|
|
132
169
|
}
|
|
133
170
|
const split = Token.splitComment(rest)
|
|
134
171
|
const ownHead = split.head.trim()
|
|
135
172
|
const ownTokens = Token.tokenize(ownHead)
|
|
136
173
|
if (ownTokens.length === 0) {
|
|
137
|
-
|
|
174
|
+
commentLine(lineNo, raw, split.comment ?? '')
|
|
138
175
|
return
|
|
139
176
|
}
|
|
177
|
+
const leading = block
|
|
178
|
+
block = emptyBlock()
|
|
179
|
+
const comment = combineComment(leading.texts, split.comment)
|
|
140
180
|
while (stack.length > 0 && stack[stack.length - 1]!.depth >= depth) {
|
|
141
181
|
stack.pop()
|
|
142
182
|
}
|
|
@@ -150,7 +190,9 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
150
190
|
`${inherited.head} ${ownHead}`
|
|
151
191
|
const semanticDepth = inherited?.semanticDepth ?? depth
|
|
152
192
|
const parent = inherited === undefined ? frame?.index : inherited.parent
|
|
153
|
-
const expanded = inherited
|
|
193
|
+
const expanded = inherited !== undefined ?
|
|
194
|
+
Token.joinComment(head, comment) :
|
|
195
|
+
leading.raws.length > 0 ? [...leading.raws, raw].join('\n') : undefined
|
|
154
196
|
const asPrefix = (message: string): boolean => {
|
|
155
197
|
if (!hasIndentedContent(rawLines, at, depth)) {
|
|
156
198
|
problem(lineNo, raw, message)
|
|
@@ -166,7 +208,7 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
166
208
|
depth,
|
|
167
209
|
expanded: head,
|
|
168
210
|
...parent === undefined ? {} : { parent },
|
|
169
|
-
...
|
|
211
|
+
...comment === undefined ? {} : { comment }
|
|
170
212
|
})
|
|
171
213
|
stack.push({ index, depth, prefix })
|
|
172
214
|
return true
|
|
@@ -191,7 +233,7 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
191
233
|
}
|
|
192
234
|
switch (kind) {
|
|
193
235
|
case 'claim': {
|
|
194
|
-
const result = Line.parseClaim(tokens,
|
|
236
|
+
const result = Line.parseClaim(tokens, comment)
|
|
195
237
|
if (!result.ok) {
|
|
196
238
|
asPrefix(result.message)
|
|
197
239
|
return
|
|
@@ -211,7 +253,7 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
211
253
|
return
|
|
212
254
|
}
|
|
213
255
|
case 'continuation': {
|
|
214
|
-
const result = Line.parseBody(tokens,
|
|
256
|
+
const result = Line.parseBody(tokens, comment)
|
|
215
257
|
if (!result.ok) {
|
|
216
258
|
asPrefix(result.message)
|
|
217
259
|
return
|
|
@@ -232,7 +274,7 @@ export const parseDocument = (input: string): Ast.Document => {
|
|
|
232
274
|
}
|
|
233
275
|
case 'qualifier': {
|
|
234
276
|
const qualifier = (tokens[0] as { text: string }).text as Verb.Qualifier
|
|
235
|
-
const result = Line.parseQualifierPayload(tokens.slice(1),
|
|
277
|
+
const result = Line.parseQualifierPayload(tokens.slice(1), comment)
|
|
236
278
|
if (!result.ok) {
|
|
237
279
|
asPrefix(result.message)
|
|
238
280
|
return
|
package/src/token.ts
CHANGED
|
@@ -50,10 +50,19 @@ const lineTokens: P.Parser<Token[]> =
|
|
|
50
50
|
export const tokenize = (line: string): Token[] =>
|
|
51
51
|
P.parse(lineTokens, line)
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* The text of a comment after its `;` (spec §6.4): exactly one following
|
|
55
|
+
* space is dropped and trailing whitespace is trimmed, so the rest of the
|
|
56
|
+
* line — including any indentation the author wrote — survives verbatim.
|
|
57
|
+
* That is what lets a comment carry indented text such as code.
|
|
58
|
+
*/
|
|
59
|
+
export const commentText = (afterSemicolon: string): string =>
|
|
60
|
+
(afterSemicolon.startsWith(' ') ? afterSemicolon.slice(1) : afterSemicolon).trimEnd()
|
|
61
|
+
|
|
53
62
|
/**
|
|
54
63
|
* Splits a line at the first `;` that sits outside quotes and backticks
|
|
55
|
-
* (spec §6.4). @returns the head and the
|
|
56
|
-
* when there is no comment or it is empty.
|
|
64
|
+
* (spec §6.4). @returns the head and the comment text ({@link commentText}),
|
|
65
|
+
* `undefined` when there is no comment or it is empty.
|
|
57
66
|
*/
|
|
58
67
|
export const splitComment = (line: string): { head: string, comment?: string } => {
|
|
59
68
|
let quote: undefined | string
|
|
@@ -70,7 +79,7 @@ export const splitComment = (line: string): { head: string, comment?: string } =
|
|
|
70
79
|
continue
|
|
71
80
|
}
|
|
72
81
|
if (char === ';') {
|
|
73
|
-
const comment = line.slice(i + 1)
|
|
82
|
+
const comment = commentText(line.slice(i + 1))
|
|
74
83
|
return comment === '' ?
|
|
75
84
|
{ head: line.slice(0, i) } :
|
|
76
85
|
{ head: line.slice(0, i), comment }
|
|
@@ -78,3 +87,31 @@ export const splitComment = (line: string): { head: string, comment?: string } =
|
|
|
78
87
|
}
|
|
79
88
|
return { head: line }
|
|
80
89
|
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Inverse of {@link splitComment} for a persisted comment (spec §6.4): a
|
|
93
|
+
* comment is one or more lines, and every line but the last is rendered as a
|
|
94
|
+
* full-line `;` comment directly above the claim while the last rides on the
|
|
95
|
+
* claim line itself. Each line is written as `; ` plus its text, so the
|
|
96
|
+
* text's own indentation survives a round trip; an empty line renders as a
|
|
97
|
+
* bare `;`.
|
|
98
|
+
*/
|
|
99
|
+
export const joinComment = (head: string, comment?: string): string => {
|
|
100
|
+
if (comment === undefined) {
|
|
101
|
+
return head
|
|
102
|
+
}
|
|
103
|
+
const lines = comment.split('\n')
|
|
104
|
+
const last = lines.pop()!
|
|
105
|
+
return [...lines.map(line => line === '' ? ';' : `; ${line}`), `${head} ; ${last}`].join('\n')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const txLineRe = /^\s*;@\s+(\S+)\s*$/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @returns the transaction id carried by a physical line when it is a spec
|
|
112
|
+
* §28.4 annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
113
|
+
* caller validates the id shape. An annotation is never comment prose: it
|
|
114
|
+
* neither joins nor interrupts the comment block above a claim (§6.4).
|
|
115
|
+
*/
|
|
116
|
+
export const txOfLine = (raw: string): undefined | string =>
|
|
117
|
+
txLineRe.exec(raw)?.[1]
|