@inventarch/language 0.0.0-stage → 1.0.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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +33 -2
- package/SPEC.md +225 -0
- package/dist/ast.d.ts +114 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +2 -0
- package/dist/ast.js.map +1 -0
- package/dist/compile/compile.d.ts +82 -0
- package/dist/compile/compile.d.ts.map +1 -0
- package/dist/compile/compile.js +249 -0
- package/dist/compile/compile.js.map +1 -0
- package/dist/compile/index.d.ts +6 -0
- package/dist/compile/index.d.ts.map +1 -0
- package/dist/compile/index.js +4 -0
- package/dist/compile/index.js.map +1 -0
- package/dist/compile/spellings.d.ts +7 -0
- package/dist/compile/spellings.d.ts.map +1 -0
- package/dist/compile/spellings.js +47 -0
- package/dist/compile/spellings.js.map +1 -0
- package/dist/compile/values.d.ts +32 -0
- package/dist/compile/values.d.ts.map +1 -0
- package/dist/compile/values.js +48 -0
- package/dist/compile/values.js.map +1 -0
- package/dist/diagnostics.d.ts +22 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +71 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/editor/index.d.ts +49 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +155 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/fold.d.ts +8 -0
- package/dist/fold.d.ts.map +1 -0
- package/dist/fold.js +26 -0
- package/dist/fold.js.map +1 -0
- package/dist/formatter.d.ts +10 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +108 -0
- package/dist/formatter.js.map +1 -0
- package/dist/identity.d.ts +31 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +64 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel.generated.d.ts +99 -0
- package/dist/kernel.generated.d.ts.map +1 -0
- package/dist/kernel.generated.js +422 -0
- package/dist/kernel.generated.js.map +1 -0
- package/dist/parser/index.d.ts +5 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parser.d.ts +11 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +297 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/values.d.ts +24 -0
- package/dist/parser/values.d.ts.map +1 -0
- package/dist/parser/values.js +284 -0
- package/dist/parser/values.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +21 -0
- package/dist/paths.js.map +1 -0
- package/dist/references.d.ts +15 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +40 -0
- package/dist/references.js.map +1 -0
- package/dist/registry/consent.d.ts +11 -0
- package/dist/registry/consent.d.ts.map +1 -0
- package/dist/registry/consent.js +31 -0
- package/dist/registry/consent.js.map +1 -0
- package/dist/registry/extract.d.ts +11 -0
- package/dist/registry/extract.d.ts.map +1 -0
- package/dist/registry/extract.js +275 -0
- package/dist/registry/extract.js.map +1 -0
- package/dist/registry/fields.d.ts +14 -0
- package/dist/registry/fields.d.ts.map +1 -0
- package/dist/registry/fields.js +30 -0
- package/dist/registry/fields.js.map +1 -0
- package/dist/registry/floor.d.ts +17 -0
- package/dist/registry/floor.d.ts.map +1 -0
- package/dist/registry/floor.js +42 -0
- package/dist/registry/floor.js.map +1 -0
- package/dist/registry/index.d.ts +19 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +80 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/merge.d.ts +32 -0
- package/dist/registry/merge.d.ts.map +1 -0
- package/dist/registry/merge.js +84 -0
- package/dist/registry/merge.js.map +1 -0
- package/dist/registry/order.d.ts +12 -0
- package/dist/registry/order.d.ts.map +1 -0
- package/dist/registry/order.js +134 -0
- package/dist/registry/order.js.map +1 -0
- package/dist/registry/records.d.ts +14 -0
- package/dist/registry/records.d.ts.map +1 -0
- package/dist/registry/records.js +64 -0
- package/dist/registry/records.js.map +1 -0
- package/dist/registry/schemas.d.ts +20 -0
- package/dist/registry/schemas.d.ts.map +1 -0
- package/dist/registry/schemas.js +282 -0
- package/dist/registry/schemas.js.map +1 -0
- package/dist/registry/types.d.ts +130 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +2 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/scanner/index.d.ts +16 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +78 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/lines.d.ts +46 -0
- package/dist/scanner/lines.d.ts.map +1 -0
- package/dist/scanner/lines.js +210 -0
- package/dist/scanner/lines.js.map +1 -0
- package/dist/scanner/tokenize.d.ts +9 -0
- package/dist/scanner/tokenize.d.ts.map +1 -0
- package/dist/scanner/tokenize.js +125 -0
- package/dist/scanner/tokenize.js.map +1 -0
- package/dist/scanner/tokens.d.ts +52 -0
- package/dist/scanner/tokens.d.ts.map +1 -0
- package/dist/scanner/tokens.js +2 -0
- package/dist/scanner/tokens.js.map +1 -0
- package/dist/semantic/cases.d.ts +12 -0
- package/dist/semantic/cases.d.ts.map +1 -0
- package/dist/semantic/cases.js +81 -0
- package/dist/semantic/cases.js.map +1 -0
- package/dist/semantic/cells.d.ts +9 -0
- package/dist/semantic/cells.d.ts.map +1 -0
- package/dist/semantic/cells.js +120 -0
- package/dist/semantic/cells.js.map +1 -0
- package/dist/semantic/conditions.d.ts +22 -0
- package/dist/semantic/conditions.d.ts.map +1 -0
- package/dist/semantic/conditions.js +54 -0
- package/dist/semantic/conditions.js.map +1 -0
- package/dist/semantic/contracts.d.ts +11 -0
- package/dist/semantic/contracts.d.ts.map +1 -0
- package/dist/semantic/contracts.js +75 -0
- package/dist/semantic/contracts.js.map +1 -0
- package/dist/semantic/edges.d.ts +19 -0
- package/dist/semantic/edges.d.ts.map +1 -0
- package/dist/semantic/edges.js +129 -0
- package/dist/semantic/edges.js.map +1 -0
- package/dist/semantic/placement.d.ts +6 -0
- package/dist/semantic/placement.d.ts.map +1 -0
- package/dist/semantic/placement.js +47 -0
- package/dist/semantic/placement.js.map +1 -0
- package/dist/semantic/requirements.d.ts +14 -0
- package/dist/semantic/requirements.d.ts.map +1 -0
- package/dist/semantic/requirements.js +32 -0
- package/dist/semantic/requirements.js.map +1 -0
- package/dist/semantic/resolve.d.ts +23 -0
- package/dist/semantic/resolve.d.ts.map +1 -0
- package/dist/semantic/resolve.js +62 -0
- package/dist/semantic/resolve.js.map +1 -0
- package/dist/semantic/selectors.d.ts +10 -0
- package/dist/semantic/selectors.d.ts.map +1 -0
- package/dist/semantic/selectors.js +33 -0
- package/dist/semantic/selectors.js.map +1 -0
- package/dist/semantic/types.d.ts +56 -0
- package/dist/semantic/types.d.ts.map +1 -0
- package/dist/semantic/types.js +11 -0
- package/dist/semantic/types.js.map +1 -0
- package/dist/semantic/variants.d.ts +10 -0
- package/dist/semantic/variants.d.ts.map +1 -0
- package/dist/semantic/variants.js +63 -0
- package/dist/semantic/variants.js.map +1 -0
- package/dist/semantic/vocabulary.d.ts +12 -0
- package/dist/semantic/vocabulary.d.ts.map +1 -0
- package/dist/semantic/vocabulary.js +33 -0
- package/dist/semantic/vocabulary.js.map +1 -0
- package/dist/taxonomy.d.ts +51 -0
- package/dist/taxonomy.d.ts.map +1 -0
- package/dist/taxonomy.js +42 -0
- package/dist/taxonomy.js.map +1 -0
- package/package.json +220 -3
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { diag } from '../diagnostics.js';
|
|
2
|
+
/** Exactly `#! ia <version>` with single spaces; the version's validity is the parser's judgement, not the scanner's. */
|
|
3
|
+
const PRAGMA_RE = /^#! ia (\S+)\s*$/;
|
|
4
|
+
/** A `#` begins a comment when preceded by one of these (or when it is the first character). */
|
|
5
|
+
const COMMENT_PRECEDERS = new Set([' ', '\t', '"', ']', ',']);
|
|
6
|
+
/**
|
|
7
|
+
* One quote-aware pass over a line, or over a joined span. This is the only place in the
|
|
8
|
+
* package that knows how `"`, `"""`, `[`, `]` and `#` interact.
|
|
9
|
+
*/
|
|
10
|
+
export function walk(text) {
|
|
11
|
+
let inString = false;
|
|
12
|
+
let inProse = false;
|
|
13
|
+
let bracketDelta = 0;
|
|
14
|
+
let commentAt = -1;
|
|
15
|
+
for (let i = 0; i < text.length; i++) {
|
|
16
|
+
const ch = text[i] ?? '';
|
|
17
|
+
if (inProse) {
|
|
18
|
+
if (text.startsWith('"""', i)) {
|
|
19
|
+
inProse = false;
|
|
20
|
+
i += 2;
|
|
21
|
+
}
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (inString) {
|
|
25
|
+
if (ch === '\\') {
|
|
26
|
+
i++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (ch === '"')
|
|
30
|
+
inString = false;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (text.startsWith('"""', i)) {
|
|
34
|
+
inProse = true;
|
|
35
|
+
i += 2;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (ch === '"') {
|
|
39
|
+
inString = true;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (ch === '#' && (i === 0 || COMMENT_PRECEDERS.has(text[i - 1] ?? ''))) {
|
|
43
|
+
commentAt = i;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (ch === '[')
|
|
47
|
+
bracketDelta++;
|
|
48
|
+
else if (ch === ']')
|
|
49
|
+
bracketDelta--;
|
|
50
|
+
}
|
|
51
|
+
return { commentAt, bracketDelta, endsInString: inString, endsInProse: inProse };
|
|
52
|
+
}
|
|
53
|
+
/** Index of a trailing comment's `#`, or -1. */
|
|
54
|
+
export function trailingCommentIndex(text) {
|
|
55
|
+
return walk(text).commentAt;
|
|
56
|
+
}
|
|
57
|
+
export function logicalLines(source, path) {
|
|
58
|
+
const diagnostics = [];
|
|
59
|
+
const lines = [];
|
|
60
|
+
const trivia = [];
|
|
61
|
+
const raw = (source.startsWith('') ? source.slice(1) : source).split(/\r?\n/);
|
|
62
|
+
if (raw.length > 0 && raw[raw.length - 1] === '')
|
|
63
|
+
raw.pop();
|
|
64
|
+
let version;
|
|
65
|
+
const pragma = PRAGMA_RE.exec(raw[0] ?? '');
|
|
66
|
+
if (pragma === null) {
|
|
67
|
+
diagnostics.push(diag('IA-LANG-PRAGMA-MISSING', path, 1, `${path}: line 1 must be the pragma '#! ia <major>.<minor>'`));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
version = pragma[1];
|
|
71
|
+
}
|
|
72
|
+
let span = null;
|
|
73
|
+
// Depth of the last accepted line, and the drop in force after a tab or odd-indentation refusal: a refused
|
|
74
|
+
// line's block produces nothing and is not judged. Widths are columns, a tab counting as one depth.
|
|
75
|
+
let lastDepth = 0;
|
|
76
|
+
let drop;
|
|
77
|
+
for (let index = pragma === null ? 0 : 1; index < raw.length; index++) {
|
|
78
|
+
const lineNo = index + 1;
|
|
79
|
+
const rawLine = raw[index] ?? '';
|
|
80
|
+
if (span !== null && span.kind === 'prose') {
|
|
81
|
+
span.parts.push(rawLine);
|
|
82
|
+
const joined = span.parts.join('\n');
|
|
83
|
+
const w = walk(joined);
|
|
84
|
+
if (!w.endsInProse) {
|
|
85
|
+
if (span.dropped) {
|
|
86
|
+
// A dropped prose value's closer line: its comment stays trivia, and a list it opens is dropped too.
|
|
87
|
+
if (w.commentAt >= 0)
|
|
88
|
+
trivia.push({ kind: 'comment', line: lineNo, text: joined.slice(w.commentAt).trimEnd() });
|
|
89
|
+
span =
|
|
90
|
+
!w.endsInString && w.bracketDelta > 0
|
|
91
|
+
? { kind: 'list', line: lineNo, depth: 0, parts: [], balance: w.bracketDelta, dropped: true }
|
|
92
|
+
: null;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const text = (w.commentAt >= 0 ? joined.slice(0, w.commentAt) : joined).trimEnd();
|
|
96
|
+
lines.push({
|
|
97
|
+
line: span.line,
|
|
98
|
+
endLine: lineNo,
|
|
99
|
+
depth: span.depth,
|
|
100
|
+
text,
|
|
101
|
+
...(w.commentAt >= 0 ? { trailingComment: joined.slice(w.commentAt) } : {}),
|
|
102
|
+
});
|
|
103
|
+
span = null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (span !== null) {
|
|
109
|
+
// List continuation lines are layout-free: the formatter re-indents them, so they are
|
|
110
|
+
// not indentation-checked. Comments on them are trivia at their own lines.
|
|
111
|
+
const trimmed = rawLine.trim();
|
|
112
|
+
if (trimmed === '') {
|
|
113
|
+
trivia.push({ kind: 'blank', line: lineNo });
|
|
114
|
+
span.parts.push('');
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (trimmed.startsWith('#')) {
|
|
118
|
+
trivia.push({ kind: 'comment', line: lineNo, text: trimmed });
|
|
119
|
+
span.parts.push('');
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const w = walk(trimmed);
|
|
123
|
+
if (w.commentAt >= 0)
|
|
124
|
+
trivia.push({ kind: 'comment', line: lineNo, text: trimmed.slice(w.commentAt) });
|
|
125
|
+
const code = (w.commentAt >= 0 ? trimmed.slice(0, w.commentAt) : trimmed).trimEnd();
|
|
126
|
+
span.parts.push(code);
|
|
127
|
+
span.balance += w.bracketDelta;
|
|
128
|
+
if (span.balance <= 0) {
|
|
129
|
+
// Joined with newlines, not spaces: a `"` left open on one line must not be closed
|
|
130
|
+
// by a `"` on the next, and the tokenizer ends a string at a newline.
|
|
131
|
+
if (!span.dropped)
|
|
132
|
+
lines.push({ line: span.line, endLine: lineNo, depth: span.depth, text: span.parts.join('\n') });
|
|
133
|
+
span = null;
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (rawLine.trim() === '') {
|
|
138
|
+
trivia.push({ kind: 'blank', line: lineNo });
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const indentText = /^[ \t]*/.exec(rawLine)?.[0] ?? '';
|
|
142
|
+
const content = rawLine.slice(indentText.length).trimEnd();
|
|
143
|
+
const width = indentText.length + indentText.split('\t').length - 1;
|
|
144
|
+
if (drop !== undefined) {
|
|
145
|
+
if (width > drop.widerThan ||
|
|
146
|
+
(drop.tabWidth !== undefined && width > drop.tabWidth && indentText.includes('\t'))) {
|
|
147
|
+
if (content.startsWith('#')) {
|
|
148
|
+
trivia.push({ kind: 'comment', line: lineNo, text: content });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
// A dropped line's comment stays trivia; a dropped line that opens a multi-line value takes its continuation lines with it.
|
|
152
|
+
const dropped = walk(content);
|
|
153
|
+
if (dropped.commentAt >= 0)
|
|
154
|
+
trivia.push({ kind: 'comment', line: lineNo, text: content.slice(dropped.commentAt) });
|
|
155
|
+
if (dropped.endsInProse)
|
|
156
|
+
span = { kind: 'prose', line: lineNo, depth: 0, parts: [content], dropped: true };
|
|
157
|
+
else if (!dropped.endsInString && dropped.bracketDelta > 0)
|
|
158
|
+
span = { kind: 'list', line: lineNo, depth: 0, parts: [], balance: dropped.bracketDelta, dropped: true };
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
drop = undefined;
|
|
162
|
+
}
|
|
163
|
+
if (indentText.includes('\t') || indentText.length % 2 !== 0) {
|
|
164
|
+
diagnostics.push(indentText.includes('\t')
|
|
165
|
+
? diag('IA-LANG-INDENT-TAB', path, lineNo, `${path}:${lineNo}: tab in indentation; use two spaces per depth`)
|
|
166
|
+
: diag('IA-LANG-INDENT-STEP', path, lineNo, `${path}:${lineNo}: indentation of ${indentText.length} is not a multiple of two`));
|
|
167
|
+
// The refused line's depth is unknowable, so its block is every following line deeper than one level past
|
|
168
|
+
// the last accepted line, which the parser would refuse as a jump; after a tab, every following tab-indented
|
|
169
|
+
// line wider than it as well, since a tab-indented parent has tab-indented children.
|
|
170
|
+
drop = { widerThan: 2 * (lastDepth + 1), tabWidth: indentText.includes('\t') ? width : undefined };
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// Depth is structural: the parser judges how far a line may step in; the scanner only measures it.
|
|
174
|
+
const depth = indentText.length / 2;
|
|
175
|
+
// A comment line obeys the indentation rules above.
|
|
176
|
+
if (content.startsWith('#')) {
|
|
177
|
+
trivia.push({ kind: 'comment', line: lineNo, text: content });
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
lastDepth = depth;
|
|
181
|
+
const w = walk(content);
|
|
182
|
+
const text = (w.commentAt >= 0 ? content.slice(0, w.commentAt) : content).trimEnd();
|
|
183
|
+
const trailingComment = w.commentAt >= 0 ? content.slice(w.commentAt) : undefined;
|
|
184
|
+
// The walk stopped at the comment, so a `"""` inside the comment cannot open a span.
|
|
185
|
+
if (w.endsInProse) {
|
|
186
|
+
span = { kind: 'prose', line: lineNo, depth, parts: [content], dropped: false };
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
// A line that ends inside a string never opens a list; Task 4's tokenizer refuses the string.
|
|
190
|
+
if (!w.endsInString && w.bracketDelta > 0) {
|
|
191
|
+
if (trailingComment !== undefined)
|
|
192
|
+
trivia.push({ kind: 'comment', line: lineNo, text: trailingComment });
|
|
193
|
+
span = { kind: 'list', line: lineNo, depth, parts: [text], balance: w.bracketDelta, dropped: false };
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
lines.push({
|
|
197
|
+
line: lineNo,
|
|
198
|
+
endLine: lineNo,
|
|
199
|
+
depth,
|
|
200
|
+
text,
|
|
201
|
+
...(trailingComment === undefined ? {} : { trailingComment }),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (span !== null && !span.dropped) {
|
|
205
|
+
const code = span.kind === 'prose' ? 'IA-LANG-PROSE-UNTERMINATED' : 'IA-LANG-LIST-UNTERMINATED';
|
|
206
|
+
diagnostics.push(diag(code, path, span.line, `${path}:${span.line}: ${span.kind === 'prose' ? 'prose value has no closing """' : 'list has no closing ]'}`));
|
|
207
|
+
}
|
|
208
|
+
return { ...(version === undefined ? {} : { version }), lines, trivia, diagnostics };
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/scanner/lines.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Diagnostic } from '../diagnostics.js';
|
|
2
|
+
import type { Token } from './tokens.js';
|
|
3
|
+
export interface TokenizeResult {
|
|
4
|
+
readonly tokens: readonly Token[];
|
|
5
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
6
|
+
}
|
|
7
|
+
/** Tokenize one logical line. `line` is the line's first source line. */
|
|
8
|
+
export declare function tokenizeLine(text: string, path: string, line: number): TokenizeResult;
|
|
9
|
+
//# sourceMappingURL=tokenize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.d.ts","sourceRoot":"","sources":["../../src/scanner/tokenize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAOD,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,CAoIrF"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { diag } from '../diagnostics.js';
|
|
2
|
+
import { foldProse } from '../fold.js';
|
|
3
|
+
/** Characters that end a word everywhere: whitespace (including the `\n` the scanner joins list lines with), a quote, an opening bracket. */
|
|
4
|
+
const WORD_END_ALWAYS = new Set([' ', '\t', '\n', '"', '[']);
|
|
5
|
+
/** Characters that end a word only inside a list. Outside one they are ordinary content. */
|
|
6
|
+
const WORD_END_IN_LIST = new Set([',', ']']);
|
|
7
|
+
/** Tokenize one logical line. `line` is the line's first source line. */
|
|
8
|
+
export function tokenizeLine(text, path, line) {
|
|
9
|
+
const tokens = [];
|
|
10
|
+
const diagnostics = [];
|
|
11
|
+
const n = text.length;
|
|
12
|
+
let i = 0;
|
|
13
|
+
let lineNo = line; // source line of position i
|
|
14
|
+
let lineStart = 0; // index in `text` where the current source line begins
|
|
15
|
+
let depth = 0; // open lists
|
|
16
|
+
const column = (at) => at - lineStart + 1;
|
|
17
|
+
const advancePastNewlines = (raw, start) => {
|
|
18
|
+
let nl = raw.indexOf('\n');
|
|
19
|
+
while (nl >= 0) {
|
|
20
|
+
lineNo++;
|
|
21
|
+
lineStart = start + nl + 1;
|
|
22
|
+
nl = raw.indexOf('\n', nl + 1);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
while (i < n) {
|
|
26
|
+
const ch = text[i] ?? '';
|
|
27
|
+
if (ch === '\n') {
|
|
28
|
+
lineNo++;
|
|
29
|
+
lineStart = i + 1;
|
|
30
|
+
i++;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (ch === ' ' || ch === '\t') {
|
|
34
|
+
i++;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const col = column(i);
|
|
38
|
+
if (text.startsWith('"""', i)) {
|
|
39
|
+
const close = text.indexOf('"""', i + 3);
|
|
40
|
+
if (close < 0) {
|
|
41
|
+
// Reachable only by direct callers: the scanner refuses an unterminated span before this runs.
|
|
42
|
+
diagnostics.push(diag('IA-LANG-PROSE-UNTERMINATED', path, lineNo, `${path}:${lineNo}: prose value has no closing """`));
|
|
43
|
+
return { tokens, diagnostics };
|
|
44
|
+
}
|
|
45
|
+
const raw = text.slice(i, close + 3);
|
|
46
|
+
tokens.push({ kind: 'prose', value: foldProse(text.slice(i + 3, close)), raw, line: lineNo, column: col });
|
|
47
|
+
advancePastNewlines(raw, i);
|
|
48
|
+
i = close + 3;
|
|
49
|
+
// Only whitespace may follow (the scanner already removed any comment). A `]` or `,`
|
|
50
|
+
// here means prose was used as a list item, which the grammar does not allow.
|
|
51
|
+
const rest = text.slice(i).trim();
|
|
52
|
+
if (rest !== '') {
|
|
53
|
+
diagnostics.push(diag('IA-LANG-PROSE-TRAILING', path, lineNo, `${path}:${lineNo}: only whitespace or a comment may follow a closing """; found '${rest}'`));
|
|
54
|
+
return { tokens, diagnostics };
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ch === '"') {
|
|
59
|
+
let j = i + 1;
|
|
60
|
+
let value = '';
|
|
61
|
+
let closed = false;
|
|
62
|
+
while (j < n) {
|
|
63
|
+
const c = text[j] ?? '';
|
|
64
|
+
if (c === '\\') {
|
|
65
|
+
const next = text[j + 1];
|
|
66
|
+
if (next === '"' || next === '\\') {
|
|
67
|
+
value += next;
|
|
68
|
+
j += 2;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
value += c;
|
|
72
|
+
j++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (c === '"') {
|
|
76
|
+
closed = true;
|
|
77
|
+
j++;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
if (c === '\n')
|
|
81
|
+
break;
|
|
82
|
+
value += c;
|
|
83
|
+
j++;
|
|
84
|
+
}
|
|
85
|
+
if (!closed) {
|
|
86
|
+
diagnostics.push(diag('IA-LANG-STRING-UNTERMINATED', path, lineNo, `${path}:${lineNo}: string has no closing quote`));
|
|
87
|
+
return { tokens, diagnostics };
|
|
88
|
+
}
|
|
89
|
+
tokens.push({ kind: 'string', value, raw: text.slice(i, j), line: lineNo, column: col });
|
|
90
|
+
i = j;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (ch === '[') {
|
|
94
|
+
depth++;
|
|
95
|
+
tokens.push({ kind: 'list-open', line: lineNo, column: col });
|
|
96
|
+
i++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (depth > 0 && ch === ']') {
|
|
100
|
+
depth--;
|
|
101
|
+
tokens.push({ kind: 'list-close', line: lineNo, column: col });
|
|
102
|
+
i++;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (depth > 0 && ch === ',') {
|
|
106
|
+
tokens.push({ kind: 'list-sep', line: lineNo, column: col });
|
|
107
|
+
i++;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
let j = i;
|
|
111
|
+
while (j < n) {
|
|
112
|
+
const c = text[j] ?? '';
|
|
113
|
+
if (WORD_END_ALWAYS.has(c) || (depth > 0 && WORD_END_IN_LIST.has(c)))
|
|
114
|
+
break;
|
|
115
|
+
j++;
|
|
116
|
+
}
|
|
117
|
+
const word = text.slice(i, j);
|
|
118
|
+
tokens.push(word.startsWith('@')
|
|
119
|
+
? { kind: 'sigil', value: word, line: lineNo, column: col }
|
|
120
|
+
: { kind: 'word', value: word, line: lineNo, column: col });
|
|
121
|
+
i = j;
|
|
122
|
+
}
|
|
123
|
+
return { tokens, diagnostics };
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=tokenize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/scanner/tokenize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface Positioned {
|
|
2
|
+
/** 1-based source line of the token's first character; correct on list continuation lines the scanner joined with `\n`. */
|
|
3
|
+
readonly line: number;
|
|
4
|
+
/** 1-based UTF-16 code-unit offset within that line's content as the scanner presents it (first-line indentation removed, list continuation lines trimmed). */
|
|
5
|
+
readonly column: number;
|
|
6
|
+
}
|
|
7
|
+
export type Token = (Positioned & {
|
|
8
|
+
readonly kind: 'word';
|
|
9
|
+
readonly value: string;
|
|
10
|
+
}) | (Positioned & {
|
|
11
|
+
readonly kind: 'sigil';
|
|
12
|
+
readonly value: string;
|
|
13
|
+
})
|
|
14
|
+
/** `raw` is the slice of the logical line's text including both delimiters, with CRLF already normalized to LF. */
|
|
15
|
+
| (Positioned & {
|
|
16
|
+
readonly kind: 'string';
|
|
17
|
+
readonly value: string;
|
|
18
|
+
readonly raw: string;
|
|
19
|
+
}) | (Positioned & {
|
|
20
|
+
readonly kind: 'prose';
|
|
21
|
+
readonly value: string;
|
|
22
|
+
readonly raw: string;
|
|
23
|
+
}) | (Positioned & {
|
|
24
|
+
readonly kind: 'list-open';
|
|
25
|
+
}) | (Positioned & {
|
|
26
|
+
readonly kind: 'list-sep';
|
|
27
|
+
}) | (Positioned & {
|
|
28
|
+
readonly kind: 'list-close';
|
|
29
|
+
});
|
|
30
|
+
/** Stream-level tokens the scanner adds around each logical line. */
|
|
31
|
+
export type StreamToken = Token | {
|
|
32
|
+
readonly kind: 'pragma';
|
|
33
|
+
readonly version: string;
|
|
34
|
+
readonly line: number;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: 'indent';
|
|
37
|
+
readonly line: number;
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: 'dedent';
|
|
40
|
+
readonly line: number;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'newline';
|
|
43
|
+
readonly line: number;
|
|
44
|
+
readonly endLine: number;
|
|
45
|
+
readonly depth: number;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: 'comment';
|
|
48
|
+
readonly line: number;
|
|
49
|
+
readonly text: string;
|
|
50
|
+
readonly trailing: boolean;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/scanner/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,2HAA2H;IAC3H,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+JAA+J;IAC/J,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,KAAK,GACb,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAChE,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACnE,mHAAmH;GACjH,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GACxF,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GACvF,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,GAC7C,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,GAC5C,CAAC,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAEnD,qEAAqE;AACrE,MAAM,MAAM,WAAW,GACnB,KAAK,GACL;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/scanner/tokens.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RecordNode } from '../ast.js';
|
|
2
|
+
import type { Diagnostic } from '../diagnostics.js';
|
|
3
|
+
import type { FrozenRegistry } from '../registry/types.js';
|
|
4
|
+
import type { CompiledEdge } from './types.js';
|
|
5
|
+
/** valid concerns only this reader's checks; earlier edge/parse errors still prevent admission. */
|
|
6
|
+
export interface CaseResult {
|
|
7
|
+
readonly valid: boolean;
|
|
8
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
9
|
+
}
|
|
10
|
+
/** Structural validation only. Raw structured fields remain preview data; no verdict is produced. */
|
|
11
|
+
export declare function validateCase(record: RecordNode, path: string, registry: FrozenRegistry, edges: readonly CompiledEdge[], refusedBindings: ReadonlySet<'govern' | 'implement'>): CaseResult;
|
|
12
|
+
//# sourceMappingURL=cases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cases.d.ts","sourceRoot":"","sources":["../../src/semantic/cases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,UAAU,EAAe,MAAM,WAAW,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,mGAAmG;AACnG,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAwDD,qGAAqG;AACrG,wBAAgB,YAAY,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,eAAe,EAAE,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,GACnD,UAAU,CAkDZ"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { diag } from '../diagnostics.js';
|
|
2
|
+
import { misplacedIn } from './placement.js';
|
|
3
|
+
import { isRequirementId } from './requirements.js';
|
|
4
|
+
const KINDS = ['success', 'failure', 'refusal', 'resumption', 'escalation'];
|
|
5
|
+
const REQUIRED = ['kind', 'given', 'request', 'expected', 'evaluator'];
|
|
6
|
+
function scenarioDiagnostics(section, path) {
|
|
7
|
+
const fail = (line, message) => [
|
|
8
|
+
diag('IA-LANG-CASE-MALFORMED', path, line, message),
|
|
9
|
+
];
|
|
10
|
+
const fields = section.children.filter((c) => c.kind === 'field');
|
|
11
|
+
const verdict = fields.find((field) => field.words[0] === 'verdict');
|
|
12
|
+
if (verdict)
|
|
13
|
+
return fail(verdict.span.line, 'A case cannot carry verdict data; results are run evidence.');
|
|
14
|
+
const misplaced = misplacedIn(section.children, path)[0];
|
|
15
|
+
if (misplaced)
|
|
16
|
+
return [misplaced];
|
|
17
|
+
const item = section.children.find((c) => c.kind === 'item');
|
|
18
|
+
if (item)
|
|
19
|
+
return fail(item.span.line, 'Scenario data uses named fields, not item rows.');
|
|
20
|
+
for (const key of REQUIRED) {
|
|
21
|
+
const named = fields.filter((field) => field.key === key);
|
|
22
|
+
if (named.length === 0)
|
|
23
|
+
return fail(section.span.line, `Scenario requires ${key}.`);
|
|
24
|
+
if (named.length > 1)
|
|
25
|
+
return named.map((field) => diag('IA-LANG-CASE-MALFORMED', path, field.span.line, `Scenario ${key} must be written once.`));
|
|
26
|
+
const field = named[0];
|
|
27
|
+
if (field.children.some((child) => child.kind !== 'record'))
|
|
28
|
+
return fail(field.span.line, `Scenario ${key} cannot have a child block.`);
|
|
29
|
+
if (key === 'kind') {
|
|
30
|
+
if ((field.value.kind !== 'scalar' && field.value.kind !== 'string') ||
|
|
31
|
+
!KINDS.includes(field.value.text))
|
|
32
|
+
return fail(field.span.line, `Scenario kind must be ${KINDS.join(', ')}.`);
|
|
33
|
+
}
|
|
34
|
+
else if (field.value.kind !== 'string' && field.value.kind !== 'prose')
|
|
35
|
+
return fail(field.span.line, `Scenario ${key} requires string or prose text.`);
|
|
36
|
+
}
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
function bindsRequirement(edge, registry) {
|
|
40
|
+
if (edge.predicate !== 'implement' ||
|
|
41
|
+
edge.direction !== 'out' ||
|
|
42
|
+
edge.fragment === undefined ||
|
|
43
|
+
!isRequirementId(edge.fragment))
|
|
44
|
+
return false;
|
|
45
|
+
const contract = registry.registrations.get('contract');
|
|
46
|
+
if (!contract)
|
|
47
|
+
return false;
|
|
48
|
+
if (edge.reference.kind === 'ref')
|
|
49
|
+
return edge.reference.discriminator === 'contract';
|
|
50
|
+
const slots = edge.reference.identity.split('/');
|
|
51
|
+
return (slots.length === 4 &&
|
|
52
|
+
slots[0] === contract.system &&
|
|
53
|
+
slots[1] === contract.kind &&
|
|
54
|
+
contract.facets.includes(slots[2]) &&
|
|
55
|
+
/^[a-z][a-z0-9-]*$/.test(slots[3]));
|
|
56
|
+
}
|
|
57
|
+
/** Structural validation only. Raw structured fields remain preview data; no verdict is produced. */
|
|
58
|
+
export function validateCase(record, path, registry, edges, refusedBindings) {
|
|
59
|
+
if (record.discriminator !== 'case' || !registry.registrations.has('case'))
|
|
60
|
+
return { valid: true, diagnostics: [] };
|
|
61
|
+
const diagnostics = [];
|
|
62
|
+
for (const field of record.head)
|
|
63
|
+
if (field.words[0] === 'verdict')
|
|
64
|
+
diagnostics.push(diag('IA-LANG-CASE-MALFORMED', path, field.span.line, 'A case cannot carry verdict data; results are run evidence.'));
|
|
65
|
+
for (const section of record.sections)
|
|
66
|
+
if (section.name === 'verdict')
|
|
67
|
+
diagnostics.push(diag('IA-LANG-CASE-MALFORMED', path, section.span.line, 'A case cannot carry a verdict block; results are run evidence.'));
|
|
68
|
+
const sections = record.sections.filter((section) => section.name === 'scenario');
|
|
69
|
+
if (sections.length === 0)
|
|
70
|
+
diagnostics.push(diag('IA-LANG-CASE-MALFORMED', path, record.span.line, 'A case requires exactly one scenario block.'));
|
|
71
|
+
else if (sections.length > 1)
|
|
72
|
+
for (const section of sections)
|
|
73
|
+
diagnostics.push(diag('IA-LANG-CASE-MALFORMED', path, section.span.line, 'A case requires exactly one scenario block; every duplicate is refused.'));
|
|
74
|
+
else
|
|
75
|
+
diagnostics.push(...scenarioDiagnostics(sections[0], path));
|
|
76
|
+
if (!refusedBindings.has('implement') && !edges.some((edge) => bindsRequirement(edge, registry)))
|
|
77
|
+
diagnostics.push(diag('IA-LANG-CASE-UNBOUND', path, record.span.line, 'A case requires an outbound implements binding to a registered contract with a REQ-ID fragment.'));
|
|
78
|
+
diagnostics.sort((a, b) => a.line - b.line);
|
|
79
|
+
return { valid: diagnostics.length === 0, diagnostics };
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=cases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cases.js","sourceRoot":"","sources":["../../src/semantic/cases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RecordNode } from '../ast.js';
|
|
2
|
+
import type { Diagnostic } from '../diagnostics.js';
|
|
3
|
+
import type { Cell } from './types.js';
|
|
4
|
+
export interface CellsResult {
|
|
5
|
+
readonly cells: readonly Cell[];
|
|
6
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
7
|
+
}
|
|
8
|
+
export declare function readCells(record: RecordNode, path: string): CellsResult;
|
|
9
|
+
//# sourceMappingURL=cells.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cells.d.ts","sourceRoot":"","sources":["../../src/semantic/cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAKpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAID,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CA2HvE"}
|