@exornea/zeno-compiler 1.7.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.
Files changed (42) hide show
  1. package/bin/zeno-codegen.mjs +117 -0
  2. package/dist/analyzer.d.ts +13 -0
  3. package/dist/analyzer.d.ts.map +1 -0
  4. package/dist/analyzer.js +153 -0
  5. package/dist/analyzer.js.map +1 -0
  6. package/dist/diagnostics.d.ts +38 -0
  7. package/dist/diagnostics.d.ts.map +1 -0
  8. package/dist/diagnostics.js +36 -0
  9. package/dist/diagnostics.js.map +1 -0
  10. package/dist/emitter-fixed-array.d.ts +11 -0
  11. package/dist/emitter-fixed-array.d.ts.map +1 -0
  12. package/dist/emitter-fixed-array.js +90 -0
  13. package/dist/emitter-fixed-array.js.map +1 -0
  14. package/dist/emitter-template.d.ts +5 -0
  15. package/dist/emitter-template.d.ts.map +1 -0
  16. package/dist/emitter-template.js +37 -0
  17. package/dist/emitter-template.js.map +1 -0
  18. package/dist/emitter.d.ts +7 -0
  19. package/dist/emitter.d.ts.map +1 -0
  20. package/dist/emitter.js +746 -0
  21. package/dist/emitter.js.map +1 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +8 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lowering.d.ts +18 -0
  27. package/dist/lowering.d.ts.map +1 -0
  28. package/dist/lowering.js +631 -0
  29. package/dist/lowering.js.map +1 -0
  30. package/dist/measurement.d.ts +41 -0
  31. package/dist/measurement.d.ts.map +1 -0
  32. package/dist/measurement.js +58 -0
  33. package/dist/measurement.js.map +1 -0
  34. package/dist/result.d.ts +20 -0
  35. package/dist/result.d.ts.map +1 -0
  36. package/dist/result.js +25 -0
  37. package/dist/result.js.map +1 -0
  38. package/dist/validator.d.ts +4 -0
  39. package/dist/validator.d.ts.map +1 -0
  40. package/dist/validator.js +342 -0
  41. package/dist/validator.js.map +1 -0
  42. package/package.json +47 -0
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ import { writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import ts from "typescript";
5
+
6
+ import {
7
+ analyzeProjectionSourceFile,
8
+ emitProjectionFile,
9
+ formatDiagnosticLocation,
10
+ } from "../dist/index.js";
11
+
12
+ const args = process.argv.slice(2);
13
+ let optimizeCursorOffsets = false;
14
+ let endianness = "little";
15
+ const diagnosticsArg = args.find((arg) => arg.startsWith("--diagnostics="));
16
+ let diagnosticsFormat = diagnosticsArg === undefined
17
+ ? "text"
18
+ : diagnosticsArg.slice("--diagnostics=".length);
19
+ const positionalArgs = [];
20
+ const usage = "Usage: zeno-codegen <input.ts> <output.view.ts> [--optimize-cursor-offsets experimental] [--endian=little|big] [--diagnostics=text|json]";
21
+
22
+ function fail(code, message, details = {}) {
23
+ if (diagnosticsFormat === "json") {
24
+ console.error(JSON.stringify({
25
+ event: "Codegen_Failed",
26
+ code,
27
+ message,
28
+ details,
29
+ }, null, 2));
30
+ } else {
31
+ console.error(message);
32
+ }
33
+ process.exit(1);
34
+ }
35
+
36
+ for (const arg of args) {
37
+ if (arg === "--help" || arg === "-h") {
38
+ console.log(usage);
39
+ process.exit(0);
40
+ }
41
+
42
+ if (arg === "--optimize-cursor-offsets") {
43
+ optimizeCursorOffsets = true;
44
+ continue;
45
+ }
46
+
47
+ if (arg.startsWith("--endian=")) {
48
+ endianness = arg.slice("--endian=".length);
49
+ continue;
50
+ }
51
+
52
+ if (arg.startsWith("--diagnostics=")) {
53
+ continue;
54
+ }
55
+
56
+ if (arg.startsWith("--")) {
57
+ fail("UNKNOWN_OPTION", `Unknown option: ${arg}`, { option: arg });
58
+ }
59
+
60
+ positionalArgs.push(arg);
61
+ }
62
+
63
+ const [inputPath, outputPath] = positionalArgs;
64
+
65
+ if (inputPath === undefined || outputPath === undefined) {
66
+ fail("INVALID_ARGUMENTS", usage);
67
+ }
68
+
69
+ if (endianness !== "little" && endianness !== "big") {
70
+ fail(
71
+ "INVALID_ENDIANNESS",
72
+ `Invalid endianness: ${endianness}. Expected "little" or "big".`,
73
+ { endianness },
74
+ );
75
+ }
76
+
77
+ if (diagnosticsFormat !== "text" && diagnosticsFormat !== "json") {
78
+ console.error(`Invalid diagnostics format: ${diagnosticsFormat}. Expected "text" or "json".`);
79
+ process.exit(1);
80
+ }
81
+
82
+ const rootName = path.resolve(inputPath);
83
+
84
+ let sourceText;
85
+ try {
86
+ sourceText = await import("node:fs/promises").then((fs) => fs.readFile(rootName, "utf8"));
87
+ } catch {
88
+ fail("INPUT_READ_FAILED", `Could not read input file: ${rootName}`, {
89
+ inputPath: rootName,
90
+ });
91
+ }
92
+
93
+ const sourceFile = ts.createSourceFile(
94
+ rootName,
95
+ sourceText,
96
+ ts.ScriptTarget.ES2022,
97
+ true,
98
+ );
99
+
100
+ const result = analyzeProjectionSourceFile(sourceFile, { endianness });
101
+
102
+ if (result.diagnostics.length > 0) {
103
+ if (diagnosticsFormat === "json") {
104
+ console.error(JSON.stringify({ diagnostics: result.diagnostics }, null, 2));
105
+ } else {
106
+ for (const diagnostic of result.diagnostics) {
107
+ console.error(`${formatDiagnosticLocation(diagnostic)} ${diagnostic.code}: ${diagnostic.message}`);
108
+ }
109
+ }
110
+ process.exit(1);
111
+ }
112
+
113
+ await writeFile(
114
+ path.resolve(outputPath),
115
+ emitProjectionFile(result.layouts, { optimizeCursorOffsets }),
116
+ "utf8",
117
+ );
@@ -0,0 +1,13 @@
1
+ import ts from "typescript";
2
+ import { type Endianness, type StructLayout } from "@exornea/zeno-schema";
3
+ import { type LayoutDiagnostic } from "./diagnostics.js";
4
+ export interface AnalyzeOptions {
5
+ readonly endianness?: Endianness;
6
+ }
7
+ export interface AnalyzeResult {
8
+ readonly layouts: StructLayout[];
9
+ readonly diagnostics: LayoutDiagnostic[];
10
+ }
11
+ export declare function analyzeProjectionFile(_program: ts.Program | undefined, sourceFile: ts.SourceFile, options?: AnalyzeOptions): AnalyzeResult;
12
+ export declare function analyzeProjectionSourceFile(sourceFile: ts.SourceFile, options?: AnalyzeOptions): AnalyzeResult;
13
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAW,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAWD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,EAChC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAEf;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAsBf"}
@@ -0,0 +1,153 @@
1
+ import ts from "typescript";
2
+ import { alignTo } from "@exornea/zeno-schema";
3
+ import { createDiagnostic, } from "./diagnostics.js";
4
+ import { measure, unsupportedAtPhase } from "./measurement.js";
5
+ import { err, ok } from "./result.js";
6
+ import { lowerField } from "./lowering.js";
7
+ import { validateLayouts } from "./validator.js";
8
+ export function analyzeProjectionFile(_program, sourceFile, options = {}) {
9
+ return analyzeProjectionSourceFile(sourceFile, options);
10
+ }
11
+ export function analyzeProjectionSourceFile(sourceFile, options = {}) {
12
+ const state = {
13
+ sourceFile,
14
+ endianness: options.endianness ?? "little",
15
+ declarations: collectInterfaceDeclarations(sourceFile),
16
+ layouts: new Map(),
17
+ diagnostics: validateSchemaSource(sourceFile),
18
+ activeStack: new Set(),
19
+ };
20
+ for (const structName of state.declarations.keys()) {
21
+ const result = lowerStruct(structName, state, sourceFile);
22
+ if (!result.ok) {
23
+ state.diagnostics.push(result.error);
24
+ }
25
+ }
26
+ const layouts = Array.from(state.layouts.values());
27
+ return {
28
+ layouts,
29
+ diagnostics: [...state.diagnostics, ...validateLayouts(layouts)],
30
+ };
31
+ }
32
+ function collectInterfaceDeclarations(sourceFile) {
33
+ const declarations = new Map();
34
+ sourceFile.forEachChild((node) => {
35
+ if (ts.isInterfaceDeclaration(node)) {
36
+ declarations.set(node.name.text, node);
37
+ }
38
+ });
39
+ return declarations;
40
+ }
41
+ function validateSchemaSource(sourceFile) {
42
+ const diagnostics = [];
43
+ for (const statement of sourceFile.statements) {
44
+ if (ts.isImportDeclaration(statement)) {
45
+ if (!isAllowedTypeOnlyImport(statement)) {
46
+ diagnostics.push(schemaStatementDiagnostic(sourceFile, statement, "import"));
47
+ }
48
+ continue;
49
+ }
50
+ if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
51
+ continue;
52
+ }
53
+ if (ts.isEmptyStatement(statement)) {
54
+ continue;
55
+ }
56
+ diagnostics.push(schemaStatementDiagnostic(sourceFile, statement, statementKind(statement)));
57
+ }
58
+ return diagnostics;
59
+ }
60
+ function isAllowedTypeOnlyImport(statement) {
61
+ const moduleName = statement.moduleSpecifier;
62
+ if (!ts.isStringLiteral(moduleName)) {
63
+ return false;
64
+ }
65
+ if (moduleName.text === "@exornea/zeno-runtime") {
66
+ return false;
67
+ }
68
+ const importClause = statement.importClause;
69
+ return importClause?.isTypeOnly === true;
70
+ }
71
+ function schemaStatementDiagnostic(sourceFile, node, construct) {
72
+ return createDiagnostic(sourceFile, node, "UNSUPPORTED_SCHEMA_STATEMENT", "Zeno schema files only support type-only imports plus interface/type declarations.", {
73
+ measurement: measure(`schema ${construct}`, "typescript-syntax", "phase-0"),
74
+ error: unsupportedAtPhase(`schema ${construct}`, "phase-0"),
75
+ });
76
+ }
77
+ function statementKind(statement) {
78
+ if (ts.isVariableStatement(statement)) {
79
+ return "value export";
80
+ }
81
+ if (ts.isFunctionDeclaration(statement)) {
82
+ return "function declaration";
83
+ }
84
+ if (ts.isClassDeclaration(statement)) {
85
+ return "class declaration";
86
+ }
87
+ if (ts.isEnumDeclaration(statement)) {
88
+ return "enum declaration";
89
+ }
90
+ if (ts.isExportDeclaration(statement) || ts.isExportAssignment(statement)) {
91
+ return "export declaration";
92
+ }
93
+ return ts.SyntaxKind[statement.kind] ?? "statement";
94
+ }
95
+ function lowerStruct(name, state, node) {
96
+ const existing = state.layouts.get(name);
97
+ if (existing !== undefined) {
98
+ return ok(existing);
99
+ }
100
+ const declaration = state.declarations.get(name);
101
+ if (declaration === undefined) {
102
+ return err(createDiagnostic(state.sourceFile, node, "UNKNOWN_STRUCT", `Unknown struct type "${name}".`, {
103
+ structName: name,
104
+ error: unsupportedAtPhase(`type reference "${name}"`, "phase-0"),
105
+ }));
106
+ }
107
+ if (state.activeStack.has(name)) {
108
+ return err(createDiagnostic(state.sourceFile, declaration.name, "RECURSIVE_STRUCT", `Recursive struct "${name}" is not supported yet.`, {
109
+ structName: name,
110
+ error: unsupportedAtPhase(`recursive struct "${name}"`, "phase-0"),
111
+ }));
112
+ }
113
+ state.activeStack.add(name);
114
+ const fields = [];
115
+ let runningOffset = 0;
116
+ let alignment = 1;
117
+ for (const member of declaration.members) {
118
+ if (!ts.isPropertySignature(member)) {
119
+ state.diagnostics.push(createDiagnostic(state.sourceFile, member, "UNSUPPORTED_MEMBER", `Struct "${name}" only supports property signatures.`, {
120
+ structName: name,
121
+ error: unsupportedAtPhase(member.getText(state.sourceFile), "phase-0"),
122
+ }));
123
+ continue;
124
+ }
125
+ const lowered = lowerField(member, {
126
+ sourceFile: state.sourceFile,
127
+ endianness: state.endianness,
128
+ diagnostics: state.diagnostics,
129
+ structName: name,
130
+ lowerStructByName: (refName, refNode) => lowerStruct(refName, state, refNode),
131
+ });
132
+ if (!lowered.ok) {
133
+ state.diagnostics.push(lowered.error);
134
+ continue;
135
+ }
136
+ runningOffset = alignTo(runningOffset, lowered.value.alignment);
137
+ fields.push(lowered.value.build(runningOffset));
138
+ runningOffset += lowered.value.byteLength;
139
+ alignment = Math.max(alignment, lowered.value.alignment);
140
+ }
141
+ const layout = {
142
+ kind: "struct",
143
+ name,
144
+ fields,
145
+ alignment,
146
+ byteLength: alignTo(runningOffset, alignment),
147
+ endianness: state.endianness,
148
+ };
149
+ state.layouts.set(name, layout);
150
+ state.activeStack.delete(name);
151
+ return ok(layout);
152
+ }
153
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import ts from "typescript";
2
+ import type { Measurement, ValidationError } from "./measurement.js";
3
+ export type DiagnosticCode = "UNSUPPORTED_NUMBER" | "UNSUPPORTED_ARRAY" | "UNSUPPORTED_TYPE" | "UNSUPPORTED_MEMBER" | "UNSUPPORTED_SCHEMA_STATEMENT" | "MISSING_TYPE" | "NON_NUMERIC_LENGTH" | "UNKNOWN_STRUCT" | "RECURSIVE_STRUCT" | "DUPLICATE_FIELD" | "ALIGNMENT_VIOLATION" | "LAYOUT_INVARIANT";
4
+ export type DiagnosticSource = {
5
+ readonly kind: "source";
6
+ readonly fileName: string;
7
+ readonly line: number;
8
+ readonly character: number;
9
+ } | {
10
+ readonly kind: "ir-derived";
11
+ readonly description: string;
12
+ };
13
+ export interface LayoutDiagnostic {
14
+ readonly code: DiagnosticCode;
15
+ readonly message: string;
16
+ readonly source: DiagnosticSource;
17
+ readonly fileName?: string;
18
+ readonly line?: number;
19
+ readonly character?: number;
20
+ readonly structName?: string;
21
+ readonly fieldName?: string;
22
+ readonly measurement?: Measurement;
23
+ readonly error?: ValidationError;
24
+ }
25
+ export declare function createDiagnostic(sourceFile: ts.SourceFile, node: ts.Node, code: DiagnosticCode, message: string, details?: {
26
+ readonly structName?: string;
27
+ readonly fieldName?: string;
28
+ readonly measurement?: Measurement;
29
+ readonly error?: ValidationError;
30
+ }): LayoutDiagnostic;
31
+ export declare function createIrDiagnostic(code: DiagnosticCode, message: string, description: string, details?: {
32
+ readonly structName?: string;
33
+ readonly fieldName?: string;
34
+ readonly measurement?: Measurement;
35
+ readonly error?: ValidationError;
36
+ }): LayoutDiagnostic;
37
+ export declare function formatDiagnosticLocation(diagnostic: LayoutDiagnostic): string;
38
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB,GACpB,8BAA8B,GAC9B,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,qBAAqB,GACrB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,gBAAgB,GACxB;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CAC7B,GACL,gBAAgB,CAgBlB;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CAC7B,GACL,gBAAgB,CAUlB;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,gBAAgB,GAAG,MAAM,CAM7E"}
@@ -0,0 +1,36 @@
1
+ import ts from "typescript";
2
+ export function createDiagnostic(sourceFile, node, code, message, details = {}) {
3
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
4
+ return {
5
+ code,
6
+ message,
7
+ source: {
8
+ kind: "source",
9
+ fileName: sourceFile.fileName,
10
+ line: position.line + 1,
11
+ character: position.character + 1,
12
+ },
13
+ fileName: sourceFile.fileName,
14
+ line: position.line + 1,
15
+ character: position.character + 1,
16
+ ...details,
17
+ };
18
+ }
19
+ export function createIrDiagnostic(code, message, description, details = {}) {
20
+ return {
21
+ code,
22
+ message,
23
+ source: {
24
+ kind: "ir-derived",
25
+ description,
26
+ },
27
+ ...details,
28
+ };
29
+ }
30
+ export function formatDiagnosticLocation(diagnostic) {
31
+ if (diagnostic.source.kind === "source") {
32
+ return `${diagnostic.source.fileName}:${diagnostic.source.line}:${diagnostic.source.character}`;
33
+ }
34
+ return `<ir-derived:${diagnostic.source.description}>`;
35
+ }
36
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AA2C5B,MAAM,UAAU,gBAAgB,CAC9B,UAAyB,EACzB,IAAa,EACb,IAAoB,EACpB,OAAe,EACf,UAKI,EAAE;IAEN,MAAM,QAAQ,GAAG,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrF,OAAO;QACL,IAAI;QACJ,OAAO;QACP,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,CAAC;YACvB,SAAS,EAAE,QAAQ,CAAC,SAAS,GAAG,CAAC;SAClC;QACD,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,CAAC;QACvB,SAAS,EAAE,QAAQ,CAAC,SAAS,GAAG,CAAC;QACjC,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAoB,EACpB,OAAe,EACf,WAAmB,EACnB,UAKI,EAAE;IAEN,OAAO;QACL,IAAI;QACJ,OAAO;QACP,MAAM,EAAE;YACN,IAAI,EAAE,YAAY;YAClB,WAAW;SACZ;QACD,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,UAA4B;IACnE,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IAClG,CAAC;IAED,OAAO,eAAe,UAAU,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC;AACzD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type FieldLayout, type FixedArrayElementLayout, type StructLayout } from "@exornea/zeno-schema";
2
+ export declare function collectFixedArrayRuntimeImports(element: FixedArrayElementLayout, imports: Set<string>): void;
3
+ export declare function fixedArrayInputElementType(element: FixedArrayElementLayout): string;
4
+ export declare function emitFixedArrayObjectFieldWrite(field: Extract<FieldLayout, {
5
+ kind: "fixed-array";
6
+ }>, encodingLiteral: (encoding: "ascii" | "utf8") => "\"ascii\"" | "\"utf8\""): string[];
7
+ export declare function emitFixedArrayFieldAccessor(field: Extract<FieldLayout, {
8
+ kind: "fixed-array";
9
+ }>, encodingLiteral: (encoding: "ascii" | "utf8") => "\"ascii\"" | "\"utf8\""): string[];
10
+ export declare function canWriteFixedArrayStructElement(element: FixedArrayElementLayout, layoutMap: ReadonlyMap<string, StructLayout>, hasTailWriterFields: (layout: StructLayout, layoutMap: ReadonlyMap<string, StructLayout>) => boolean): boolean;
11
+ //# sourceMappingURL=emitter-fixed-array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter-fixed-array.d.ts","sourceRoot":"","sources":["../src/emitter-fixed-array.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAI9B,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GACnB,IAAI,CAkBN;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAWnF;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EACpD,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,KAAK,WAAW,GAAG,UAAU,GACxE,MAAM,EAAE,CAkCV;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EACpD,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,KAAK,WAAW,GAAG,UAAU,GACxE,MAAM,EAAE,CAuBV;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAChC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAC5C,mBAAmB,EAAE,CACnB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,KACzC,OAAO,GACX,OAAO,CAOT"}
@@ -0,0 +1,90 @@
1
+ import { scalarTsType, } from "@exornea/zeno-schema";
2
+ import { method } from "./emitter-template.js";
3
+ export function collectFixedArrayRuntimeImports(element, imports) {
4
+ switch (element.kind) {
5
+ case "scalar":
6
+ imports.add("FixedScalarArrayView");
7
+ imports.add("writeScalar");
8
+ return;
9
+ case "fixed-bytes":
10
+ imports.add("FixedBytesArrayView");
11
+ imports.add("writeFixedBytes");
12
+ return;
13
+ case "fixed-string":
14
+ imports.add("FixedStringArrayView");
15
+ imports.add("writeFixedText");
16
+ return;
17
+ case "struct":
18
+ imports.add("FixedStructArrayView");
19
+ return;
20
+ }
21
+ }
22
+ export function fixedArrayInputElementType(element) {
23
+ switch (element.kind) {
24
+ case "scalar":
25
+ return scalarTsType(element.scalar);
26
+ case "fixed-bytes":
27
+ return "ArrayLike<number> | Uint8Array";
28
+ case "fixed-string":
29
+ return "string";
30
+ case "struct":
31
+ return `${element.typeName}ViewInput`;
32
+ }
33
+ }
34
+ export function emitFixedArrayObjectFieldWrite(field, encodingLiteral) {
35
+ const lines = [
36
+ ` if (value.${field.name}.length !== ${field.length}) {`,
37
+ ` throw new RangeError(\`Fixed array field "${field.name}" expects ${field.length} elements, got \${value.${field.name}.length}\`);`,
38
+ " }",
39
+ ` for (let index = 0; index < ${field.length}; index += 1) {`,
40
+ ];
41
+ const elementOffset = `baseOffset + ${field.offset} + index * ${field.element.byteLength}`;
42
+ switch (field.element.kind) {
43
+ case "scalar":
44
+ lines.push(` writeScalar(view, "${field.element.scalar}", ${elementOffset}, value.${field.name}[index]!, littleEndian);`);
45
+ break;
46
+ case "fixed-bytes":
47
+ lines.push(` writeFixedBytes(view.buffer, view.byteOffset + ${elementOffset}, ${field.element.byteLength}, value.${field.name}[index]!);`);
48
+ break;
49
+ case "fixed-string":
50
+ lines.push(` writeFixedText(view.buffer, view.byteOffset + ${elementOffset}, ${field.element.byteLength}, value.${field.name}[index]!, ${encodingLiteral(field.element.encoding)});`);
51
+ break;
52
+ case "struct":
53
+ lines.push(` ${field.element.typeName}View.write(view, value.${field.name}[index]!, ${elementOffset}, littleEndian);`);
54
+ break;
55
+ }
56
+ lines.push(" }");
57
+ return lines;
58
+ }
59
+ export function emitFixedArrayFieldAccessor(field, encodingLiteral) {
60
+ switch (field.element.kind) {
61
+ case "scalar":
62
+ return method `
63
+ ${field.name}View(): FixedScalarArrayView<${scalarTsType(field.element.scalar)}> {
64
+ return new FixedScalarArrayView(this.view, ${field.offset}, ${field.length}, "${field.element.scalar}", this.baseOffset, this.littleEndian);
65
+ }`;
66
+ case "fixed-bytes":
67
+ return method `
68
+ ${field.name}View(): FixedBytesArrayView {
69
+ return new FixedBytesArrayView(this.view, ${field.offset}, ${field.length}, ${field.element.byteLength}, this.baseOffset, this.littleEndian);
70
+ }`;
71
+ case "fixed-string":
72
+ return method `
73
+ ${field.name}View(): FixedStringArrayView {
74
+ return new FixedStringArrayView(this.view, ${field.offset}, ${field.length}, ${field.element.byteLength}, this.baseOffset, this.littleEndian, ${encodingLiteral(field.element.encoding)});
75
+ }`;
76
+ case "struct":
77
+ return method `
78
+ ${field.name}View(): FixedStructArrayView<${field.element.typeName}View> {
79
+ return new FixedStructArrayView(this.view, ${field.offset}, ${field.length}, ${field.element.byteLength}, (view, baseOffset, littleEndian) => new ${field.element.typeName}View(view, baseOffset, littleEndian), this.baseOffset, this.littleEndian);
80
+ }`;
81
+ }
82
+ }
83
+ export function canWriteFixedArrayStructElement(element, layoutMap, hasTailWriterFields) {
84
+ if (element.kind !== "struct") {
85
+ return false;
86
+ }
87
+ const elementLayout = layoutMap.get(element.typeName);
88
+ return elementLayout !== undefined && !hasTailWriterFields(elementLayout, layoutMap);
89
+ }
90
+ //# sourceMappingURL=emitter-fixed-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter-fixed-array.js","sourceRoot":"","sources":["../src/emitter-fixed-array.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ type CodeValue = string | number | boolean | readonly string[];
2
+ export declare function method(strings: TemplateStringsArray, ...values: CodeValue[]): string[];
3
+ export declare function code(strings: TemplateStringsArray, ...values: CodeValue[]): string[];
4
+ export {};
5
+ //# sourceMappingURL=emitter-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter-template.d.ts","sourceRoot":"","sources":["../src/emitter-template.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,MAAM,EAAE,CAAC;AAE/D,wBAAgB,MAAM,CACpB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,SAAS,EAAE,GACrB,MAAM,EAAE,CAEV;AAED,wBAAgB,IAAI,CAClB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,SAAS,EAAE,GACrB,MAAM,EAAE,CAMV"}
@@ -0,0 +1,37 @@
1
+ export function method(strings, ...values) {
2
+ return indentLines(" ", code(strings, ...values));
3
+ }
4
+ export function code(strings, ...values) {
5
+ let source = strings[0] ?? "";
6
+ for (let index = 0; index < values.length; index += 1) {
7
+ source += stringifyCodeValue(values[index]) + strings[index + 1];
8
+ }
9
+ return dedent(source).split("\n");
10
+ }
11
+ function stringifyCodeValue(value) {
12
+ if (Array.isArray(value)) {
13
+ return value.join("\n");
14
+ }
15
+ return String(value);
16
+ }
17
+ function indentLines(indent, lines) {
18
+ return lines.map((line) => (line.length === 0 ? line : indent + line));
19
+ }
20
+ function dedent(source) {
21
+ const lines = trimBlankEdges(source).split("\n");
22
+ const indent = commonIndent(lines);
23
+ return lines.map((line) => line.slice(Math.min(indent, leadingSpaces(line)))).join("\n");
24
+ }
25
+ function trimBlankEdges(source) {
26
+ return source.replace(/^\n/, "").replace(/\n[ \t]*$/, "");
27
+ }
28
+ function commonIndent(lines) {
29
+ const indents = lines
30
+ .filter((line) => line.trim().length > 0)
31
+ .map((line) => leadingSpaces(line));
32
+ return indents.length === 0 ? 0 : Math.min(...indents);
33
+ }
34
+ function leadingSpaces(line) {
35
+ return line.match(/^[ \t]*/)?.[0].length ?? 0;
36
+ }
37
+ //# sourceMappingURL=emitter-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter-template.js","sourceRoot":"","sources":["../src/emitter-template.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,MAAM,CACpB,OAA6B,EAC7B,GAAG,MAAmB;IAEtB,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,OAA6B,EAC7B,GAAG,MAAmB;IAEtB,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAE,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAgB;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,KAAwB;IAC3D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,MAAM,CAAC,MAAc;IAC5B,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,YAAY,CAAC,KAAwB;IAC5C,MAAM,OAAO,GAAG,KAAK;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type StructLayout } from "@exornea/zeno-schema";
2
+ export interface EmitOptions {
3
+ readonly optimizeCursorOffsets?: boolean;
4
+ }
5
+ export declare function emitStructView(layout: StructLayout, options?: EmitOptions): string;
6
+ export declare function emitProjectionFile(layouts: readonly StructLayout[], options?: EmitOptions): string;
7
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAkC9B,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAEtF;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,GAAE,WAAgB,GACxB,MAAM,CAiBR"}