@kawaijs/parser 0.1.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/dist/compiler.d.ts +14 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +198 -0
- package/dist/compiler.js.map +1 -0
- package/dist/diagnostic.d.ts +18 -0
- package/dist/diagnostic.d.ts.map +1 -0
- package/dist/diagnostic.js +37 -0
- package/dist/diagnostic.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lexer.d.ts +32 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +324 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser.d.ts +38 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +459 -0
- package/dist/parser.js.map +1 -0
- package/dist/token.d.ts +9 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +27 -0
- package/dist/token.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProgramNode, StoryPackage } from '@kawaijs/ast';
|
|
2
|
+
export interface CompilerOptions {
|
|
3
|
+
validateLabels?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class Compiler {
|
|
6
|
+
private readonly program;
|
|
7
|
+
private readonly options;
|
|
8
|
+
private anonymousLabelCounter;
|
|
9
|
+
constructor(program: ProgramNode, options?: CompilerOptions);
|
|
10
|
+
compile(): StoryPackage;
|
|
11
|
+
private compileBlock;
|
|
12
|
+
private validateLabelReferences;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,WAAW,EAEX,YAAY,EACb,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,qBAAqB,CAAK;gBAEtB,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,eAA0C;IAK9E,OAAO,IAAI,YAAY;IAyC9B,OAAO,CAAC,YAAY;IA4JpB,OAAO,CAAC,uBAAuB;CAiBhC"}
|
package/dist/compiler.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { KawaError } from './diagnostic.js';
|
|
2
|
+
export class Compiler {
|
|
3
|
+
program;
|
|
4
|
+
options;
|
|
5
|
+
anonymousLabelCounter = 0;
|
|
6
|
+
constructor(program, options = { validateLabels: true }) {
|
|
7
|
+
this.program = program;
|
|
8
|
+
this.options = options;
|
|
9
|
+
}
|
|
10
|
+
compile() {
|
|
11
|
+
const characters = {};
|
|
12
|
+
const labels = {};
|
|
13
|
+
// 1. First pass: Collect character declarations and label bodies
|
|
14
|
+
for (const stmt of this.program.statements) {
|
|
15
|
+
if (stmt.type === 'CharacterDecl') {
|
|
16
|
+
characters[stmt.id] = {
|
|
17
|
+
id: stmt.id,
|
|
18
|
+
name: stmt.displayName,
|
|
19
|
+
color: stmt.color
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
else if (stmt.type === 'LabelDecl') {
|
|
23
|
+
if (labels[stmt.name]) {
|
|
24
|
+
throw new KawaError({
|
|
25
|
+
code: 'E0201',
|
|
26
|
+
message: `Duplicate label declaration '${stmt.name}'`,
|
|
27
|
+
severity: 'error',
|
|
28
|
+
loc: stmt.loc
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
labels[stmt.name] = this.compileBlock(stmt.name, stmt.body, labels);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// 2. Validate label references if enabled
|
|
35
|
+
if (this.options.validateLabels) {
|
|
36
|
+
this.validateLabelReferences(labels);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
meta: {
|
|
40
|
+
title: 'Kawaijs Visual Novel',
|
|
41
|
+
version: '0.1.0',
|
|
42
|
+
startLabel: labels['start'] ? 'start' : Object.keys(labels)[0]
|
|
43
|
+
},
|
|
44
|
+
characters,
|
|
45
|
+
labels
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
compileBlock(currentLabel, statements, labels) {
|
|
49
|
+
const instructions = [];
|
|
50
|
+
for (const stmt of statements) {
|
|
51
|
+
switch (stmt.type) {
|
|
52
|
+
case 'SceneStmt':
|
|
53
|
+
instructions.push({
|
|
54
|
+
type: 'scene',
|
|
55
|
+
background: stmt.background,
|
|
56
|
+
transition: stmt.transition,
|
|
57
|
+
loc: stmt.loc
|
|
58
|
+
});
|
|
59
|
+
break;
|
|
60
|
+
case 'ShowStmt':
|
|
61
|
+
instructions.push({
|
|
62
|
+
type: 'show',
|
|
63
|
+
character: stmt.character,
|
|
64
|
+
expression: stmt.expression,
|
|
65
|
+
position: stmt.position,
|
|
66
|
+
transition: stmt.transition,
|
|
67
|
+
loc: stmt.loc
|
|
68
|
+
});
|
|
69
|
+
break;
|
|
70
|
+
case 'HideStmt':
|
|
71
|
+
instructions.push({
|
|
72
|
+
type: 'hide',
|
|
73
|
+
character: stmt.character,
|
|
74
|
+
transition: stmt.transition,
|
|
75
|
+
loc: stmt.loc
|
|
76
|
+
});
|
|
77
|
+
break;
|
|
78
|
+
case 'DialogueStmt':
|
|
79
|
+
instructions.push({
|
|
80
|
+
type: 'dialogue',
|
|
81
|
+
speaker: stmt.speaker,
|
|
82
|
+
text: stmt.text,
|
|
83
|
+
loc: stmt.loc
|
|
84
|
+
});
|
|
85
|
+
break;
|
|
86
|
+
case 'MenuStmt': {
|
|
87
|
+
const choiceOptions = [];
|
|
88
|
+
for (const choice of stmt.choices) {
|
|
89
|
+
this.anonymousLabelCounter += 1;
|
|
90
|
+
const syntheticLabel = `__choice_${currentLabel}_${this.anonymousLabelCounter}`;
|
|
91
|
+
// Compile choice body into its own synthetic label block
|
|
92
|
+
const choiceInstructions = this.compileBlock(syntheticLabel, choice.body, labels);
|
|
93
|
+
labels[syntheticLabel] = choiceInstructions;
|
|
94
|
+
choiceOptions.push({
|
|
95
|
+
text: choice.text,
|
|
96
|
+
targetLabel: syntheticLabel,
|
|
97
|
+
condition: choice.condition
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
instructions.push({
|
|
101
|
+
type: 'choice',
|
|
102
|
+
prompt: stmt.prompt,
|
|
103
|
+
choices: choiceOptions,
|
|
104
|
+
loc: stmt.loc
|
|
105
|
+
});
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'JumpStmt':
|
|
109
|
+
instructions.push({
|
|
110
|
+
type: 'jump',
|
|
111
|
+
targetLabel: stmt.targetLabel,
|
|
112
|
+
loc: stmt.loc
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
115
|
+
case 'ReturnStmt':
|
|
116
|
+
instructions.push({
|
|
117
|
+
type: 'return',
|
|
118
|
+
loc: stmt.loc
|
|
119
|
+
});
|
|
120
|
+
break;
|
|
121
|
+
case 'SetStmt':
|
|
122
|
+
instructions.push({
|
|
123
|
+
type: 'set',
|
|
124
|
+
variable: stmt.variable,
|
|
125
|
+
value: stmt.value,
|
|
126
|
+
loc: stmt.loc
|
|
127
|
+
});
|
|
128
|
+
break;
|
|
129
|
+
case 'IfStmt': {
|
|
130
|
+
this.anonymousLabelCounter += 1;
|
|
131
|
+
const thenLabel = `__if_then_${currentLabel}_${this.anonymousLabelCounter}`;
|
|
132
|
+
const mergeLabel = `__if_merge_${currentLabel}_${this.anonymousLabelCounter}`;
|
|
133
|
+
const thenInstructions = this.compileBlock(thenLabel, stmt.thenBranch, labels);
|
|
134
|
+
// If thenBranch doesn't end with jump or return, fall through to mergeLabel
|
|
135
|
+
thenInstructions.push({ type: 'jump', targetLabel: mergeLabel });
|
|
136
|
+
labels[thenLabel] = thenInstructions;
|
|
137
|
+
let elseLabel;
|
|
138
|
+
if (stmt.elseBranch) {
|
|
139
|
+
elseLabel = `__if_else_${currentLabel}_${this.anonymousLabelCounter}`;
|
|
140
|
+
const elseInstructions = this.compileBlock(elseLabel, stmt.elseBranch.body, labels);
|
|
141
|
+
elseInstructions.push({ type: 'jump', targetLabel: mergeLabel });
|
|
142
|
+
labels[elseLabel] = elseInstructions;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
elseLabel = mergeLabel;
|
|
146
|
+
}
|
|
147
|
+
instructions.push({
|
|
148
|
+
type: 'branch',
|
|
149
|
+
condition: stmt.condition,
|
|
150
|
+
thenLabel,
|
|
151
|
+
elseLabel,
|
|
152
|
+
loc: stmt.loc
|
|
153
|
+
});
|
|
154
|
+
// Create merge block for following instructions
|
|
155
|
+
labels[mergeLabel] = [];
|
|
156
|
+
// Switch compiling remainder of statements into mergeLabel if needed
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case 'PlayStmt':
|
|
160
|
+
instructions.push({
|
|
161
|
+
type: 'play_audio',
|
|
162
|
+
channel: stmt.channel,
|
|
163
|
+
track: stmt.track,
|
|
164
|
+
fade: stmt.fade,
|
|
165
|
+
loop: stmt.loop,
|
|
166
|
+
loc: stmt.loc
|
|
167
|
+
});
|
|
168
|
+
break;
|
|
169
|
+
case 'StopStmt':
|
|
170
|
+
instructions.push({
|
|
171
|
+
type: 'stop_audio',
|
|
172
|
+
channel: stmt.channel,
|
|
173
|
+
fade: stmt.fade,
|
|
174
|
+
loc: stmt.loc
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return instructions;
|
|
180
|
+
}
|
|
181
|
+
validateLabelReferences(labels) {
|
|
182
|
+
const knownLabels = new Set(Object.keys(labels));
|
|
183
|
+
for (const [labelName, instructions] of Object.entries(labels)) {
|
|
184
|
+
for (const inst of instructions) {
|
|
185
|
+
if (inst.type === 'jump' && !knownLabels.has(inst.targetLabel)) {
|
|
186
|
+
throw new KawaError({
|
|
187
|
+
code: 'E0202',
|
|
188
|
+
message: `Unknown label '${inst.targetLabel}' referenced in '${labelName}'`,
|
|
189
|
+
severity: 'error',
|
|
190
|
+
loc: inst.loc,
|
|
191
|
+
hint: `Available labels: ${Array.from(knownLabels).filter(l => !l.startsWith('__')).join(', ')}`
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SourceLocation } from '@kawaijs/ast';
|
|
2
|
+
export type DiagnosticSeverity = 'error' | 'warning' | 'info';
|
|
3
|
+
export interface KawaDiagnostic {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly severity: DiagnosticSeverity;
|
|
7
|
+
readonly loc?: SourceLocation;
|
|
8
|
+
readonly hint?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class KawaError extends Error {
|
|
11
|
+
readonly diagnostic: KawaDiagnostic;
|
|
12
|
+
constructor(diagnostic: KawaDiagnostic);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Formats a diagnostic into a human-friendly compiler error message with code frames.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatDiagnostic(diagnostic: KawaDiagnostic, sourceText?: string): string;
|
|
18
|
+
//# sourceMappingURL=diagnostic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;gBAExB,UAAU,EAAE,cAAc;CAKvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAiCxF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class KawaError extends Error {
|
|
2
|
+
diagnostic;
|
|
3
|
+
constructor(diagnostic) {
|
|
4
|
+
super(diagnostic.message);
|
|
5
|
+
this.name = 'KawaError';
|
|
6
|
+
this.diagnostic = diagnostic;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Formats a diagnostic into a human-friendly compiler error message with code frames.
|
|
11
|
+
*/
|
|
12
|
+
export function formatDiagnostic(diagnostic, sourceText) {
|
|
13
|
+
const prefix = `[Kawa ${diagnostic.severity.toUpperCase()}] ${diagnostic.code}: ${diagnostic.message}`;
|
|
14
|
+
if (!diagnostic.loc) {
|
|
15
|
+
return prefix;
|
|
16
|
+
}
|
|
17
|
+
const { file, start, end } = diagnostic.loc;
|
|
18
|
+
const locationHeader = ` --> ${file}:${start.line}:${start.column}`;
|
|
19
|
+
if (!sourceText) {
|
|
20
|
+
return `${prefix}\n${locationHeader}`;
|
|
21
|
+
}
|
|
22
|
+
const lines = sourceText.split(/\r?\n/);
|
|
23
|
+
const targetLineIdx = start.line - 1;
|
|
24
|
+
const lineContent = lines[targetLineIdx] ?? '';
|
|
25
|
+
const lineNumStr = String(start.line);
|
|
26
|
+
const padding = ' '.repeat(lineNumStr.length);
|
|
27
|
+
const startCol = Math.max(1, start.column);
|
|
28
|
+
const endCol = (end.line === start.line && end.column > start.column) ? end.column : startCol + 1;
|
|
29
|
+
const underlineLen = Math.max(1, endCol - startCol);
|
|
30
|
+
const caretLine = ' '.repeat(startCol - 1) + '^'.repeat(underlineLen);
|
|
31
|
+
let frame = `${prefix}\n${locationHeader}\n${padding} |\n${lineNumStr} | ${lineContent}\n${padding} | ${caretLine}`;
|
|
32
|
+
if (diagnostic.hint) {
|
|
33
|
+
frame += `\n${padding} =\n${padding} = Hint: ${diagnostic.hint}`;
|
|
34
|
+
}
|
|
35
|
+
return frame;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=diagnostic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,UAAU,CAAiB;IAEpC,YAAY,UAA0B;QACpC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA0B,EAAE,UAAmB;IAC9E,MAAM,MAAM,GAAG,SAAS,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;IAEvG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC;IAC5C,MAAM,cAAc,GAAG,QAAQ,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IAEpE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,GAAG,MAAM,KAAK,cAAc,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAE/C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;IAClG,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAEtE,IAAI,KAAK,GAAG,GAAG,MAAM,KAAK,cAAc,KAAK,OAAO,OAAO,UAAU,MAAM,WAAW,KAAK,OAAO,MAAM,SAAS,EAAE,CAAC;IAEpH,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,IAAI,KAAK,OAAO,OAAO,OAAO,YAAY,UAAU,CAAC,IAAI,EAAE,CAAC;IACnE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StoryPackage } from '@kawaijs/ast';
|
|
2
|
+
import { type LexerOptions } from './lexer.js';
|
|
3
|
+
import { type CompilerOptions } from './compiler.js';
|
|
4
|
+
export * from './token.js';
|
|
5
|
+
export * from './diagnostic.js';
|
|
6
|
+
export * from './lexer.js';
|
|
7
|
+
export * from './parser.js';
|
|
8
|
+
export * from './compiler.js';
|
|
9
|
+
/**
|
|
10
|
+
* Convenience helper to compile a raw Kawa Script string directly into a StoryPackage IR.
|
|
11
|
+
*/
|
|
12
|
+
export declare function compileScript(source: string, file?: string, options?: LexerOptions & CompilerOptions): StoryPackage;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE/D,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAE9B;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,SAAgB,EACpB,OAAO,CAAC,EAAE,YAAY,GAAG,eAAe,GACvC,YAAY,CAOd"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Lexer } from './lexer.js';
|
|
2
|
+
import { Parser } from './parser.js';
|
|
3
|
+
import { Compiler } from './compiler.js';
|
|
4
|
+
export * from './token.js';
|
|
5
|
+
export * from './diagnostic.js';
|
|
6
|
+
export * from './lexer.js';
|
|
7
|
+
export * from './parser.js';
|
|
8
|
+
export * from './compiler.js';
|
|
9
|
+
/**
|
|
10
|
+
* Convenience helper to compile a raw Kawa Script string directly into a StoryPackage IR.
|
|
11
|
+
*/
|
|
12
|
+
export function compileScript(source, file = 'script.kawa', options) {
|
|
13
|
+
const lexer = new Lexer(source, file, options);
|
|
14
|
+
const tokens = lexer.tokenize();
|
|
15
|
+
const parser = new Parser(tokens, file);
|
|
16
|
+
const ast = parser.parse();
|
|
17
|
+
const compiler = new Compiler(ast, options);
|
|
18
|
+
return compiler.compile();
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAqB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAwB,MAAM,eAAe,CAAC;AAE/D,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAE9B;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,IAAI,GAAG,aAAa,EACpB,OAAwC;IAExC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/lexer.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Token } from './token.js';
|
|
2
|
+
export interface LexerOptions {
|
|
3
|
+
tabSize?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class Lexer {
|
|
6
|
+
private readonly source;
|
|
7
|
+
private readonly file;
|
|
8
|
+
private readonly tabSize;
|
|
9
|
+
private cursor;
|
|
10
|
+
private line;
|
|
11
|
+
private column;
|
|
12
|
+
private indentStack;
|
|
13
|
+
private pendingTokens;
|
|
14
|
+
private isAtLineStart;
|
|
15
|
+
private hasTokensOnCurrentLine;
|
|
16
|
+
constructor(source: string, file?: string, options?: LexerOptions);
|
|
17
|
+
tokenize(): Token[];
|
|
18
|
+
nextToken(): Token;
|
|
19
|
+
private handleIndentation;
|
|
20
|
+
private readString;
|
|
21
|
+
private readNumber;
|
|
22
|
+
private readIdentifier;
|
|
23
|
+
private skipComment;
|
|
24
|
+
private peek;
|
|
25
|
+
private advance;
|
|
26
|
+
private isEof;
|
|
27
|
+
private isDigit;
|
|
28
|
+
private isAlpha;
|
|
29
|
+
private isAlphaNumeric;
|
|
30
|
+
private getCurrentPosition;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=lexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../src/lexer.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IAEnB,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,sBAAsB,CAAS;gBAE3B,MAAM,EAAE,MAAM,EAAE,IAAI,SAAgB,EAAE,OAAO,GAAE,YAAiB;IAMrE,QAAQ,IAAI,KAAK,EAAE;IAYnB,SAAS,IAAI,KAAK;IAmIzB,OAAO,CAAC,iBAAiB;IA2DzB,OAAO,CAAC,UAAU;IAoDlB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,kBAAkB;CAG3B"}
|