yarn-spinner-runner-ts 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/README.md +180 -0
- package/dist/compile/compiler.d.ts +9 -0
- package/dist/compile/compiler.js +172 -0
- package/dist/compile/compiler.js.map +1 -0
- package/dist/compile/ir.d.ts +47 -0
- package/dist/compile/ir.js +2 -0
- package/dist/compile/ir.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/model/ast.d.ts +72 -0
- package/dist/model/ast.js +2 -0
- package/dist/model/ast.js.map +1 -0
- package/dist/parse/lexer.d.ts +7 -0
- package/dist/parse/lexer.js +78 -0
- package/dist/parse/lexer.js.map +1 -0
- package/dist/parse/parser.d.ts +4 -0
- package/dist/parse/parser.js +433 -0
- package/dist/parse/parser.js.map +1 -0
- package/dist/runtime/commands.d.ts +31 -0
- package/dist/runtime/commands.js +157 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/evaluator.d.ts +52 -0
- package/dist/runtime/evaluator.js +309 -0
- package/dist/runtime/evaluator.js.map +1 -0
- package/dist/runtime/results.d.ts +22 -0
- package/dist/runtime/results.js +2 -0
- package/dist/runtime/results.js.map +1 -0
- package/dist/runtime/runner.d.ts +63 -0
- package/dist/runtime/runner.js +456 -0
- package/dist/runtime/runner.js.map +1 -0
- package/dist/tests/full_featured.test.d.ts +1 -0
- package/dist/tests/full_featured.test.js +130 -0
- package/dist/tests/full_featured.test.js.map +1 -0
- package/dist/tests/index.test.d.ts +1 -0
- package/dist/tests/index.test.js +30 -0
- package/dist/tests/index.test.js.map +1 -0
- package/dist/tests/jump_detour.test.d.ts +1 -0
- package/dist/tests/jump_detour.test.js +47 -0
- package/dist/tests/jump_detour.test.js.map +1 -0
- package/dist/tests/nodes_lines.test.d.ts +1 -0
- package/dist/tests/nodes_lines.test.js +23 -0
- package/dist/tests/nodes_lines.test.js.map +1 -0
- package/dist/tests/once.test.d.ts +1 -0
- package/dist/tests/once.test.js +29 -0
- package/dist/tests/once.test.js.map +1 -0
- package/dist/tests/options.test.d.ts +1 -0
- package/dist/tests/options.test.js +32 -0
- package/dist/tests/options.test.js.map +1 -0
- package/dist/tests/variables_flow_cmds.test.d.ts +1 -0
- package/dist/tests/variables_flow_cmds.test.js +30 -0
- package/dist/tests/variables_flow_cmds.test.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/commands.md +21 -0
- package/docs/compatibility-checklist.md +77 -0
- package/docs/css-attribute.md +47 -0
- package/docs/detour.md +24 -0
- package/docs/enums.md +25 -0
- package/docs/flow-control.md +25 -0
- package/docs/functions.md +20 -0
- package/docs/jumps.md +24 -0
- package/docs/line-groups.md +21 -0
- package/docs/lines-nodes-and-options.md +30 -0
- package/docs/logic-and-variables.md +25 -0
- package/docs/markup.md +19 -0
- package/docs/node-groups.md +13 -0
- package/docs/once.md +21 -0
- package/docs/options.md +45 -0
- package/docs/saliency.md +25 -0
- package/docs/scenes-actors-setup.md +195 -0
- package/docs/scenes.md +64 -0
- package/docs/shadow-lines.md +18 -0
- package/docs/smart-variables.md +19 -0
- package/docs/storylets-and-saliency-a-primer.md +14 -0
- package/docs/tags-metadata.md +18 -0
- package/eslint.config.cjs +33 -0
- package/examples/browser/README.md +40 -0
- package/examples/browser/index.html +23 -0
- package/examples/browser/main.tsx +16 -0
- package/examples/browser/vite.config.ts +22 -0
- package/examples/react/DialogueExample.tsx +2 -0
- package/examples/react/DialogueView.tsx +2 -0
- package/examples/react/useYarnRunner.tsx +2 -0
- package/examples/scenes/scenes.yaml +10 -0
- package/examples/yarn/full_featured.yarn +43 -0
- package/package.json +55 -0
- package/src/compile/compiler.ts +183 -0
- package/src/compile/ir.ts +28 -0
- package/src/index.ts +17 -0
- package/src/model/ast.ts +93 -0
- package/src/parse/lexer.ts +108 -0
- package/src/parse/parser.ts +435 -0
- package/src/react/DialogueExample.tsx +149 -0
- package/src/react/DialogueScene.tsx +107 -0
- package/src/react/DialogueView.tsx +160 -0
- package/src/react/dialogue.css +181 -0
- package/src/react/useYarnRunner.tsx +33 -0
- package/src/runtime/commands.ts +183 -0
- package/src/runtime/evaluator.ts +327 -0
- package/src/runtime/results.ts +27 -0
- package/src/runtime/runner.ts +480 -0
- package/src/scene/parser.ts +83 -0
- package/src/scene/types.ts +17 -0
- package/src/tests/full_featured.test.ts +131 -0
- package/src/tests/index.test.ts +34 -0
- package/src/tests/jump_detour.test.ts +47 -0
- package/src/tests/nodes_lines.test.ts +27 -0
- package/src/tests/once.test.ts +32 -0
- package/src/tests/options.test.ts +34 -0
- package/src/tests/variables_flow_cmds.test.ts +33 -0
- package/src/types.ts +4 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import { lex } from "./lexer.js";
|
|
2
|
+
export class ParseError extends Error {
|
|
3
|
+
}
|
|
4
|
+
export function parseYarn(text) {
|
|
5
|
+
const tokens = lex(text);
|
|
6
|
+
const p = new Parser(tokens);
|
|
7
|
+
return p.parseDocument();
|
|
8
|
+
}
|
|
9
|
+
class Parser {
|
|
10
|
+
constructor(tokens) {
|
|
11
|
+
this.tokens = tokens;
|
|
12
|
+
this.i = 0;
|
|
13
|
+
}
|
|
14
|
+
peek(offset = 0) {
|
|
15
|
+
return this.tokens[this.i + offset];
|
|
16
|
+
}
|
|
17
|
+
at(type) {
|
|
18
|
+
return this.peek()?.type === type;
|
|
19
|
+
}
|
|
20
|
+
take(type, err) {
|
|
21
|
+
const t = this.peek();
|
|
22
|
+
if (!t || t.type !== type)
|
|
23
|
+
throw new ParseError(err ?? `Expected ${type}, got ${t?.type}`);
|
|
24
|
+
this.i++;
|
|
25
|
+
return t;
|
|
26
|
+
}
|
|
27
|
+
takeIf(type) {
|
|
28
|
+
if (this.at(type))
|
|
29
|
+
return this.take(type);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
parseDocument() {
|
|
33
|
+
const enums = [];
|
|
34
|
+
const nodes = [];
|
|
35
|
+
while (!this.at("EOF")) {
|
|
36
|
+
// Skip empties
|
|
37
|
+
while (this.at("EMPTY"))
|
|
38
|
+
this.i++;
|
|
39
|
+
if (this.at("EOF"))
|
|
40
|
+
break;
|
|
41
|
+
// Check if this is an enum definition (top-level)
|
|
42
|
+
if (this.at("COMMAND")) {
|
|
43
|
+
const cmd = this.peek().text.trim();
|
|
44
|
+
if (cmd.startsWith("enum ")) {
|
|
45
|
+
const enumCmd = this.take("COMMAND").text; // consume the enum command
|
|
46
|
+
const enumName = enumCmd.slice(5).trim();
|
|
47
|
+
const enumDef = this.parseEnumBlock(enumName);
|
|
48
|
+
enums.push(enumDef);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
nodes.push(this.parseNode());
|
|
53
|
+
}
|
|
54
|
+
return { type: "Document", enums, nodes };
|
|
55
|
+
}
|
|
56
|
+
parseNode() {
|
|
57
|
+
const headers = {};
|
|
58
|
+
let title = null;
|
|
59
|
+
let nodeTags;
|
|
60
|
+
let whenConditions = [];
|
|
61
|
+
let nodeCss;
|
|
62
|
+
// headers
|
|
63
|
+
while (!this.at("NODE_START")) {
|
|
64
|
+
const keyTok = this.take("HEADER_KEY", "Expected node header before '---'");
|
|
65
|
+
const valTok = this.take("HEADER_VALUE", "Expected header value");
|
|
66
|
+
if (keyTok.text === "title")
|
|
67
|
+
title = valTok.text.trim();
|
|
68
|
+
if (keyTok.text === "tags") {
|
|
69
|
+
const raw = valTok.text.trim();
|
|
70
|
+
nodeTags = raw.split(/\s+/).filter(Boolean);
|
|
71
|
+
}
|
|
72
|
+
if (keyTok.text === "when") {
|
|
73
|
+
// Each when: header adds one condition (can have multiple when: headers)
|
|
74
|
+
const raw = valTok.text.trim();
|
|
75
|
+
whenConditions.push(raw);
|
|
76
|
+
}
|
|
77
|
+
// Capture &css{ ... } styles in any header value
|
|
78
|
+
const rawVal = valTok.text.trim();
|
|
79
|
+
if (rawVal.startsWith("&css{")) {
|
|
80
|
+
// Collect until closing '}' possibly spanning multiple lines before '---'
|
|
81
|
+
let cssContent = rawVal.replace(/^&css\{/, "");
|
|
82
|
+
let closed = cssContent.includes("}");
|
|
83
|
+
if (closed) {
|
|
84
|
+
cssContent = cssContent.split("}")[0];
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Consume subsequent TEXT or HEADER_VALUE tokens until we find a '}'
|
|
88
|
+
while (!this.at("NODE_START") && !this.at("EOF")) {
|
|
89
|
+
const next = this.peek();
|
|
90
|
+
if (next.type === "TEXT" || next.type === "HEADER_VALUE") {
|
|
91
|
+
const t = this.take(next.type).text;
|
|
92
|
+
if (t.includes("}")) {
|
|
93
|
+
cssContent += (cssContent ? "\n" : "") + t.split("}")[0];
|
|
94
|
+
closed = true;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
cssContent += (cssContent ? "\n" : "") + t;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (next.type === "EMPTY") {
|
|
102
|
+
this.i++;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
nodeCss = (cssContent || "").trim();
|
|
110
|
+
}
|
|
111
|
+
headers[keyTok.text] = valTok.text;
|
|
112
|
+
// allow empty lines
|
|
113
|
+
while (this.at("EMPTY"))
|
|
114
|
+
this.i++;
|
|
115
|
+
}
|
|
116
|
+
if (!title)
|
|
117
|
+
throw new ParseError("Every node must have a title header");
|
|
118
|
+
this.take("NODE_START");
|
|
119
|
+
// allow optional empties after ---
|
|
120
|
+
while (this.at("EMPTY"))
|
|
121
|
+
this.i++;
|
|
122
|
+
const body = this.parseStatementsUntil("NODE_END");
|
|
123
|
+
this.take("NODE_END", "Expected node end '==='");
|
|
124
|
+
return {
|
|
125
|
+
type: "Node",
|
|
126
|
+
title,
|
|
127
|
+
headers,
|
|
128
|
+
nodeTags,
|
|
129
|
+
when: whenConditions.length > 0 ? whenConditions : undefined,
|
|
130
|
+
css: nodeCss,
|
|
131
|
+
body
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
parseStatementsUntil(endType) {
|
|
135
|
+
const out = [];
|
|
136
|
+
while (!this.at(endType) && !this.at("EOF")) {
|
|
137
|
+
// skip extra empties
|
|
138
|
+
while (this.at("EMPTY"))
|
|
139
|
+
this.i++;
|
|
140
|
+
if (this.at(endType) || this.at("EOF"))
|
|
141
|
+
break;
|
|
142
|
+
if (this.at("OPTION")) {
|
|
143
|
+
out.push(this.parseOptionGroup());
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const stmt = this.parseStatement();
|
|
147
|
+
out.push(stmt);
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
parseStatement() {
|
|
152
|
+
const t = this.peek();
|
|
153
|
+
if (!t)
|
|
154
|
+
throw new ParseError("Unexpected EOF");
|
|
155
|
+
if (t.type === "COMMAND") {
|
|
156
|
+
const cmd = this.take("COMMAND").text;
|
|
157
|
+
if (cmd.startsWith("jump "))
|
|
158
|
+
return { type: "Jump", target: cmd.slice(5).trim() };
|
|
159
|
+
if (cmd.startsWith("detour "))
|
|
160
|
+
return { type: "Detour", target: cmd.slice(7).trim() };
|
|
161
|
+
if (cmd.startsWith("if "))
|
|
162
|
+
return this.parseIfCommandBlock(cmd);
|
|
163
|
+
if (cmd === "once")
|
|
164
|
+
return this.parseOnceBlock();
|
|
165
|
+
if (cmd.startsWith("enum ")) {
|
|
166
|
+
const enumName = cmd.slice(5).trim();
|
|
167
|
+
return this.parseEnumBlock(enumName);
|
|
168
|
+
}
|
|
169
|
+
return { type: "Command", content: cmd };
|
|
170
|
+
}
|
|
171
|
+
if (t.type === "TEXT") {
|
|
172
|
+
const raw = this.take("TEXT").text;
|
|
173
|
+
const { cleanText: text, tags } = this.extractTags(raw);
|
|
174
|
+
const speakerMatch = text.match(/^([^:\s][^:]*)\s*:\s*(.*)$/);
|
|
175
|
+
if (speakerMatch) {
|
|
176
|
+
return { type: "Line", speaker: speakerMatch[1].trim(), text: speakerMatch[2], tags };
|
|
177
|
+
}
|
|
178
|
+
// If/Else blocks use inline markup {if ...}
|
|
179
|
+
const trimmed = text.trim();
|
|
180
|
+
if (trimmed.startsWith("{if ") || trimmed === "{else}" || trimmed.startsWith("{else if ") || trimmed === "{endif}") {
|
|
181
|
+
return this.parseIfFromText(text);
|
|
182
|
+
}
|
|
183
|
+
return { type: "Line", text, tags };
|
|
184
|
+
}
|
|
185
|
+
throw new ParseError(`Unexpected token ${t.type}`);
|
|
186
|
+
}
|
|
187
|
+
parseOptionGroup() {
|
|
188
|
+
const options = [];
|
|
189
|
+
// One or more OPTION lines, with bodies under INDENT
|
|
190
|
+
while (this.at("OPTION")) {
|
|
191
|
+
const raw = this.take("OPTION").text;
|
|
192
|
+
const { cleanText: textWithAttrs, tags } = this.extractTags(raw);
|
|
193
|
+
const { text, css } = this.extractCss(textWithAttrs);
|
|
194
|
+
let body = [];
|
|
195
|
+
if (this.at("INDENT")) {
|
|
196
|
+
this.take("INDENT");
|
|
197
|
+
body = this.parseStatementsUntil("DEDENT");
|
|
198
|
+
this.take("DEDENT");
|
|
199
|
+
while (this.at("EMPTY"))
|
|
200
|
+
this.i++;
|
|
201
|
+
}
|
|
202
|
+
options.push({ type: "Option", text, body, tags, css });
|
|
203
|
+
// Consecutive options belong to the same group; break on non-OPTION
|
|
204
|
+
while (this.at("EMPTY"))
|
|
205
|
+
this.i++;
|
|
206
|
+
}
|
|
207
|
+
return { type: "OptionGroup", options };
|
|
208
|
+
}
|
|
209
|
+
extractTags(input) {
|
|
210
|
+
const tags = [];
|
|
211
|
+
const re = /\s#([^\s]+)/g;
|
|
212
|
+
let text = input;
|
|
213
|
+
let m;
|
|
214
|
+
while ((m = re.exec(input))) {
|
|
215
|
+
tags.push(m[1]);
|
|
216
|
+
}
|
|
217
|
+
if (tags.length > 0) {
|
|
218
|
+
text = input.replace(/\s#([^\s]+)/g, "").trimEnd();
|
|
219
|
+
return { cleanText: text, tags };
|
|
220
|
+
}
|
|
221
|
+
return { cleanText: input };
|
|
222
|
+
}
|
|
223
|
+
extractCss(input) {
|
|
224
|
+
const cssMatch = input.match(/\s*&css\{([^}]*)\}\s*$/);
|
|
225
|
+
if (cssMatch) {
|
|
226
|
+
const css = cssMatch[1].trim();
|
|
227
|
+
const text = input.replace(cssMatch[0], "").trimEnd();
|
|
228
|
+
return { text, css };
|
|
229
|
+
}
|
|
230
|
+
return { text: input };
|
|
231
|
+
}
|
|
232
|
+
parseStatementsUntilStop(shouldStop) {
|
|
233
|
+
const out = [];
|
|
234
|
+
while (!this.at("EOF")) {
|
|
235
|
+
// Check stop condition at root level only
|
|
236
|
+
if (shouldStop())
|
|
237
|
+
break;
|
|
238
|
+
while (this.at("EMPTY"))
|
|
239
|
+
this.i++;
|
|
240
|
+
if (this.at("EOF") || shouldStop())
|
|
241
|
+
break;
|
|
242
|
+
// Handle indentation - if we see INDENT, parse the indented block
|
|
243
|
+
if (this.at("INDENT")) {
|
|
244
|
+
this.take("INDENT");
|
|
245
|
+
// Parse statements at this indent level until DEDENT (don't check stop condition inside)
|
|
246
|
+
while (!this.at("DEDENT") && !this.at("EOF")) {
|
|
247
|
+
while (this.at("EMPTY"))
|
|
248
|
+
this.i++;
|
|
249
|
+
if (this.at("DEDENT") || this.at("EOF"))
|
|
250
|
+
break;
|
|
251
|
+
if (this.at("OPTION")) {
|
|
252
|
+
out.push(this.parseOptionGroup());
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
out.push(this.parseStatement());
|
|
256
|
+
}
|
|
257
|
+
if (this.at("DEDENT")) {
|
|
258
|
+
this.take("DEDENT");
|
|
259
|
+
while (this.at("EMPTY"))
|
|
260
|
+
this.i++;
|
|
261
|
+
}
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (this.at("OPTION")) {
|
|
265
|
+
out.push(this.parseOptionGroup());
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
out.push(this.parseStatement());
|
|
269
|
+
}
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
parseOnceBlock() {
|
|
273
|
+
// Already consumed <<once>>; expect body under INDENT then <<endonce>> as COMMAND
|
|
274
|
+
let body = [];
|
|
275
|
+
if (this.at("INDENT")) {
|
|
276
|
+
this.take("INDENT");
|
|
277
|
+
body = this.parseStatementsUntil("DEDENT");
|
|
278
|
+
this.take("DEDENT");
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Alternatively, body until explicit <<endonce>> command on single line
|
|
282
|
+
body = [];
|
|
283
|
+
}
|
|
284
|
+
// consume closing command if present on own line
|
|
285
|
+
if (this.at("COMMAND") && this.peek().text === "endonce") {
|
|
286
|
+
this.take("COMMAND");
|
|
287
|
+
}
|
|
288
|
+
return { type: "Once", body };
|
|
289
|
+
}
|
|
290
|
+
parseIfFromText(firstLine) {
|
|
291
|
+
const branches = [];
|
|
292
|
+
// expecting state not required in current implementation
|
|
293
|
+
let cursor = firstLine.trim();
|
|
294
|
+
function parseCond(text) {
|
|
295
|
+
const mIf = text.match(/^\{if\s+(.+?)\}$/);
|
|
296
|
+
if (mIf)
|
|
297
|
+
return mIf[1];
|
|
298
|
+
const mElIf = text.match(/^\{else\s+if\s+(.+?)\}$/);
|
|
299
|
+
if (mElIf)
|
|
300
|
+
return mElIf[1];
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
while (true) {
|
|
304
|
+
const cond = parseCond(cursor);
|
|
305
|
+
if (cursor === "{else}") {
|
|
306
|
+
branches.push({ condition: null, body: this.parseIfBlockBody() });
|
|
307
|
+
// next must be {endif}
|
|
308
|
+
const endLine = this.take("TEXT", "Expected {endif}").text.trim();
|
|
309
|
+
if (endLine !== "{endif}")
|
|
310
|
+
throw new ParseError("Expected {endif}");
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
else if (cond) {
|
|
314
|
+
branches.push({ condition: cond, body: this.parseIfBlockBody() });
|
|
315
|
+
// next control line
|
|
316
|
+
const next = this.take("TEXT", "Expected {else}, {else if}, or {endif}").text.trim();
|
|
317
|
+
if (next === "{endif}")
|
|
318
|
+
break;
|
|
319
|
+
cursor = next;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
else if (cursor === "{endif}") {
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
throw new ParseError("Invalid if/else control line");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { type: "If", branches };
|
|
330
|
+
}
|
|
331
|
+
parseEnumBlock(enumName) {
|
|
332
|
+
const cases = [];
|
|
333
|
+
// Parse cases until <<endenum>>
|
|
334
|
+
while (!this.at("EOF")) {
|
|
335
|
+
while (this.at("EMPTY"))
|
|
336
|
+
this.i++;
|
|
337
|
+
if (this.at("COMMAND")) {
|
|
338
|
+
const cmd = this.peek().text.trim();
|
|
339
|
+
if (cmd === "endenum") {
|
|
340
|
+
this.take("COMMAND");
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
if (cmd.startsWith("case ")) {
|
|
344
|
+
this.take("COMMAND");
|
|
345
|
+
const caseName = cmd.slice(5).trim();
|
|
346
|
+
cases.push(caseName);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
// Unknown command, might be inside enum block - skip or break?
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
// Skip non-command lines
|
|
355
|
+
if (this.at("TEXT"))
|
|
356
|
+
this.take("TEXT");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return { type: "Enum", name: enumName, cases };
|
|
360
|
+
}
|
|
361
|
+
parseIfCommandBlock(firstCmd) {
|
|
362
|
+
const branches = [];
|
|
363
|
+
const firstCond = firstCmd.slice(3).trim();
|
|
364
|
+
// Body until next elseif/else/endif command (check at root level, not inside indented blocks)
|
|
365
|
+
const firstBody = this.parseStatementsUntilStop(() => {
|
|
366
|
+
// Only stop at root level commands, not inside indented blocks
|
|
367
|
+
return this.at("COMMAND") && /^(elseif\s|else$|endif$)/.test(this.peek().text);
|
|
368
|
+
});
|
|
369
|
+
branches.push({ condition: firstCond, body: firstBody });
|
|
370
|
+
while (!this.at("EOF")) {
|
|
371
|
+
if (!this.at("COMMAND"))
|
|
372
|
+
break;
|
|
373
|
+
const t = this.peek();
|
|
374
|
+
const txt = t.text.trim();
|
|
375
|
+
if (txt.startsWith("elseif ")) {
|
|
376
|
+
this.take("COMMAND");
|
|
377
|
+
const cond = txt.slice(7).trim();
|
|
378
|
+
const body = this.parseStatementsUntilStop(() => this.at("COMMAND") && /^(elseif\s|else$|endif$)/.test(this.peek().text));
|
|
379
|
+
branches.push({ condition: cond, body });
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (txt === "else") {
|
|
383
|
+
this.take("COMMAND");
|
|
384
|
+
const body = this.parseStatementsUntilStop(() => this.at("COMMAND") && /^(endif$)/.test(this.peek().text));
|
|
385
|
+
branches.push({ condition: null, body });
|
|
386
|
+
// require endif after else body
|
|
387
|
+
if (this.at("COMMAND") && this.peek().text.trim() === "endif") {
|
|
388
|
+
this.take("COMMAND");
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
if (txt === "endif") {
|
|
393
|
+
this.take("COMMAND");
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
return { type: "If", branches };
|
|
399
|
+
}
|
|
400
|
+
parseIfBlockBody() {
|
|
401
|
+
// Body is indented lines until next control line or DEDENT boundary; to keep this simple
|
|
402
|
+
// we consume subsequent lines until encountering a control TEXT or EOF/OPTION/NODE_END.
|
|
403
|
+
const body = [];
|
|
404
|
+
while (!this.at("EOF") && !this.at("NODE_END")) {
|
|
405
|
+
// Stop when next TEXT is a control or when OPTION starts (new group)
|
|
406
|
+
if (this.at("TEXT")) {
|
|
407
|
+
const look = this.peek().text.trim();
|
|
408
|
+
if (look === "{else}" || look === "{endif}" || look.startsWith("{else if ") || look.startsWith("{if "))
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
if (this.at("OPTION"))
|
|
412
|
+
break;
|
|
413
|
+
// Support indented bodies inside if-branches
|
|
414
|
+
if (this.at("INDENT")) {
|
|
415
|
+
this.take("INDENT");
|
|
416
|
+
const nested = this.parseStatementsUntil("DEDENT");
|
|
417
|
+
this.take("DEDENT");
|
|
418
|
+
body.push(...nested);
|
|
419
|
+
// continue scanning after dedent
|
|
420
|
+
while (this.at("EMPTY"))
|
|
421
|
+
this.i++;
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
if (this.at("EMPTY")) {
|
|
425
|
+
this.i++;
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
body.push(this.parseStatement());
|
|
429
|
+
}
|
|
430
|
+
return body;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parse/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command parser and handler utilities for Yarn Spinner commands.
|
|
3
|
+
* Commands like <<command_name arg1 arg2>> or <<command_name "arg with spaces">>
|
|
4
|
+
*/
|
|
5
|
+
import type { ExpressionEvaluator as Evaluator } from "./evaluator";
|
|
6
|
+
export interface ParsedCommand {
|
|
7
|
+
name: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
raw: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse a command string like "command_name arg1 arg2" or "set variable value"
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseCommand(content: string): ParsedCommand;
|
|
15
|
+
/**
|
|
16
|
+
* Built-in command handlers for common Yarn Spinner commands.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CommandHandler {
|
|
19
|
+
private handlers;
|
|
20
|
+
private variables;
|
|
21
|
+
constructor(variables?: Record<string, unknown>);
|
|
22
|
+
/**
|
|
23
|
+
* Register a command handler.
|
|
24
|
+
*/
|
|
25
|
+
register(name: string, handler: (args: string[], evaluator?: Evaluator) => void | Promise<void>): void;
|
|
26
|
+
/**
|
|
27
|
+
* Execute a parsed command.
|
|
28
|
+
*/
|
|
29
|
+
execute(parsed: ParsedCommand, evaluator?: Evaluator): Promise<void>;
|
|
30
|
+
private registerBuiltins;
|
|
31
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command parser and handler utilities for Yarn Spinner commands.
|
|
3
|
+
* Commands like <<command_name arg1 arg2>> or <<command_name "arg with spaces">>
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Parse a command string like "command_name arg1 arg2" or "set variable value"
|
|
7
|
+
*/
|
|
8
|
+
export function parseCommand(content) {
|
|
9
|
+
const trimmed = content.trim();
|
|
10
|
+
if (!trimmed) {
|
|
11
|
+
throw new Error("Empty command");
|
|
12
|
+
}
|
|
13
|
+
const parts = [];
|
|
14
|
+
let current = "";
|
|
15
|
+
let inQuotes = false;
|
|
16
|
+
let quoteChar = "";
|
|
17
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
18
|
+
const char = trimmed[i];
|
|
19
|
+
if ((char === '"' || char === "'") && !inQuotes) {
|
|
20
|
+
inQuotes = true;
|
|
21
|
+
quoteChar = char;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (char === quoteChar && inQuotes) {
|
|
25
|
+
inQuotes = false;
|
|
26
|
+
quoteChar = "";
|
|
27
|
+
parts.push(current);
|
|
28
|
+
current = "";
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (char === " " && !inQuotes) {
|
|
32
|
+
if (current.trim()) {
|
|
33
|
+
parts.push(current.trim());
|
|
34
|
+
current = "";
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
current += char;
|
|
39
|
+
}
|
|
40
|
+
if (current.trim()) {
|
|
41
|
+
parts.push(current.trim());
|
|
42
|
+
}
|
|
43
|
+
if (parts.length === 0) {
|
|
44
|
+
throw new Error("No command name found");
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
name: parts[0],
|
|
48
|
+
args: parts.slice(1),
|
|
49
|
+
raw: content,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Built-in command handlers for common Yarn Spinner commands.
|
|
54
|
+
*/
|
|
55
|
+
export class CommandHandler {
|
|
56
|
+
constructor(variables = {}) {
|
|
57
|
+
this.handlers = new Map();
|
|
58
|
+
this.variables = variables;
|
|
59
|
+
this.registerBuiltins();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Register a command handler.
|
|
63
|
+
*/
|
|
64
|
+
register(name, handler) {
|
|
65
|
+
this.handlers.set(name.toLowerCase(), handler);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Execute a parsed command.
|
|
69
|
+
*/
|
|
70
|
+
async execute(parsed, evaluator) {
|
|
71
|
+
const handler = this.handlers.get(parsed.name.toLowerCase());
|
|
72
|
+
if (handler) {
|
|
73
|
+
await handler(parsed.args, evaluator);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.warn(`Unknown command: ${parsed.name}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
registerBuiltins() {
|
|
80
|
+
// <<set $var to expr>> or <<set $var = expr>> or <<set $var expr>>
|
|
81
|
+
this.register("set", (args, evaluator) => {
|
|
82
|
+
if (!evaluator)
|
|
83
|
+
return;
|
|
84
|
+
if (args.length < 2)
|
|
85
|
+
return;
|
|
86
|
+
const varNameRaw = args[0];
|
|
87
|
+
let exprParts = args.slice(1);
|
|
88
|
+
if (exprParts[0] === "to")
|
|
89
|
+
exprParts = exprParts.slice(1);
|
|
90
|
+
if (exprParts[0] === "=")
|
|
91
|
+
exprParts = exprParts.slice(1);
|
|
92
|
+
const expr = exprParts.join(" ");
|
|
93
|
+
let value = evaluator.evaluateExpression(expr);
|
|
94
|
+
// If value is a string starting with ".", try to resolve as enum shorthand
|
|
95
|
+
if (typeof value === "string" && value.startsWith(".")) {
|
|
96
|
+
const enumType = evaluator.getEnumTypeForVariable(varNameRaw);
|
|
97
|
+
if (enumType) {
|
|
98
|
+
value = evaluator.resolveEnumValue(value, enumType);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const key = varNameRaw.startsWith("$") ? varNameRaw.slice(1) : varNameRaw;
|
|
102
|
+
// Setting a variable converts it from smart to regular
|
|
103
|
+
this.variables[key] = value;
|
|
104
|
+
evaluator.setVariable(key, value);
|
|
105
|
+
});
|
|
106
|
+
// <<declare $var = expr>>
|
|
107
|
+
this.register("declare", (args, evaluator) => {
|
|
108
|
+
if (!evaluator)
|
|
109
|
+
return;
|
|
110
|
+
if (args.length < 3)
|
|
111
|
+
return; // name, '=', expr
|
|
112
|
+
const varNameRaw = args[0];
|
|
113
|
+
let exprParts = args.slice(1);
|
|
114
|
+
if (exprParts[0] === "=")
|
|
115
|
+
exprParts = exprParts.slice(1);
|
|
116
|
+
const expr = exprParts.join(" ");
|
|
117
|
+
const key = varNameRaw.startsWith("$") ? varNameRaw.slice(1) : varNameRaw;
|
|
118
|
+
// Check if expression is "smart" (contains operators, comparisons, or variable references)
|
|
119
|
+
// Smart variables: expressions with operators, comparisons, logical ops, or function calls
|
|
120
|
+
const isSmart = /[+\-*/%<>=!&|]/.test(expr) ||
|
|
121
|
+
/\$\w+/.test(expr) || // references other variables
|
|
122
|
+
/[a-zA-Z_]\w*\s*\(/.test(expr); // function calls
|
|
123
|
+
if (isSmart) {
|
|
124
|
+
// Store as smart variable - will recalculate on each access
|
|
125
|
+
evaluator.setSmartVariable(key, expr);
|
|
126
|
+
// Also store initial value in variables for immediate use
|
|
127
|
+
const initialValue = evaluator.evaluateExpression(expr);
|
|
128
|
+
this.variables[key] = initialValue;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// Regular variable - evaluate once and store
|
|
132
|
+
let value = evaluator.evaluateExpression(expr);
|
|
133
|
+
// Check if expr is an enum value (EnumName.CaseName or .CaseName)
|
|
134
|
+
if (typeof value === "string") {
|
|
135
|
+
// Try to extract enum name from EnumName.CaseName
|
|
136
|
+
const enumMatch = expr.match(/^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/);
|
|
137
|
+
if (enumMatch) {
|
|
138
|
+
const enumName = enumMatch[1];
|
|
139
|
+
value = evaluator.resolveEnumValue(expr, enumName);
|
|
140
|
+
}
|
|
141
|
+
else if (value.startsWith(".")) {
|
|
142
|
+
// Shorthand - we can't infer enum type from declaration alone
|
|
143
|
+
// Store as-is, will be resolved on first use if variable has enum type
|
|
144
|
+
value = value;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
this.variables[key] = value;
|
|
148
|
+
evaluator.setVariable(key, value);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// <<stop>> - no-op, just a marker
|
|
152
|
+
this.register("stop", () => {
|
|
153
|
+
// Dialogue stop marker
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/runtime/commands.ts"],"names":[],"mappings":"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"}
|