@kumikijs/compiler 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 +34 -0
- package/dist/index.d.ts +472 -0
- package/dist/index.js +3400 -0
- package/dist/node.d.ts +8 -0
- package/dist/node.js +12 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @kumikijs/compiler
|
|
2
|
+
|
|
3
|
+
Kumiki compiler — lexer, parser, typechecker, and code generator. Part of [Kumiki](https://github.com/kage1020/Kumiki), an AI-first web framework language.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i @kumikijs/compiler
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { check, compile, lex, parse } from "@kumikijs/compiler";
|
|
15
|
+
|
|
16
|
+
// Type-check a .kumiki source (returns diagnostics)
|
|
17
|
+
const diagnostics = check(source);
|
|
18
|
+
|
|
19
|
+
// Compile a source into a runnable HTML app
|
|
20
|
+
const result = compile(source);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
To inline the runtime bundle from disk in a Node environment, use the `./node` subpath:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { compile } from "@kumikijs/compiler";
|
|
27
|
+
import { nodeRuntimeBundleReader } from "@kumikijs/compiler/node";
|
|
28
|
+
|
|
29
|
+
const result = compile(source, { bundle: true, readRuntimeBundle: nodeRuntimeBundleReader });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## License
|
|
33
|
+
|
|
34
|
+
Apache-2.0
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
//#region src/ast.d.ts
|
|
2
|
+
type Pos = {
|
|
3
|
+
line: number;
|
|
4
|
+
col: number;
|
|
5
|
+
};
|
|
6
|
+
type Token = {
|
|
7
|
+
kind: "ident";
|
|
8
|
+
value: string;
|
|
9
|
+
pos: Pos;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "kw";
|
|
12
|
+
value: string;
|
|
13
|
+
pos: Pos;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "num";
|
|
16
|
+
value: number;
|
|
17
|
+
pos: Pos;
|
|
18
|
+
} | {
|
|
19
|
+
kind: "str";
|
|
20
|
+
value: string;
|
|
21
|
+
pos: Pos;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "op";
|
|
24
|
+
value: string;
|
|
25
|
+
pos: Pos;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "eof";
|
|
28
|
+
pos: Pos;
|
|
29
|
+
};
|
|
30
|
+
type Program = {
|
|
31
|
+
kind: "Program";
|
|
32
|
+
defs: Def[];
|
|
33
|
+
};
|
|
34
|
+
type Def = TypeDef | SlotDef | ReducerDef | TileDef | FnDef | EffectDef | AppDef | ThemeDef;
|
|
35
|
+
type ThemeValue = string | number | {
|
|
36
|
+
[k: string]: ThemeValue;
|
|
37
|
+
};
|
|
38
|
+
type ThemeDef = {
|
|
39
|
+
kind: "ThemeDef";
|
|
40
|
+
name: string;
|
|
41
|
+
body: {
|
|
42
|
+
[k: string]: ThemeValue;
|
|
43
|
+
};
|
|
44
|
+
pos: Pos;
|
|
45
|
+
};
|
|
46
|
+
type TypeDef = {
|
|
47
|
+
kind: "TypeDef";
|
|
48
|
+
name: string;
|
|
49
|
+
params: string[];
|
|
50
|
+
body: TypeExpr;
|
|
51
|
+
pos: Pos;
|
|
52
|
+
};
|
|
53
|
+
type SlotDef = {
|
|
54
|
+
kind: "SlotDef";
|
|
55
|
+
name: string;
|
|
56
|
+
type: TypeExpr;
|
|
57
|
+
modifier?: "transient" | "volatile";
|
|
58
|
+
init: Expr;
|
|
59
|
+
pos: Pos;
|
|
60
|
+
};
|
|
61
|
+
type ReducerDef = {
|
|
62
|
+
kind: "ReducerDef";
|
|
63
|
+
name: string;
|
|
64
|
+
on: EventPattern;
|
|
65
|
+
do: Statement[];
|
|
66
|
+
pos: Pos;
|
|
67
|
+
};
|
|
68
|
+
type TileDef = {
|
|
69
|
+
kind: "TileDef";
|
|
70
|
+
name: string;
|
|
71
|
+
in?: TypeExpr;
|
|
72
|
+
errorBoundary?: string;
|
|
73
|
+
body: TileExpr;
|
|
74
|
+
pos: Pos;
|
|
75
|
+
};
|
|
76
|
+
type FnDef = {
|
|
77
|
+
kind: "FnDef";
|
|
78
|
+
name: string;
|
|
79
|
+
params: {
|
|
80
|
+
name: string;
|
|
81
|
+
type: TypeExpr;
|
|
82
|
+
}[];
|
|
83
|
+
ret?: TypeExpr;
|
|
84
|
+
body: Expr;
|
|
85
|
+
pos: Pos;
|
|
86
|
+
};
|
|
87
|
+
type EffectDef = {
|
|
88
|
+
kind: "EffectDef";
|
|
89
|
+
name: string;
|
|
90
|
+
cap: string;
|
|
91
|
+
inType: TypeExpr;
|
|
92
|
+
outType: TypeExpr;
|
|
93
|
+
policy?: PolicyExpr;
|
|
94
|
+
retry?: RetryExpr;
|
|
95
|
+
mapRequest?: Expr;
|
|
96
|
+
pos: Pos;
|
|
97
|
+
};
|
|
98
|
+
type AppDef = {
|
|
99
|
+
kind: "AppDef";
|
|
100
|
+
name: string;
|
|
101
|
+
caps: string[];
|
|
102
|
+
routes: {
|
|
103
|
+
path: string;
|
|
104
|
+
tile: string;
|
|
105
|
+
}[];
|
|
106
|
+
init: Expr[];
|
|
107
|
+
theme?: string;
|
|
108
|
+
pos: Pos;
|
|
109
|
+
};
|
|
110
|
+
type TypeExpr = {
|
|
111
|
+
kind: "TypePrim";
|
|
112
|
+
name: "Int" | "Text" | "Bool" | "Unit" | "Float" | "Time" | "Bytes";
|
|
113
|
+
pos: Pos;
|
|
114
|
+
} | {
|
|
115
|
+
kind: "TypeRef";
|
|
116
|
+
name: string;
|
|
117
|
+
pos: Pos;
|
|
118
|
+
} | {
|
|
119
|
+
kind: "TypeApp";
|
|
120
|
+
name: string;
|
|
121
|
+
args: TypeExpr[];
|
|
122
|
+
pos: Pos;
|
|
123
|
+
} | {
|
|
124
|
+
kind: "TypeRecord";
|
|
125
|
+
fields: {
|
|
126
|
+
name: string;
|
|
127
|
+
type: TypeExpr;
|
|
128
|
+
}[];
|
|
129
|
+
pos: Pos;
|
|
130
|
+
} | {
|
|
131
|
+
kind: "TypeUnion";
|
|
132
|
+
variants: {
|
|
133
|
+
name: string;
|
|
134
|
+
payloads: TypeExpr[];
|
|
135
|
+
}[];
|
|
136
|
+
pos: Pos;
|
|
137
|
+
} | {
|
|
138
|
+
kind: "TypeNominal";
|
|
139
|
+
inner: TypeExpr;
|
|
140
|
+
refinement?: Refinement;
|
|
141
|
+
pos: Pos;
|
|
142
|
+
} | {
|
|
143
|
+
kind: "TypeRefinement";
|
|
144
|
+
inner: TypeExpr;
|
|
145
|
+
refinement: Refinement;
|
|
146
|
+
pos: Pos;
|
|
147
|
+
};
|
|
148
|
+
type Refinement = {
|
|
149
|
+
kind: "Refinement";
|
|
150
|
+
pred: string;
|
|
151
|
+
args: (number | string)[];
|
|
152
|
+
pos: Pos;
|
|
153
|
+
};
|
|
154
|
+
type EventPattern = {
|
|
155
|
+
kind: "UiEvent";
|
|
156
|
+
ev: UiEventKind;
|
|
157
|
+
selector: {
|
|
158
|
+
tile: string;
|
|
159
|
+
id?: string;
|
|
160
|
+
};
|
|
161
|
+
pos: Pos;
|
|
162
|
+
} | {
|
|
163
|
+
kind: "EffectEvent";
|
|
164
|
+
effect: string;
|
|
165
|
+
outcome: "ok" | "err";
|
|
166
|
+
binds: string[];
|
|
167
|
+
pos: Pos;
|
|
168
|
+
} | {
|
|
169
|
+
kind: "TimerEvent";
|
|
170
|
+
intervalMs: number;
|
|
171
|
+
pos: Pos;
|
|
172
|
+
} | {
|
|
173
|
+
kind: "LifecycleEvent";
|
|
174
|
+
name: string;
|
|
175
|
+
pos: Pos;
|
|
176
|
+
};
|
|
177
|
+
type UiEventKind = "click" | "submit" | "change" | "input" | "focus" | "blur";
|
|
178
|
+
type Statement = {
|
|
179
|
+
kind: "SlotAssign";
|
|
180
|
+
lvalue: Lvalue;
|
|
181
|
+
rhs: Expr;
|
|
182
|
+
pos: Pos;
|
|
183
|
+
} | {
|
|
184
|
+
kind: "LetStmt";
|
|
185
|
+
name: string;
|
|
186
|
+
rhs: Expr;
|
|
187
|
+
pos: Pos;
|
|
188
|
+
} | {
|
|
189
|
+
kind: "Emit";
|
|
190
|
+
effect: string;
|
|
191
|
+
args: Expr[];
|
|
192
|
+
pos: Pos;
|
|
193
|
+
} | {
|
|
194
|
+
kind: "ForStmt";
|
|
195
|
+
bind: string;
|
|
196
|
+
iter: Expr;
|
|
197
|
+
body: Statement[];
|
|
198
|
+
pos: Pos;
|
|
199
|
+
} | {
|
|
200
|
+
kind: "IfStmt";
|
|
201
|
+
cond: Expr;
|
|
202
|
+
consequent: Statement[];
|
|
203
|
+
alternate: Statement[];
|
|
204
|
+
pos: Pos;
|
|
205
|
+
} | {
|
|
206
|
+
kind: "MatchStmt";
|
|
207
|
+
scrutinee: Expr;
|
|
208
|
+
arms: {
|
|
209
|
+
pattern: Pattern;
|
|
210
|
+
body: Statement[];
|
|
211
|
+
}[];
|
|
212
|
+
pos: Pos;
|
|
213
|
+
} | {
|
|
214
|
+
kind: "NoopStmt";
|
|
215
|
+
pos: Pos;
|
|
216
|
+
};
|
|
217
|
+
type Lvalue = {
|
|
218
|
+
kind: "LSlot";
|
|
219
|
+
name: string;
|
|
220
|
+
pos: Pos;
|
|
221
|
+
} | {
|
|
222
|
+
kind: "LIndex";
|
|
223
|
+
base: Lvalue;
|
|
224
|
+
index: Expr;
|
|
225
|
+
pos: Pos;
|
|
226
|
+
} | {
|
|
227
|
+
kind: "LField";
|
|
228
|
+
base: Lvalue;
|
|
229
|
+
field: string;
|
|
230
|
+
pos: Pos;
|
|
231
|
+
};
|
|
232
|
+
type Expr = {
|
|
233
|
+
kind: "Num";
|
|
234
|
+
value: number;
|
|
235
|
+
pos: Pos;
|
|
236
|
+
} | {
|
|
237
|
+
kind: "Str";
|
|
238
|
+
value: string;
|
|
239
|
+
pos: Pos;
|
|
240
|
+
} | {
|
|
241
|
+
kind: "Bool";
|
|
242
|
+
value: boolean;
|
|
243
|
+
pos: Pos;
|
|
244
|
+
} | {
|
|
245
|
+
kind: "Unit";
|
|
246
|
+
pos: Pos;
|
|
247
|
+
} | {
|
|
248
|
+
kind: "Ref";
|
|
249
|
+
name: string;
|
|
250
|
+
pos: Pos;
|
|
251
|
+
} | {
|
|
252
|
+
kind: "BinOp";
|
|
253
|
+
op: BinOp;
|
|
254
|
+
lhs: Expr;
|
|
255
|
+
rhs: Expr;
|
|
256
|
+
pos: Pos;
|
|
257
|
+
} | {
|
|
258
|
+
kind: "UnaryOp";
|
|
259
|
+
op: "-" | "!";
|
|
260
|
+
rhs: Expr;
|
|
261
|
+
pos: Pos;
|
|
262
|
+
} | {
|
|
263
|
+
kind: "FieldAccess";
|
|
264
|
+
base: Expr;
|
|
265
|
+
field: string;
|
|
266
|
+
pos: Pos;
|
|
267
|
+
} | {
|
|
268
|
+
kind: "Index";
|
|
269
|
+
base: Expr;
|
|
270
|
+
index: Expr;
|
|
271
|
+
pos: Pos;
|
|
272
|
+
} | {
|
|
273
|
+
kind: "Call";
|
|
274
|
+
callee: string;
|
|
275
|
+
args: Expr[];
|
|
276
|
+
pos: Pos;
|
|
277
|
+
} | {
|
|
278
|
+
kind: "MethodCall";
|
|
279
|
+
receiver: Expr;
|
|
280
|
+
method: string;
|
|
281
|
+
args: Expr[];
|
|
282
|
+
pos: Pos;
|
|
283
|
+
} | {
|
|
284
|
+
kind: "RecordLit";
|
|
285
|
+
fields: {
|
|
286
|
+
name: string;
|
|
287
|
+
value: Expr;
|
|
288
|
+
}[];
|
|
289
|
+
pos: Pos;
|
|
290
|
+
} | {
|
|
291
|
+
kind: "ListLit";
|
|
292
|
+
items: Expr[];
|
|
293
|
+
pos: Pos;
|
|
294
|
+
} | {
|
|
295
|
+
kind: "MapLit";
|
|
296
|
+
entries: {
|
|
297
|
+
key: Expr;
|
|
298
|
+
value: Expr;
|
|
299
|
+
}[];
|
|
300
|
+
pos: Pos;
|
|
301
|
+
} | {
|
|
302
|
+
kind: "MatchExpr";
|
|
303
|
+
scrutinee: Expr;
|
|
304
|
+
arms: MatchArm[];
|
|
305
|
+
pos: Pos;
|
|
306
|
+
} | {
|
|
307
|
+
kind: "IfExpr";
|
|
308
|
+
cond: Expr;
|
|
309
|
+
consequent: Expr;
|
|
310
|
+
alternate: Expr;
|
|
311
|
+
pos: Pos;
|
|
312
|
+
} | {
|
|
313
|
+
kind: "LetIn";
|
|
314
|
+
name: string;
|
|
315
|
+
value: Expr;
|
|
316
|
+
body: Expr;
|
|
317
|
+
pos: Pos;
|
|
318
|
+
} | {
|
|
319
|
+
kind: "Variant";
|
|
320
|
+
name: string;
|
|
321
|
+
payload: Expr[];
|
|
322
|
+
pos: Pos;
|
|
323
|
+
};
|
|
324
|
+
type MatchArm = {
|
|
325
|
+
pattern: Pattern;
|
|
326
|
+
body: Expr;
|
|
327
|
+
};
|
|
328
|
+
type Pattern = {
|
|
329
|
+
kind: "PVariant";
|
|
330
|
+
name: string;
|
|
331
|
+
binds: string[];
|
|
332
|
+
pos: Pos;
|
|
333
|
+
} | {
|
|
334
|
+
kind: "PWildcard";
|
|
335
|
+
pos: Pos;
|
|
336
|
+
} | {
|
|
337
|
+
kind: "PBind";
|
|
338
|
+
name: string;
|
|
339
|
+
pos: Pos;
|
|
340
|
+
} | {
|
|
341
|
+
kind: "PLiteral";
|
|
342
|
+
value: number | string | boolean;
|
|
343
|
+
pos: Pos;
|
|
344
|
+
};
|
|
345
|
+
type BinOp = "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "<" | ">" | "<=" | ">=" | "&" | "|";
|
|
346
|
+
type PolicyExpr = {
|
|
347
|
+
kind: "PolLatest";
|
|
348
|
+
} | {
|
|
349
|
+
kind: "PolLatestKey";
|
|
350
|
+
key: Expr;
|
|
351
|
+
} | {
|
|
352
|
+
kind: "PolQueue";
|
|
353
|
+
} | {
|
|
354
|
+
kind: "PolDebounce";
|
|
355
|
+
ms: number;
|
|
356
|
+
} | {
|
|
357
|
+
kind: "PolThrottle";
|
|
358
|
+
ms: number;
|
|
359
|
+
} | {
|
|
360
|
+
kind: "PolOnce";
|
|
361
|
+
};
|
|
362
|
+
type RetryExpr = {
|
|
363
|
+
kind: "RetryNone";
|
|
364
|
+
} | {
|
|
365
|
+
kind: "RetryLinear";
|
|
366
|
+
n: number;
|
|
367
|
+
ms: number;
|
|
368
|
+
} | {
|
|
369
|
+
kind: "RetryExp";
|
|
370
|
+
n: number;
|
|
371
|
+
ms: number;
|
|
372
|
+
factor: number;
|
|
373
|
+
};
|
|
374
|
+
type TileExpr = {
|
|
375
|
+
kind: "TileCall";
|
|
376
|
+
name: string;
|
|
377
|
+
args: TileArg[];
|
|
378
|
+
props: TileProp[];
|
|
379
|
+
pos: Pos;
|
|
380
|
+
} | {
|
|
381
|
+
kind: "TileFor";
|
|
382
|
+
bind: string;
|
|
383
|
+
iter: Expr;
|
|
384
|
+
body: TileExpr;
|
|
385
|
+
pos: Pos;
|
|
386
|
+
} | {
|
|
387
|
+
kind: "TileWhen";
|
|
388
|
+
cond: Expr;
|
|
389
|
+
body: TileExpr;
|
|
390
|
+
pos: Pos;
|
|
391
|
+
} | {
|
|
392
|
+
kind: "TileIf";
|
|
393
|
+
cond: Expr;
|
|
394
|
+
consequent: TileExpr;
|
|
395
|
+
alternate: TileExpr;
|
|
396
|
+
pos: Pos;
|
|
397
|
+
} | {
|
|
398
|
+
kind: "TileMatch";
|
|
399
|
+
scrutinee: Expr;
|
|
400
|
+
arms: TileMatchArm[];
|
|
401
|
+
pos: Pos;
|
|
402
|
+
};
|
|
403
|
+
type TileMatchArm = {
|
|
404
|
+
pattern: Pattern;
|
|
405
|
+
body: TileExpr;
|
|
406
|
+
};
|
|
407
|
+
type TileArg = {
|
|
408
|
+
kind: "TileArg";
|
|
409
|
+
name?: string;
|
|
410
|
+
value: Expr | TileExpr;
|
|
411
|
+
};
|
|
412
|
+
type TileProp = {
|
|
413
|
+
kind: "TileProp";
|
|
414
|
+
name: string;
|
|
415
|
+
value: Expr;
|
|
416
|
+
};
|
|
417
|
+
//#endregion
|
|
418
|
+
//#region src/codegen.d.ts
|
|
419
|
+
type CodegenOptions = {
|
|
420
|
+
runtimeSpecifier: string;
|
|
421
|
+
};
|
|
422
|
+
declare function codegen(program: Program, opts: CodegenOptions): string;
|
|
423
|
+
declare const RUNTIME_HELPERS = "\nfunction _setPath(obj, path, value) {\n if (path.length === 0) return value;\n const [head, ...rest] = path;\n const cur = obj ?? {};\n return { ...cur, [head]: _setPath(cur[head], rest, value) };\n}\nfunction _children(...xs) {\n const out = [];\n for (const x of xs) {\n if (x === null || x === undefined) continue;\n if (Array.isArray(x)) {\n for (const y of x) if (y !== null && y !== undefined) out.push(y);\n } else {\n out.push(x);\n }\n }\n return out;\n}\nfunction _attachProps(node, props) {\n if (!node || !props) return node;\n return { ...node, props: { ...(node.props || {}), ...props } };\n}\n";
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region src/typecheck.d.ts
|
|
426
|
+
type KumikiError = {
|
|
427
|
+
code: string;
|
|
428
|
+
kind: string;
|
|
429
|
+
message: string;
|
|
430
|
+
pos: Pos;
|
|
431
|
+
};
|
|
432
|
+
/** Returns errors with a11y warnings filtered out (unless strict). */
|
|
433
|
+
declare function check(program: Program, opts?: {
|
|
434
|
+
strictA11y?: boolean;
|
|
435
|
+
}): KumikiError[];
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/compile.d.ts
|
|
438
|
+
type CompileOk = {
|
|
439
|
+
kind: "ok";
|
|
440
|
+
js: string;
|
|
441
|
+
program: Program;
|
|
442
|
+
};
|
|
443
|
+
type CompileFail = {
|
|
444
|
+
kind: "fail";
|
|
445
|
+
errors: KumikiError[];
|
|
446
|
+
};
|
|
447
|
+
type CompileResult = CompileOk | CompileFail;
|
|
448
|
+
type ExtendedCodegenOptions = CodegenOptions & {
|
|
449
|
+
/** Inline the runtime source into the output so the generated module needs no external import. */bundle?: boolean;
|
|
450
|
+
/**
|
|
451
|
+
* Returns the prebuilt runtime bundle JS. Required when `bundle` is true.
|
|
452
|
+
* This is injected (rather than read here) to keep the compiler free of any
|
|
453
|
+
* Node-only imports, so it can run unchanged in the browser. Node callers can
|
|
454
|
+
* use `nodeRuntimeBundleReader` from `@kumikijs/compiler/node`.
|
|
455
|
+
*/
|
|
456
|
+
readRuntimeBundle?: () => string;
|
|
457
|
+
};
|
|
458
|
+
/** Inline a runtime bundle into generated module code, stripping the bridging import/export lines. */
|
|
459
|
+
declare function inlineRuntime(generatedJs: string, runtimeBundleJs: string): string;
|
|
460
|
+
declare function compile(source: string, opts: ExtendedCodegenOptions): CompileResult;
|
|
461
|
+
//#endregion
|
|
462
|
+
//#region src/lexer.d.ts
|
|
463
|
+
declare function lex(source: string): Token[];
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region src/parser.d.ts
|
|
466
|
+
declare class ParseError extends Error {
|
|
467
|
+
pos: Pos;
|
|
468
|
+
constructor(message: string, pos: Pos);
|
|
469
|
+
}
|
|
470
|
+
declare function parse(tokens: Token[]): Program;
|
|
471
|
+
//#endregion
|
|
472
|
+
export { type AppDef, type BinOp, type CodegenOptions, type CompileFail, type CompileOk, type CompileResult, type Def, type EffectDef, type EventPattern, type Expr, type ExtendedCodegenOptions, type FnDef, type KumikiError, type Lvalue, type MatchArm, ParseError, type Pattern, type PolicyExpr, type Pos, type Program, RUNTIME_HELPERS, type ReducerDef, type Refinement, type RetryExpr, type SlotDef, type Statement, type ThemeDef, type ThemeValue, type TileArg, type TileDef, type TileExpr, type TileMatchArm, type TileProp, type Token, type TypeDef, type TypeExpr, type UiEventKind, check, codegen, compile, inlineRuntime, lex, parse };
|