@kernlang/core 3.1.5 → 3.1.7
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 +17 -0
- package/README.md +5 -2
- package/dist/codegen/data-layer.d.ts +12 -0
- package/dist/codegen/data-layer.js +291 -0
- package/dist/codegen/data-layer.js.map +1 -0
- package/dist/codegen/emitters.js +1 -4
- package/dist/codegen/emitters.js.map +1 -1
- package/dist/codegen/events.d.ts +9 -0
- package/dist/codegen/events.js +169 -0
- package/dist/codegen/events.js.map +1 -0
- package/dist/codegen/functions.d.ts +8 -0
- package/dist/codegen/functions.js +149 -0
- package/dist/codegen/functions.js.map +1 -0
- package/dist/codegen/ground-layer.d.ts +22 -0
- package/dist/codegen/ground-layer.js +321 -0
- package/dist/codegen/ground-layer.js.map +1 -0
- package/dist/codegen/helpers.d.ts +2 -0
- package/dist/codegen/helpers.js +19 -7
- package/dist/codegen/helpers.js.map +1 -1
- package/dist/codegen/machines.d.ts +9 -0
- package/dist/codegen/machines.js +129 -0
- package/dist/codegen/machines.js.map +1 -0
- package/dist/codegen/modules.d.ts +10 -0
- package/dist/codegen/modules.js +43 -0
- package/dist/codegen/modules.js.map +1 -0
- package/dist/codegen/screens.d.ts +29 -0
- package/dist/codegen/screens.js +202 -0
- package/dist/codegen/screens.js.map +1 -0
- package/dist/codegen/semantic-types.d.ts +14 -0
- package/dist/codegen/semantic-types.js +31 -0
- package/dist/codegen/semantic-types.js.map +1 -0
- package/dist/codegen/test-gen.d.ts +7 -0
- package/dist/codegen/test-gen.js +56 -0
- package/dist/codegen/test-gen.js.map +1 -0
- package/dist/codegen/type-system.d.ts +11 -0
- package/dist/codegen/type-system.js +171 -0
- package/dist/codegen/type-system.js.map +1 -0
- package/dist/codegen-core.d.ts +30 -36
- package/dist/codegen-core.js +258 -1459
- package/dist/codegen-core.js.map +1 -1
- package/dist/concepts.js.map +1 -1
- package/dist/config.d.ts +20 -1
- package/dist/config.js +36 -3
- package/dist/config.js.map +1 -1
- package/dist/coverage-gap.js +9 -5
- package/dist/coverage-gap.js.map +1 -1
- package/dist/decompiler.d.ts +10 -1
- package/dist/decompiler.js +21 -4
- package/dist/decompiler.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +11 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +33 -28
- package/dist/index.js +40 -35
- package/dist/index.js.map +1 -1
- package/dist/node-props.d.ts +255 -0
- package/dist/node-props.js +35 -0
- package/dist/node-props.js.map +1 -0
- package/dist/parser-core.d.ts +5 -0
- package/dist/parser-core.js +364 -0
- package/dist/parser-core.js.map +1 -0
- package/dist/parser-diagnostics.d.ts +14 -0
- package/dist/parser-diagnostics.js +32 -0
- package/dist/parser-diagnostics.js.map +1 -0
- package/dist/parser-keywords.d.ts +5 -0
- package/dist/parser-keywords.js +203 -0
- package/dist/parser-keywords.js.map +1 -0
- package/dist/parser-style.d.ts +3 -0
- package/dist/parser-style.js +73 -0
- package/dist/parser-style.js.map +1 -0
- package/dist/parser-token-stream.d.ts +27 -0
- package/dist/parser-token-stream.js +81 -0
- package/dist/parser-token-stream.js.map +1 -0
- package/dist/parser-tokenizer.d.ts +11 -0
- package/dist/parser-tokenizer.js +188 -0
- package/dist/parser-tokenizer.js.map +1 -0
- package/dist/parser.d.ts +61 -14
- package/dist/parser.js +65 -865
- package/dist/parser.js.map +1 -1
- package/dist/scanner.js +85 -25
- package/dist/scanner.js.map +1 -1
- package/dist/schema.d.ts +7 -2
- package/dist/schema.js +7 -2
- package/dist/schema.js.map +1 -1
- package/dist/source-map.d.ts +27 -0
- package/dist/source-map.js +82 -0
- package/dist/source-map.js.map +1 -0
- package/dist/spec.d.ts +1 -1
- package/dist/spec.js +197 -55
- package/dist/spec.js.map +1 -1
- package/dist/styles-react.js +1 -1
- package/dist/styles-react.js.map +1 -1
- package/dist/styles-tailwind.d.ts +10 -0
- package/dist/styles-tailwind.js +62 -15
- package/dist/styles-tailwind.js.map +1 -1
- package/dist/template-catalog.js +1 -1
- package/dist/template-catalog.js.map +1 -1
- package/dist/template-engine.d.ts +11 -6
- package/dist/template-engine.js +20 -12
- package/dist/template-engine.js.map +1 -1
- package/dist/types.d.ts +8 -3
- package/dist/utils.d.ts +21 -1
- package/dist/utils.js +29 -5
- package/dist/utils.js.map +1 -1
- package/dist/version-adapters.js +1 -2
- package/dist/version-adapters.js.map +1 -1
- package/dist/version-detect.js +3 -3
- package/dist/version-detect.js.map +1 -1
- package/dist/walk.d.ts +40 -0
- package/dist/walk.js +111 -0
- package/dist/walk.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** @internal Style block parsing for KERN nodes. */
|
|
2
|
+
export function splitStylePairs(block) {
|
|
3
|
+
const pairs = [];
|
|
4
|
+
let current = '';
|
|
5
|
+
let inQuote = false;
|
|
6
|
+
let parenDepth = 0;
|
|
7
|
+
for (let i = 0; i < block.length; i++) {
|
|
8
|
+
const ch = block[i];
|
|
9
|
+
if (ch === '\\' && i + 1 < block.length) {
|
|
10
|
+
current += ch + block[i + 1];
|
|
11
|
+
i++;
|
|
12
|
+
}
|
|
13
|
+
else if (ch === '"') {
|
|
14
|
+
inQuote = !inQuote;
|
|
15
|
+
current += ch;
|
|
16
|
+
}
|
|
17
|
+
else if (!inQuote && ch === '(') {
|
|
18
|
+
parenDepth++;
|
|
19
|
+
current += ch;
|
|
20
|
+
}
|
|
21
|
+
else if (!inQuote && ch === ')') {
|
|
22
|
+
parenDepth--;
|
|
23
|
+
current += ch;
|
|
24
|
+
}
|
|
25
|
+
else if (!inQuote && parenDepth === 0 && ch === ',') {
|
|
26
|
+
if (current.trim())
|
|
27
|
+
pairs.push(current.trim());
|
|
28
|
+
current = '';
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
current += ch;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (current.trim())
|
|
35
|
+
pairs.push(current.trim());
|
|
36
|
+
return pairs;
|
|
37
|
+
}
|
|
38
|
+
export function parseStyleBlock(block, styles, pseudoStyles) {
|
|
39
|
+
const pairs = splitStylePairs(block);
|
|
40
|
+
for (const pair of pairs) {
|
|
41
|
+
// Pseudo-selector: :press:bg:#005BB5
|
|
42
|
+
const pseudoMatch = pair.match(/^:([a-z]+):([A-Za-z0-9_-]+):(.+)$/);
|
|
43
|
+
if (pseudoMatch) {
|
|
44
|
+
const [, pseudo, key, value] = pseudoMatch;
|
|
45
|
+
if (!pseudoStyles[pseudo])
|
|
46
|
+
pseudoStyles[pseudo] = {};
|
|
47
|
+
pseudoStyles[pseudo][key] = value.trim();
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Quoted key: "backdrop-filter":"blur(8px)"
|
|
51
|
+
const quotedKeyMatch = pair.match(/^"([^"]+)"\s*:\s*(.*)/);
|
|
52
|
+
if (quotedKeyMatch) {
|
|
53
|
+
const key = quotedKeyMatch[1];
|
|
54
|
+
let value = quotedKeyMatch[2].trim();
|
|
55
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
56
|
+
value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
57
|
+
}
|
|
58
|
+
styles[key] = value;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Normal: key:value (value may be quoted)
|
|
62
|
+
const colonIdx = pair.indexOf(':');
|
|
63
|
+
if (colonIdx > 0) {
|
|
64
|
+
const key = pair.slice(0, colonIdx).trim();
|
|
65
|
+
let value = pair.slice(colonIdx + 1).trim();
|
|
66
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
67
|
+
value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
68
|
+
}
|
|
69
|
+
styles[key] = value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=parser-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-style.js","sourceRoot":"","sources":["../src/parser-style.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @internal Token stream cursor for KERN parser. */
|
|
2
|
+
import type { Token } from './parser-tokenizer.js';
|
|
3
|
+
export declare class TokenStream {
|
|
4
|
+
private tokens;
|
|
5
|
+
private idx;
|
|
6
|
+
constructor(tokens: Token[]);
|
|
7
|
+
peek(): Token | undefined;
|
|
8
|
+
next(): Token | undefined;
|
|
9
|
+
done(): boolean;
|
|
10
|
+
position(): number;
|
|
11
|
+
setPosition(pos: number): void;
|
|
12
|
+
skipWS(): void;
|
|
13
|
+
/** Try to consume an identifier. Returns its value or null. */
|
|
14
|
+
tryIdent(): string | null;
|
|
15
|
+
/** Try to consume a number token. Returns its value or null. */
|
|
16
|
+
tryNumber(): string | null;
|
|
17
|
+
/** Check if the next non-WS token is an identifier followed by '='. */
|
|
18
|
+
isKeyValue(): boolean;
|
|
19
|
+
/** Check if any remaining token contains '='. */
|
|
20
|
+
hasEquals(): boolean;
|
|
21
|
+
/** Check if there are more non-whitespace tokens. */
|
|
22
|
+
hasMore(): boolean;
|
|
23
|
+
/** Get remaining raw text from current position (for fallback / params). */
|
|
24
|
+
remainingRaw(line: string): string;
|
|
25
|
+
/** Consume any single non-whitespace token as a value (for evolved positional args). */
|
|
26
|
+
consumeAnyValue(): Token | undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export class TokenStream {
|
|
2
|
+
tokens;
|
|
3
|
+
idx = 0;
|
|
4
|
+
constructor(tokens) {
|
|
5
|
+
this.tokens = tokens;
|
|
6
|
+
}
|
|
7
|
+
peek() {
|
|
8
|
+
return this.tokens[this.idx];
|
|
9
|
+
}
|
|
10
|
+
next() {
|
|
11
|
+
return this.tokens[this.idx++];
|
|
12
|
+
}
|
|
13
|
+
done() {
|
|
14
|
+
return this.idx >= this.tokens.length;
|
|
15
|
+
}
|
|
16
|
+
position() {
|
|
17
|
+
return this.idx;
|
|
18
|
+
}
|
|
19
|
+
setPosition(pos) {
|
|
20
|
+
this.idx = pos;
|
|
21
|
+
}
|
|
22
|
+
skipWS() {
|
|
23
|
+
while (this.idx < this.tokens.length && this.tokens[this.idx].kind === 'whitespace')
|
|
24
|
+
this.idx++;
|
|
25
|
+
}
|
|
26
|
+
/** Try to consume an identifier. Returns its value or null. */
|
|
27
|
+
tryIdent() {
|
|
28
|
+
if (this.idx < this.tokens.length && this.tokens[this.idx].kind === 'identifier') {
|
|
29
|
+
return this.tokens[this.idx++].value;
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/** Try to consume a number token. Returns its value or null. */
|
|
34
|
+
tryNumber() {
|
|
35
|
+
if (this.idx < this.tokens.length && this.tokens[this.idx].kind === 'number') {
|
|
36
|
+
return this.tokens[this.idx++].value;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** Check if the next non-WS token is an identifier followed by '='. */
|
|
41
|
+
isKeyValue() {
|
|
42
|
+
let j = this.idx;
|
|
43
|
+
while (j < this.tokens.length && this.tokens[j].kind === 'whitespace')
|
|
44
|
+
j++;
|
|
45
|
+
if (j >= this.tokens.length || this.tokens[j].kind !== 'identifier')
|
|
46
|
+
return false;
|
|
47
|
+
return j + 1 < this.tokens.length && this.tokens[j + 1].kind === 'equals';
|
|
48
|
+
}
|
|
49
|
+
/** Check if any remaining token contains '='. */
|
|
50
|
+
hasEquals() {
|
|
51
|
+
for (let j = this.idx; j < this.tokens.length; j++) {
|
|
52
|
+
if (this.tokens[j].kind === 'equals')
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/** Check if there are more non-whitespace tokens. */
|
|
58
|
+
hasMore() {
|
|
59
|
+
let j = this.idx;
|
|
60
|
+
while (j < this.tokens.length && this.tokens[j].kind === 'whitespace')
|
|
61
|
+
j++;
|
|
62
|
+
return j < this.tokens.length;
|
|
63
|
+
}
|
|
64
|
+
/** Get remaining raw text from current position (for fallback / params). */
|
|
65
|
+
remainingRaw(line) {
|
|
66
|
+
if (this.idx >= this.tokens.length)
|
|
67
|
+
return '';
|
|
68
|
+
const startPos = this.tokens[this.idx].pos;
|
|
69
|
+
this.idx = this.tokens.length;
|
|
70
|
+
return line.slice(startPos);
|
|
71
|
+
}
|
|
72
|
+
/** Consume any single non-whitespace token as a value (for evolved positional args). */
|
|
73
|
+
consumeAnyValue() {
|
|
74
|
+
this.skipWS();
|
|
75
|
+
const tok = this.peek();
|
|
76
|
+
if (!tok || tok.kind === 'whitespace')
|
|
77
|
+
return undefined;
|
|
78
|
+
return this.next();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=parser-token-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-token-stream.js","sourceRoot":"","sources":["../src/parser-token-stream.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,WAAW;IACd,MAAM,CAAU;IAChB,GAAG,GAAG,CAAC,CAAC;IAEhB,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,CAAC;IACD,QAAQ;QACN,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IACD,WAAW,CAAC,GAAW;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAClG,CAAC;IAED,+DAA+D;IAC/D,QAAQ;QACN,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACjF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gEAAgE;IAChE,SAAS;QACP,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC;QACvC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uEAAuE;IACvE,UAAU;QACR,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;IAC5E,CAAC;IAED,iDAAiD;IACjD,SAAS;QACP,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qDAAqD;IACrD,OAAO;QACL,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,YAAY,CAAC,IAAY;QACvB,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,wFAAwF;IACxF,eAAe;QACb,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,SAAS,CAAC;QACxD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** @internal Tokenizer for KERN source lines. */
|
|
2
|
+
import type { ParseState } from './parser-diagnostics.js';
|
|
3
|
+
export type TokenKind = 'identifier' | 'number' | 'equals' | 'quoted' | 'expr' | 'style' | 'themeRef' | 'slash' | 'comma' | 'whitespace' | 'unknown';
|
|
4
|
+
export interface Token {
|
|
5
|
+
kind: TokenKind;
|
|
6
|
+
value: string;
|
|
7
|
+
pos: number;
|
|
8
|
+
}
|
|
9
|
+
/** @internal Character-by-character tokenizer for a single KERN line (after indent stripped). */
|
|
10
|
+
export declare function tokenizeLineInternal(line: string, state?: ParseState): Token[];
|
|
11
|
+
export declare function tokenizeLine(line: string): Token[];
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { emitDiagnostic } from './parser-diagnostics.js';
|
|
2
|
+
// ── Tokenizer ────────────────────────────────────────────────────────────
|
|
3
|
+
function isIdentStart(ch) {
|
|
4
|
+
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch === '_';
|
|
5
|
+
}
|
|
6
|
+
function isIdentChar(ch) {
|
|
7
|
+
return isIdentStart(ch) || (ch >= '0' && ch <= '9') || ch === '-';
|
|
8
|
+
}
|
|
9
|
+
function isDigit(ch) {
|
|
10
|
+
return ch >= '0' && ch <= '9';
|
|
11
|
+
}
|
|
12
|
+
/** @internal Character-by-character tokenizer for a single KERN line (after indent stripped). */
|
|
13
|
+
export function tokenizeLineInternal(line, state) {
|
|
14
|
+
const tokens = [];
|
|
15
|
+
let i = 0;
|
|
16
|
+
while (i < line.length) {
|
|
17
|
+
const ch = line[i];
|
|
18
|
+
// Whitespace
|
|
19
|
+
if (ch === ' ' || ch === '\t') {
|
|
20
|
+
const start = i;
|
|
21
|
+
while (i < line.length && (line[i] === ' ' || line[i] === '\t'))
|
|
22
|
+
i++;
|
|
23
|
+
tokens.push({ kind: 'whitespace', value: line.slice(start, i), pos: start });
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
// Expression block {{ ... }}
|
|
27
|
+
if (ch === '{' && i + 1 < line.length && line[i + 1] === '{') {
|
|
28
|
+
const start = i;
|
|
29
|
+
i += 2;
|
|
30
|
+
let depth = 1;
|
|
31
|
+
while (i < line.length - 1 && depth > 0) {
|
|
32
|
+
if (line[i] === '{' && line[i + 1] === '{') {
|
|
33
|
+
depth++;
|
|
34
|
+
i += 2;
|
|
35
|
+
}
|
|
36
|
+
else if (line[i] === '}' && line[i + 1] === '}') {
|
|
37
|
+
depth--;
|
|
38
|
+
if (depth === 0)
|
|
39
|
+
break;
|
|
40
|
+
i += 2;
|
|
41
|
+
}
|
|
42
|
+
else
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
if (depth > 0) {
|
|
46
|
+
if (state) {
|
|
47
|
+
emitDiagnostic(state, 'UNCLOSED_EXPR', 'error', `Unclosed expression block '{{' at column ${start + 1}`, 0, start + 1, { endCol: start + 3 });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const inner = line.slice(start + 2, i).trim();
|
|
51
|
+
if (i < line.length - 1)
|
|
52
|
+
i += 2;
|
|
53
|
+
else
|
|
54
|
+
i = line.length;
|
|
55
|
+
tokens.push({ kind: 'expr', value: inner, pos: start });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Style block { ... } — find matching } respecting quotes
|
|
59
|
+
if (ch === '{') {
|
|
60
|
+
const start = i;
|
|
61
|
+
let inQuote = false;
|
|
62
|
+
let j = i + 1;
|
|
63
|
+
let closed = false;
|
|
64
|
+
while (j < line.length) {
|
|
65
|
+
if (line[j] === '\\' && j + 1 < line.length) {
|
|
66
|
+
j += 2;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (line[j] === '"')
|
|
70
|
+
inQuote = !inQuote;
|
|
71
|
+
if (!inQuote && line[j] === '}') {
|
|
72
|
+
j++;
|
|
73
|
+
closed = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
j++;
|
|
77
|
+
}
|
|
78
|
+
if (!closed) {
|
|
79
|
+
if (state) {
|
|
80
|
+
emitDiagnostic(state, 'UNCLOSED_STYLE', 'error', `Unclosed style block '{' at column ${start + 1}`, 0, start + 1, { endCol: start + 2 });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
tokens.push({ kind: 'style', value: line.slice(start + 1, closed ? j - 1 : j), pos: start });
|
|
84
|
+
i = j;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// Quoted string "..." with \" escape support
|
|
88
|
+
if (ch === '"') {
|
|
89
|
+
const start = i;
|
|
90
|
+
i++;
|
|
91
|
+
let inner = '';
|
|
92
|
+
while (i < line.length && line[i] !== '"') {
|
|
93
|
+
if (line[i] === '\\' && i + 1 < line.length) {
|
|
94
|
+
const next = line[i + 1];
|
|
95
|
+
if (next === '"') {
|
|
96
|
+
inner += '"';
|
|
97
|
+
i += 2;
|
|
98
|
+
}
|
|
99
|
+
else if (next === '\\') {
|
|
100
|
+
inner += '\\';
|
|
101
|
+
i += 2;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
inner += line[i];
|
|
105
|
+
i++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
inner += line[i];
|
|
110
|
+
i++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (i >= line.length) {
|
|
114
|
+
if (state) {
|
|
115
|
+
emitDiagnostic(state, 'UNCLOSED_STRING', 'error', `Unclosed quoted string at column ${start + 1}`, 0, start + 1, { endCol: start + 2 });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
i++; // skip closing quote
|
|
120
|
+
}
|
|
121
|
+
tokens.push({ kind: 'quoted', value: inner, pos: start });
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
// Theme ref $name
|
|
125
|
+
if (ch === '$' && i + 1 < line.length && isIdentStart(line[i + 1])) {
|
|
126
|
+
const start = i;
|
|
127
|
+
i++;
|
|
128
|
+
while (i < line.length && isIdentChar(line[i]))
|
|
129
|
+
i++;
|
|
130
|
+
tokens.push({ kind: 'themeRef', value: line.slice(start + 1, i), pos: start });
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Equals
|
|
134
|
+
if (ch === '=') {
|
|
135
|
+
tokens.push({ kind: 'equals', value: '=', pos: i });
|
|
136
|
+
i++;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Comma
|
|
140
|
+
if (ch === ',') {
|
|
141
|
+
tokens.push({ kind: 'comma', value: ',', pos: i });
|
|
142
|
+
i++;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// Slash-prefixed path: /something
|
|
146
|
+
if (ch === '/') {
|
|
147
|
+
const start = i;
|
|
148
|
+
while (i < line.length && line[i] !== ' ' && line[i] !== '\t' && line[i] !== '{' && line[i] !== '$')
|
|
149
|
+
i++;
|
|
150
|
+
tokens.push({ kind: 'slash', value: line.slice(start, i), pos: start });
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// Number (pure digits)
|
|
154
|
+
if (isDigit(ch)) {
|
|
155
|
+
const start = i;
|
|
156
|
+
while (i < line.length && isDigit(line[i]))
|
|
157
|
+
i++;
|
|
158
|
+
tokens.push({ kind: 'number', value: line.slice(start, i), pos: start });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Identifier: [A-Za-z_][A-Za-z0-9_-]*
|
|
162
|
+
// Handles evolved: prefix (evolved:keyword → strips prefix, returns keyword)
|
|
163
|
+
if (isIdentStart(ch)) {
|
|
164
|
+
const start = i;
|
|
165
|
+
while (i < line.length && isIdentChar(line[i]))
|
|
166
|
+
i++;
|
|
167
|
+
if (line[i] === ':' && line.slice(start, i) === 'evolved' && i + 1 < line.length && isIdentStart(line[i + 1])) {
|
|
168
|
+
i++;
|
|
169
|
+
const nameStart = i;
|
|
170
|
+
while (i < line.length && isIdentChar(line[i]))
|
|
171
|
+
i++;
|
|
172
|
+
tokens.push({ kind: 'identifier', value: line.slice(nameStart, i), pos: start });
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
tokens.push({ kind: 'identifier', value: line.slice(start, i), pos: start });
|
|
176
|
+
}
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// Unknown character
|
|
180
|
+
tokens.push({ kind: 'unknown', value: ch, pos: i });
|
|
181
|
+
i++;
|
|
182
|
+
}
|
|
183
|
+
return tokens;
|
|
184
|
+
}
|
|
185
|
+
export function tokenizeLine(line) {
|
|
186
|
+
return tokenizeLineInternal(line);
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=parser-tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-tokenizer.js","sourceRoot":"","sources":["../src/parser-tokenizer.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,21 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* KERN Parser — public API surface.
|
|
3
|
+
*
|
|
4
|
+
* Implementation is split across sibling modules:
|
|
5
|
+
* - parser-diagnostics.ts — diagnostic infrastructure
|
|
6
|
+
* - parser-tokenizer.ts — character-level tokenizer
|
|
7
|
+
* - parser-token-stream.ts — token cursor
|
|
8
|
+
* - parser-style.ts — style block parsing
|
|
9
|
+
* - parser-keywords.ts — keyword-specific handlers
|
|
10
|
+
* - parser-core.ts — line parsing, tree building, orchestration
|
|
11
|
+
*/
|
|
3
12
|
import type { ParserHintsConfig } from './runtime.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
pos: number;
|
|
9
|
-
}
|
|
10
|
-
export declare function tokenizeLine(line: string): Token[];
|
|
13
|
+
import { type KernRuntime } from './runtime.js';
|
|
14
|
+
import type { IRNode, ParseDiagnostic, ParseResult } from './types.js';
|
|
15
|
+
export type { Token, TokenKind } from './parser-tokenizer.js';
|
|
16
|
+
export { tokenizeLine } from './parser-tokenizer.js';
|
|
11
17
|
/** Register parser hints for an evolved node type. */
|
|
12
18
|
export declare function registerParserHints(keyword: string, hints: ParserHintsConfig): void;
|
|
13
19
|
/** Unregister parser hints (for rollback/testing). */
|
|
14
20
|
export declare function unregisterParserHints(keyword: string): void;
|
|
15
21
|
/** Clear all parser hints (for test isolation). */
|
|
16
22
|
export declare function clearParserHints(): void;
|
|
17
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Get diagnostic messages from the last parse() call as plain strings.
|
|
25
|
+
*
|
|
26
|
+
* @remarks Returns messages for all severities (error, warning, info).
|
|
27
|
+
* For structured diagnostics with severity filtering, use {@link getParseDiagnostics}.
|
|
28
|
+
*/
|
|
18
29
|
export declare function getParseWarnings(): string[];
|
|
30
|
+
/** Get structured diagnostics from the last parse() call. */
|
|
31
|
+
export declare function getParseDiagnostics(runtime?: KernRuntime): ParseDiagnostic[];
|
|
32
|
+
/**
|
|
33
|
+
* Parse KERN source into an IR node tree.
|
|
34
|
+
*
|
|
35
|
+
* Recovers from errors gracefully — malformed lines produce `DROPPED_LINE`
|
|
36
|
+
* diagnostics but never throw. Use {@link parseStrict} if you want errors to throw.
|
|
37
|
+
*
|
|
38
|
+
* @param source - KERN indentation-based source text
|
|
39
|
+
* @param runtime - Optional KernRuntime instance for isolation (defaults to shared singleton)
|
|
40
|
+
* @returns Root IRNode of the parsed tree
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const root = parse('page "Home"\n text "Hello"');
|
|
45
|
+
* // root.type === 'page', root.children[0].type === 'text'
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @see {@link parseWithDiagnostics} to also receive parse diagnostics
|
|
49
|
+
* @see {@link parseStrict} to throw on errors
|
|
50
|
+
*/
|
|
19
51
|
export declare function parse(source: string, runtime?: KernRuntime): IRNode;
|
|
20
52
|
/**
|
|
21
53
|
* Parse KERN source into a document-wrapped IR tree.
|
|
@@ -23,13 +55,28 @@ export declare function parse(source: string, runtime?: KernRuntime): IRNode;
|
|
|
23
55
|
* top-level nodes (e.g., multiple `rule` definitions) are siblings.
|
|
24
56
|
*/
|
|
25
57
|
export declare function parseDocument(source: string, runtime?: KernRuntime): IRNode;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Parse KERN source and return both the IR tree and structured diagnostics.
|
|
60
|
+
*
|
|
61
|
+
* Unlike {@link parse}, this returns a {@link ParseResult} containing the full
|
|
62
|
+
* diagnostics array, useful for editor integrations and lint-style reporting.
|
|
63
|
+
*
|
|
64
|
+
* @param source - KERN indentation-based source text
|
|
65
|
+
* @param runtime - Optional KernRuntime instance for isolation
|
|
66
|
+
* @returns `{ root: IRNode, diagnostics: ParseDiagnostic[] }`
|
|
67
|
+
*/
|
|
29
68
|
export declare function parseWithDiagnostics(source: string, runtime?: KernRuntime): ParseResult;
|
|
30
69
|
/** Parse with diagnostics (document mode). */
|
|
31
70
|
export declare function parseDocumentWithDiagnostics(source: string, runtime?: KernRuntime): ParseResult;
|
|
32
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Strict parse — throws if any diagnostic has severity `'error'` or a schema violation is found.
|
|
73
|
+
*
|
|
74
|
+
* @param source - KERN indentation-based source text
|
|
75
|
+
* @param runtime - Optional KernRuntime instance for isolation
|
|
76
|
+
* @returns Root IRNode of the parsed tree
|
|
77
|
+
* @throws {KernParseError} When the source contains errors or schema violations.
|
|
78
|
+
* The error includes a code frame and the full diagnostics array.
|
|
79
|
+
*/
|
|
33
80
|
export declare function parseStrict(source: string, runtime?: KernRuntime): IRNode;
|
|
34
81
|
/** Strict document parse — throws KernParseError if any diagnostic has severity=error or schema violation. */
|
|
35
82
|
export declare function parseDocumentStrict(source: string, runtime?: KernRuntime): IRNode;
|