@thi.ng/wasm-api 0.18.0 → 1.0.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.
@@ -1,240 +0,0 @@
1
- import { BIGINT_ARRAY_CTORS, BIT_SHIFTS, TYPEDARRAY_CTORS, } from "@thi.ng/api/typedarray";
2
- import { isString } from "@thi.ng/checks/is-string";
3
- import { PKG_NAME, } from "../api.js";
4
- import { ensureLines, enumName, isBigNumeric, isNumeric, isPadding, isStringSlice, isWasmPrim, isWasmString, pointerFields, prefixLines, stringFields, withIndentation, } from "./utils.js";
5
- import { fieldType as zigFieldType } from "./zig.js";
6
- /**
7
- * TypeScript code generator. Call with options and then pass to
8
- * {@link generateTypes} (see its docs for further usage).
9
- *
10
- * @remarks
11
- * This codegen generates interface and enum definitions for a {@link TypeColl}
12
- * given to {@link generateTypes}. For structs it will also generate memory
13
- * mapped wrappers with fully typed accessors.
14
- *
15
- * @param opts
16
- */
17
- export const TYPESCRIPT = (opts = {}) => {
18
- const { indent } = {
19
- indent: "\t",
20
- stringType: "slice",
21
- ...opts,
22
- };
23
- const SCOPES = [/\{$/, /\}\)?[;,]?$/];
24
- const gen = {
25
- pre: (opts) => `// @ts-ignore possibly includes unused imports
26
- import { MemorySlice, Pointer, ${__stringImpl(opts)}, WasmTypeBase, WasmTypeConstructor } from "${PKG_NAME}";${opts.pre ? `\n${opts.pre}` : ""}`,
27
- post: () => opts.post || "",
28
- doc: (doc, acc, opts) => {
29
- acc.push("/**", ...prefixLines(" * ", doc, opts.lineWidth), " */");
30
- },
31
- enum: (e, _, acc, opts) => {
32
- const res = [];
33
- res.push(`export enum ${e.name} {`);
34
- for (let v of e.values) {
35
- let line;
36
- if (!isString(v)) {
37
- v.doc && gen.doc(v.doc, res, opts);
38
- line = enumName(opts, v.name);
39
- if (v.value != null)
40
- line += ` = ${v.value}`;
41
- }
42
- else {
43
- line = enumName(opts, v);
44
- }
45
- res.push(line + ",");
46
- }
47
- res.push("}", "");
48
- acc.push(...withIndentation(res, indent, ...SCOPES));
49
- },
50
- struct: (struct, types, acc, opts) => {
51
- const fieldTypes = {};
52
- const $stringImpl = __stringImpl(opts);
53
- const lines = [];
54
- // interface definition
55
- lines.push(`export interface ${struct.name} extends WasmTypeBase {`);
56
- for (let f of struct.fields) {
57
- if (isPadding(f))
58
- continue;
59
- const doc = __docType(struct, f, opts);
60
- doc && gen.doc(doc, lines, opts);
61
- const ftype = __fieldType(f, opts);
62
- fieldTypes[f.name] = ftype;
63
- lines.push(`${f.name}: ${ftype};`);
64
- }
65
- if (struct.body?.ts) {
66
- lines.push("", ...ensureLines(struct.body.ts, "decl"));
67
- }
68
- lines.push("}", "");
69
- const pointerDecls = pointerFields(struct.fields).map((x) => {
70
- return `let $${x.name}: ${fieldTypes[x.name]} | null = null;`;
71
- });
72
- const stringDecls = stringFields(struct.fields).map((x) => {
73
- const suffix = x.tag === "array" || x.tag === "slice" ? "[]" : "";
74
- return `let $${x.name}: ${$stringImpl}${suffix} | null = null;`;
75
- });
76
- // type implementation
77
- lines.push(`export const $${struct.name}: WasmTypeConstructor<${struct.name}> = (mem) => ({`, `get align() {`, `return ${struct.__align};`, `},`, `get size() {`, `return ${struct.__size};`, `},`, `instance: (base) => {`, ...pointerDecls, ...stringDecls, `return {`, `get __base() {`, `return base;`, `},`, `get __bytes() {`, `return mem.u8.subarray(base, base + ${struct.__size});`, `},`);
78
- for (let f of struct.fields) {
79
- // skip explicit padding fields
80
- if (isPadding(f))
81
- continue;
82
- const ftype = fieldTypes[f.name];
83
- const offset = f.__offset || 0;
84
- lines.push(`get ${f.name}(): ${ftype} {`);
85
- const isPrim = isWasmPrim(f.type);
86
- const isStr = isWasmString(f.type);
87
- const isConst = isStr ? f.const !== false : !!f.const;
88
- if (f.tag === "ptr") {
89
- if (isPrim) {
90
- const fn = f.len
91
- ? `(base) => mem.${f.type}.subarray(${__addrShift(0, f.type)}, (${__addrShift(0, f.type)}) + ${f.len})`
92
- : `(base) => mem.${f.type}[${__addrShift(0, f.type)}]`;
93
- lines.push(`return $${f.name} || ($${f.name} = new ${ftype}(mem, ${__addr(offset)}, ${fn}));`);
94
- }
95
- else if (isStr) {
96
- const fn = f.len
97
- ? [
98
- `(addr) => {`,
99
- ...__mapStringArray(opts.target, "buf", $stringImpl, f.len, isConst, true),
100
- `}`,
101
- ]
102
- : [
103
- `(addr) => new ${$stringImpl}(mem, addr, ${isConst})`,
104
- ];
105
- lines.push(`return $${f.name} || ($${f.name} = new ${ftype}(mem, ${__addr(offset)},`, ...fn, `));`);
106
- }
107
- else {
108
- const fn = f.len
109
- ? [`(addr) => {`, ...__mapArray(f, f.len), `}`]
110
- : [`(addr) => new $${f.type}.instance(addr)`];
111
- lines.push(`return $${f.name} || ($${f.name} = new ${ftype}(mem, ${__addr(offset)},`, ...fn, `));`);
112
- }
113
- }
114
- else if (f.tag === "slice") {
115
- lines.push(`const len = ${__ptr(opts.target, offset + 4)};`);
116
- if (isPrim) {
117
- lines.push(`const addr = ${__ptrShift(opts.target, offset, f.type)};`, `return mem.${f.type}.subarray(addr, addr + len);`);
118
- }
119
- else if (isStr) {
120
- lines.push(`const addr = ${__ptr(opts.target, offset)};`, ...__mapStringArray(opts.target, "buf", $stringImpl, "len", isConst));
121
- }
122
- else {
123
- lines.push(`const addr = ${__ptr(opts.target, offset)};`, ...__mapArray(f));
124
- }
125
- }
126
- else if (f.tag === "array" || f.tag === "vec") {
127
- if (isPrim) {
128
- lines.push(`const addr = ${__addrShift(offset, f.type)};`, `return mem.${f.type}.subarray(addr, addr + ${f.len});`);
129
- }
130
- else if (isStr) {
131
- lines.push(`if ($${f.name}) return $${f.name};`, `const addr = ${__addr(offset)};`, ...__mapStringArray(opts.target, f.name, $stringImpl, f.len, isConst));
132
- }
133
- else {
134
- lines.push(`const addr = ${__addr(offset)};`, ...__mapArray(f, f.len));
135
- }
136
- }
137
- else {
138
- let setter;
139
- if (isPrim) {
140
- const addr = __mem(f.type, f.__offset);
141
- lines.push(`return ${addr};`);
142
- setter = `${addr} = x`;
143
- }
144
- else if (isStr) {
145
- lines.push(`return $${f.name} || ($${f.name} = new ${$stringImpl}(mem, ${__addr(offset)}, ${isConst}));`);
146
- }
147
- else if (types[f.type].type === "enum") {
148
- const tag = types[f.type].tag;
149
- const addr = __mem(tag, f.__offset);
150
- lines.push(`return ${addr};`);
151
- setter = `${addr} = x`;
152
- }
153
- else {
154
- lines.push(`return $${f.type}(mem).instance(${__addr(offset)});`);
155
- setter = `mem.u8.set(x.__bytes, ${__addr(offset)})`;
156
- }
157
- // setter
158
- if (setter) {
159
- lines.push(
160
- // close getter
161
- `},`, `set ${f.name}(x: ${fieldTypes[f.name]}) {`, `${setter};`);
162
- }
163
- }
164
- // close field accessor
165
- lines.push(`},`);
166
- }
167
- if (struct.body?.ts) {
168
- lines.push("", ...ensureLines(struct.body.ts, "impl"), "");
169
- }
170
- lines.push("};", "}", "});", "");
171
- acc.push(...withIndentation(lines, indent, ...SCOPES));
172
- },
173
- union: (type, coll, acc, opts) => {
174
- gen.struct(type, coll, acc, opts);
175
- },
176
- };
177
- return gen;
178
- };
179
- /** @internal */
180
- const __stringImpl = (opts) => isStringSlice(opts.stringType) ? "WasmStringSlice" : "WasmStringPtr";
181
- /** @internal */
182
- const __fieldType = (f, opts) => {
183
- const ftype = f.tag == "array" ||
184
- f.tag == "slice" ||
185
- f.tag === "vec" ||
186
- (f.tag === "ptr" && f.len)
187
- ? isNumeric(f.type)
188
- ? TYPEDARRAY_CTORS[f.type].name
189
- : isBigNumeric(f.type)
190
- ? BIGINT_ARRAY_CTORS[f.type].name
191
- : isWasmString(f.type)
192
- ? __stringImpl(opts) + "[]"
193
- : f.type + "[]"
194
- : !f.tag || f.tag === "scalar" || f.tag === "ptr"
195
- ? isBigNumeric(f.type)
196
- ? "bigint"
197
- : isNumeric(f.type)
198
- ? "number"
199
- : isWasmString(f.type)
200
- ? __stringImpl(opts)
201
- : f.type
202
- : f.type;
203
- return f.tag === "ptr" ? `Pointer<${ftype}>` : ftype;
204
- };
205
- /** @internal */
206
- const __shift = (type) => BIT_SHIFTS[type];
207
- /** @internal */
208
- const __addr = (offset) => (offset > 0 ? `(base + ${offset})` : "base");
209
- /** @internal */
210
- const __addrShift = (offset, shift) => {
211
- const bits = __shift(shift);
212
- return __addr(offset) + (bits ? " >>> " + bits : "");
213
- };
214
- /** @internal */
215
- const __ptr = (target, offset) => `mem.${target.usize}[${__addrShift(offset, target.usize)}]`;
216
- /** @internal */
217
- const __ptrShift = (target, offset, shift) => __ptr(target, offset) + " >>> " + __shift(shift);
218
- const __mem = (type, offset) => `mem.${type}[${__addrShift(offset, type)}]`;
219
- /** @internal */
220
- const __mapArray = (f, len = "len") => [
221
- `const inst = $${f.type}(mem);`,
222
- `const slice: ${f.type}[] = [];`,
223
- `for(let i = 0; i < ${len}; i++) slice.push(inst.instance(addr + i * ${f.__size}));`,
224
- `return slice;`,
225
- ];
226
- /** @internal */
227
- const __mapStringArray = (target, name, type, len, isConst, isLocal = false) => [
228
- isLocal ? `const $${name}: ${type}[] = [];` : `$${name} = [];`,
229
- `for(let i = 0; i < ${len}; i++) $${name}.push(new ${type}(mem, addr + i * ${target.usizeBytes * (type === "WasmStringSlice" ? 2 : 1)}, ${isConst}));`,
230
- `return $${name};`,
231
- ];
232
- const __docType = (parent, f, opts) => {
233
- const doc = [...ensureLines(f.doc || [])];
234
- if (isWasmPrim(f.type)) {
235
- if (doc.length)
236
- doc.push("");
237
- doc.push(`WASM type: ${zigFieldType(parent, f, opts).type}`);
238
- }
239
- return doc.length ? doc : undefined;
240
- };
@@ -1,96 +0,0 @@
1
- import type { BigType } from "@thi.ng/api";
2
- import type { CodeGenOpts, Field, InjectedBody, WasmPrim, WasmPrim32 } from "../api.js";
3
- /**
4
- * Returns true iff `x` is a {@link WasmPrim32}.
5
- *
6
- * @param x
7
- */
8
- export declare const isNumeric: (x: string) => x is WasmPrim32;
9
- /**
10
- * Returns true iff `x` is a `i64` or `u64`.
11
- *
12
- * @param x
13
- */
14
- export declare const isBigNumeric: (x: string) => x is BigType;
15
- /**
16
- * Returns true iff `x` is a {@link WasmPrim}.
17
- *
18
- * @param x
19
- */
20
- export declare const isWasmPrim: (x: string) => x is WasmPrim;
21
- export declare const isWasmString: (x: string) => x is "string";
22
- export declare const isPadding: (f: Field) => boolean;
23
- export declare const isPointer: (f: Field) => boolean;
24
- export declare const isSlice: (f: Field) => boolean;
25
- /**
26
- * Returns true iff the struct field is a pointer, slice or "string" type
27
- *
28
- * @param f
29
- */
30
- export declare const isPointerLike: (f: Field) => boolean;
31
- /**
32
- * Returns true if `type` is "slice".
33
- *
34
- * @param type
35
- */
36
- export declare const isStringSlice: (type: CodeGenOpts["stringType"]) => type is "slice";
37
- /**
38
- * Returns filtered array of struct fields of with "ptr" tag.
39
- *
40
- * @param fields
41
- *
42
- * @internal
43
- */
44
- export declare const pointerFields: (fields: Field[]) => Field[];
45
- /**
46
- * Returns filtered array of struct fields of only "string" fields.
47
- *
48
- * @param fields
49
- *
50
- * @internal
51
- */
52
- export declare const stringFields: (fields: Field[]) => Field[];
53
- /**
54
- * Returns enum identifier formatted according to given opts.
55
- *
56
- * @param opts
57
- * @param name
58
- *
59
- * @internal
60
- */
61
- export declare const enumName: (opts: CodeGenOpts, name: string) => string;
62
- /**
63
- * Returns given field's default value (or undefined). The `lang` ID is required
64
- * to obtain the language specific value if the default is given as object.
65
- *
66
- * @param f
67
- * @param lang
68
- */
69
- export declare const defaultValue: (f: Field, lang: string) => import("@thi.ng/api").NumOrString | undefined;
70
- /**
71
- * Takes an array of strings or splits given string into lines, word wraps and
72
- * then prefixes each line with given `width` and `prefix`. Returns array of new
73
- * lines.
74
- *
75
- * @param prefix
76
- * @param str
77
- * @param width
78
- */
79
- export declare const prefixLines: (prefix: string, str: string | string[], width: number) => string[];
80
- export declare const ensureLines: (src: string | string[] | InjectedBody, key?: keyof InjectedBody) => Iterable<string>;
81
- /**
82
- * Yields iterator of given lines, each with applied indentation based on given
83
- * scope regexp's which are applied to each line to increase or decrease
84
- * indentation level (the initial indentation level can be specified via
85
- * optional `level` arg, default 0). If `scopeStart` succeeds, the indent is
86
- * increased for the _next_ line. If `scopeEnd` succeeds the level is decreased
87
- * for the _current_ line. ...
88
- *
89
- * @param lines
90
- * @param indent
91
- * @param scopeStart
92
- * @param scopeEnd
93
- * @param level
94
- */
95
- export declare function withIndentation(lines: string[], indent: string, scopeStart: RegExp, scopeEnd: RegExp, level?: number): Generator<string, void, unknown>;
96
- //# sourceMappingURL=utils.d.ts.map
package/codegen/utils.js DELETED
@@ -1,120 +0,0 @@
1
- import { isArray } from "@thi.ng/checks/is-array";
2
- import { isPlainObject } from "@thi.ng/checks/is-plain-object";
3
- import { isString } from "@thi.ng/checks/is-string";
4
- import { split } from "@thi.ng/strings/split";
5
- import { wordWrapLine, wordWrapLines } from "@thi.ng/strings/word-wrap";
6
- /**
7
- * Returns true iff `x` is a {@link WasmPrim32}.
8
- *
9
- * @param x
10
- */
11
- export const isNumeric = (x) => /^(([iu](8|16|32))|(f(32|64)))$/.test(x);
12
- /**
13
- * Returns true iff `x` is a `i64` or `u64`.
14
- *
15
- * @param x
16
- */
17
- export const isBigNumeric = (x) => /^[iu]64$/.test(x);
18
- /**
19
- * Returns true iff `x` is a {@link WasmPrim}.
20
- *
21
- * @param x
22
- */
23
- export const isWasmPrim = (x) => isNumeric(x) || isBigNumeric(x);
24
- export const isWasmString = (x) => x === "string";
25
- export const isPadding = (f) => f.pad != null && f.pad > 0;
26
- export const isPointer = (f) => f.tag === "ptr";
27
- export const isSlice = (f) => f.tag === "slice";
28
- /**
29
- * Returns true iff the struct field is a pointer, slice or "string" type
30
- *
31
- * @param f
32
- */
33
- export const isPointerLike = (f) => isPointer(f) || isSlice(f) || isWasmString(f.type);
34
- /**
35
- * Returns true if `type` is "slice".
36
- *
37
- * @param type
38
- */
39
- export const isStringSlice = (type) => type === "slice";
40
- /**
41
- * Returns filtered array of struct fields of with "ptr" tag.
42
- *
43
- * @param fields
44
- *
45
- * @internal
46
- */
47
- export const pointerFields = (fields) => fields.filter((f) => f.tag === "ptr");
48
- /**
49
- * Returns filtered array of struct fields of only "string" fields.
50
- *
51
- * @param fields
52
- *
53
- * @internal
54
- */
55
- export const stringFields = (fields) => fields.filter((f) => isWasmString(f.type) && f.tag !== "ptr");
56
- /**
57
- * Returns enum identifier formatted according to given opts.
58
- *
59
- * @param opts
60
- * @param name
61
- *
62
- * @internal
63
- */
64
- export const enumName = (opts, name) => opts.uppercaseEnums ? name.toUpperCase() : name;
65
- /**
66
- * Returns given field's default value (or undefined). The `lang` ID is required
67
- * to obtain the language specific value if the default is given as object.
68
- *
69
- * @param f
70
- * @param lang
71
- */
72
- export const defaultValue = (f, lang) => f.default !== undefined
73
- ? isPlainObject(f.default)
74
- ? f.default[lang]
75
- : f.default
76
- : undefined;
77
- /**
78
- * Takes an array of strings or splits given string into lines, word wraps and
79
- * then prefixes each line with given `width` and `prefix`. Returns array of new
80
- * lines.
81
- *
82
- * @param prefix
83
- * @param str
84
- * @param width
85
- */
86
- export const prefixLines = (prefix, str, width) => (isString(str)
87
- ? wordWrapLines(str, { width: width - prefix.length })
88
- : str.flatMap((x) => wordWrapLine(x, { width: width - prefix.length }))).map((line) => prefix + line);
89
- export const ensureLines = (src, key) => isString(src)
90
- ? split(src)
91
- : isArray(src)
92
- ? src
93
- : key
94
- ? src[key]
95
- ? ensureLines(src[key], key)
96
- : []
97
- : [];
98
- /**
99
- * Yields iterator of given lines, each with applied indentation based on given
100
- * scope regexp's which are applied to each line to increase or decrease
101
- * indentation level (the initial indentation level can be specified via
102
- * optional `level` arg, default 0). If `scopeStart` succeeds, the indent is
103
- * increased for the _next_ line. If `scopeEnd` succeeds the level is decreased
104
- * for the _current_ line. ...
105
- *
106
- * @param lines
107
- * @param indent
108
- * @param scopeStart
109
- * @param scopeEnd
110
- * @param level
111
- */
112
- export function* withIndentation(lines, indent, scopeStart, scopeEnd, level = 0) {
113
- const stack = new Array(level).fill(indent);
114
- for (let l of lines) {
115
- scopeEnd.test(l) && stack.pop();
116
- const curr = stack.length ? stack[stack.length - 1] : "";
117
- yield curr + l;
118
- scopeStart.test(l) && stack.push(curr + indent);
119
- }
120
- }
package/codegen/zig.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import type { CodeGenOpts, CodeGenOptsBase, Field, ICodeGen, Struct, Union } from "../api.js";
2
- /**
3
- * Zig code generator options.
4
- */
5
- export interface ZigOpts extends CodeGenOptsBase {
6
- }
7
- /**
8
- * Zig code generator. Call with options and then pass to {@link generateTypes}
9
- * (see its docs for further usage).
10
- *
11
- * @remarks
12
- * This codegen generates struct and enum definitions for a {@link TypeColl}
13
- * given to {@link generateTypes}.
14
- *
15
- * @param opts
16
- */
17
- export declare const ZIG: (opts?: Partial<ZigOpts>) => ICodeGen;
18
- /** @internal */
19
- export declare const fieldType: (parent: Struct | Union, f: Field, opts: CodeGenOpts) => {
20
- type: string;
21
- defaultVal: string;
22
- };
23
- //# sourceMappingURL=zig.d.ts.map
package/codegen/zig.js DELETED
@@ -1,149 +0,0 @@
1
- import { isNumber } from "@thi.ng/checks";
2
- import { isString } from "@thi.ng/checks/is-string";
3
- import { unsupported } from "@thi.ng/errors/unsupported";
4
- import { defaultValue, ensureLines, isPadding, isStringSlice, isWasmString, prefixLines, withIndentation, } from "./utils.js";
5
- /**
6
- * Zig code generator. Call with options and then pass to {@link generateTypes}
7
- * (see its docs for further usage).
8
- *
9
- * @remarks
10
- * This codegen generates struct and enum definitions for a {@link TypeColl}
11
- * given to {@link generateTypes}.
12
- *
13
- * @param opts
14
- */
15
- export const ZIG = (opts = {}) => {
16
- const INDENT = " ";
17
- const SCOPES = [/\{$/, /\}\)?[;,]?$/];
18
- const gen = {
19
- pre: () => `const std = @import("std");${opts.pre ? `\n${opts.pre}` : ""}`,
20
- post: () => opts.post || "",
21
- doc: (doc, acc, opts, topLevel = false) => {
22
- acc.push(...prefixLines(topLevel ? "//! " : "/// ", doc, opts.lineWidth));
23
- },
24
- enum: (e, _, acc, opts) => {
25
- const lines = [];
26
- lines.push(`pub const ${e.name} = enum(${e.tag}) {`);
27
- for (let v of e.values) {
28
- let line;
29
- if (!isString(v)) {
30
- v.doc && gen.doc(v.doc, lines, opts);
31
- line = v.name;
32
- if (v.value != null)
33
- line += ` = ${v.value}`;
34
- }
35
- else {
36
- line = v;
37
- }
38
- lines.push(line + ",");
39
- }
40
- if (e.body?.zig) {
41
- lines.push("", ...ensureLines(e.body.zig, "impl"), "");
42
- }
43
- lines.push("};", "");
44
- acc.push(...withIndentation(lines, INDENT, ...SCOPES));
45
- },
46
- struct: (struct, _, acc, opts) => {
47
- acc.push(...withIndentation([
48
- `pub const ${struct.name} = ${struct.tag ? struct.tag + " " : ""}struct {`,
49
- ...__generateFields(gen, struct, opts),
50
- ], INDENT, ...SCOPES));
51
- },
52
- union: (union, _, acc, opts) => {
53
- acc.push(...withIndentation([
54
- `pub const ${union.name} = ${union.tag ? union.tag + " " : ""}union {`,
55
- ...__generateFields(gen, union, opts),
56
- ], INDENT, ...SCOPES));
57
- },
58
- };
59
- return gen;
60
- };
61
- const __generateFields = (gen, parent, opts) => {
62
- const res = [];
63
- const ftypes = {};
64
- const isUnion = parent.type === "union";
65
- const name = parent.name;
66
- let padID = 0;
67
- for (let f of parent.fields) {
68
- // autolabel explicit padding fields
69
- if (isPadding(f)) {
70
- parent.tag === "packed"
71
- ? __packedPadding(padID, f.pad, res)
72
- : res.push(`__pad${padID}: [${f.pad}]u8,`);
73
- padID++;
74
- continue;
75
- }
76
- f.doc && gen.doc(f.doc, res, opts);
77
- const { type, defaultVal } = fieldType(parent, f, opts);
78
- ftypes[f.name] = type;
79
- res.push(`${f.name}: ${type}${defaultVal},`);
80
- }
81
- if (parent.body?.zig) {
82
- res.push("", ...ensureLines(parent.body.zig, "impl"), "");
83
- }
84
- res.push("};");
85
- if (opts.debug) {
86
- const fn = (fname, body) => res.push("", `export fn ${name}_${fname}() usize {`, `return ${body};`, `}`);
87
- fn("align", `@alignOf(${name})`);
88
- fn("size", `@sizeOf(${name})`);
89
- for (let f of parent.fields) {
90
- if (isPadding(f))
91
- continue;
92
- fn(f.name + "_align", `@alignOf(${ftypes[f.name]})`);
93
- !isUnion &&
94
- fn(f.name + "_offset", `@offsetOf(${name}, "${f.name}")`);
95
- fn(f.name + "_size", `@sizeOf(${ftypes[f.name]})`);
96
- }
97
- }
98
- res.push("");
99
- return res;
100
- };
101
- /** @internal */
102
- export const fieldType = (parent, f, opts) => {
103
- let type = isWasmString(f.type)
104
- ? isStringSlice(opts.stringType)
105
- ? f.const !== false
106
- ? "[]const u8"
107
- : "[]u8"
108
- : f.const !== false
109
- ? "[*:0]const u8"
110
- : "[*:0]u8"
111
- : f.type;
112
- let defaultVal = defaultValue(f, "zig");
113
- switch (f.tag) {
114
- case "array":
115
- type =
116
- f.sentinel !== undefined
117
- ? `[${f.len}:${f.sentinel}]${type}`
118
- : `[${f.len}]${type}`;
119
- break;
120
- case "slice":
121
- type = `[${f.sentinel !== undefined ? ":" + f.sentinel : ""}]${f.const ? "const " : ""}${type}`;
122
- break;
123
- case "vec":
124
- type = `@Vector(${f.len}, ${type})`;
125
- break;
126
- case "ptr":
127
- type = `*${f.const ? "const " : ""}${f.len ? `[${f.len}]` : ""}${type}`;
128
- break;
129
- case "scalar":
130
- default:
131
- if (defaultVal != undefined) {
132
- if (!(isString(defaultVal) || isNumber(defaultVal))) {
133
- unsupported(`wrong default value for ${parent.name}.${f.name} (${defaultVal})`);
134
- }
135
- }
136
- }
137
- return {
138
- type,
139
- defaultVal: defaultVal != undefined ? ` = ${defaultVal}` : "",
140
- };
141
- };
142
- const __packedPadding = (id, n, res) => {
143
- let i = 0;
144
- n <<= 3;
145
- for (; n >= 128; n -= 128, i++) {
146
- res.push(`__pad${id}_${i}: u128,`);
147
- }
148
- res.push(`__pad${id}_${i}: u${n},`);
149
- };
package/codegen.d.ts DELETED
@@ -1,32 +0,0 @@
1
- import { CodeGenOpts, ICodeGen, TypeColl } from "./api.js";
2
- export declare const DEFAULT_CODEGEN_OPTS: CodeGenOpts;
3
- /**
4
- * Takes a type collection and analyzes each analyzed to compute individual
5
- * alignments and sizes.
6
- *
7
- * @remarks
8
- * This function is idempotent and called automatically by
9
- * {@link generateTypes}. Only exported for dev/debug purposes.
10
- *
11
- * @param types
12
- *
13
- * @internal
14
- */
15
- export declare const prepareTypes: (types: TypeColl, opts: CodeGenOpts) => TypeColl;
16
- /**
17
- * Code generator main entry point. Takes an object of {@link TopLevelType}
18
- * definitions, an actual code generator implementation for a single target
19
- * language and (optional) global codegen options. Returns generated source code
20
- * for all given types as a single string.
21
- *
22
- * @remarks
23
- * Before actual code generation the types are first analyzed to compute their
24
- * alignments and sizes. This is only ever done once (idempotent), even if
25
- * `generateTypes()` is called multiple times for different target langs.
26
- *
27
- * @param types
28
- * @param codegen
29
- * @param opts
30
- */
31
- export declare const generateTypes: (types: TypeColl, codegen: ICodeGen, opts?: Partial<CodeGenOpts>) => string;
32
- //# sourceMappingURL=codegen.d.ts.map