import { TypeDefinition, ServiceDefinition, EnumDefinition, Step } from "../ir"; import { CompileTarget } from "../compile"; import { LineAppender, lineAppender } from "../utils"; import chalk from "chalk"; const conversion = { boolean: "bool", int: "i64", float: "f64", string: "[]u8", void: "void", bytes: "[]u8", }; function toZigType(type: string): string { return (conversion as any)[type] || type; } export class ZIGTarget extends CompileTarget<{ }> { name: string = "zig"; start(): void { if (this.options.allow_bytes == true) { throw new Error("Zig has no support for 'bytes' yet!"); } } getImport(name: string) { return `const ${name} = @import("./${name}.zig").${name};`; } generateImports(a: lineAppender, def: TypeDefinition | ServiceDefinition) { a(0, `const std = @import("std");`); def.depends.forEach((dep) => { a(0, this.getImport(dep)); }); } generateType(definition: TypeDefinition): void { const { a, getResult } = LineAppender(); this.generateImports(a, definition); a(0, ``); a(0, `pub const ${definition.name} = struct {`); for (const field of definition.fields) { if (field.array) { a(1, `${field.name}: std.ArrayList(${toZigType(field.type)}),`); } else if (field.map) { a( 1, `${field.name}: std.AutoHashMap(${toZigType( field.map )}, ${toZigType(field.type)}),` ); } else { a(1, `${field.name}: ${toZigType(field.type)},`); } } a(0, `};`); this.writeFile(`${definition.name}.zig`, getResult()); } generateEnum(definition: EnumDefinition): void { const { a, getResult } = LineAppender(); a(0, `pub const ${definition.name} = enum(i32) {`); for (const entry of definition.values) { a(1, `${entry.name} = ${entry.value},`); } a(0, `};`); this.writeFile(`${definition.name}.zig`, getResult()); } generateService(definition: ServiceDefinition): void { console.log( chalk.yellow("[ZIG] WARNING:"), "ZIG support for services is not yet there. Service generation is skipped!" ); } finalize(steps: Step[]): void { const { a, getResult } = LineAppender(); steps.forEach(([type, def]) => { switch (type) { case "type": a(0, `pub ${this.getImport(def.name)}`); break; case "enum": a(0, `pub ${this.getImport(def.name)}`); break; default: console.warn( chalk.yellow("[ZIG] WARNING:"), "unimplemented step found:", type ); // case "service": } }); this.writeFile(`mod.zig`, getResult()); } }