Start implementing ZIG

This commit is contained in:
Fabian Stamm
2022-07-16 21:03:27 +00:00
parent af4902c9a8
commit 8ee16fb09d
9 changed files with 204 additions and 9 deletions

View File

@ -44,22 +44,29 @@ yargs(hideBin(process.argv))
});
},
(argv) => {
if (argv.verbose) {dbg.enable("app");}
if (argv.verbose) {
dbg.enable("app");
}
log("Received compile command with args", argv);
startCompile({
input: argv.input,
targets: argv.output as any,
emitDefinitions: argv.definition
})
emitDefinitions: argv.definition,
});
}
)
.command(
"targets",
"List all targets",
(yargs) => yargs,
() => {
console.log("Targets:");
Targets.forEach((__dirname, target) => {
console.log(" " + target);
});
}
)
.command("targets", "List all targets", (yargs)=>yargs, ()=>{
console.log("Targets:")
Targets.forEach((__dirname, target) => {
console.log(" " + target);
})
})
.option("verbose", {
alias: "v",
type: "boolean",

View File

@ -12,6 +12,7 @@ import {
} from "./targets/typescript";
import { CSharpTarget } from "./targets/csharp";
import { RustTarget } from "./targets/rust";
import { ZIGTarget } from "./targets/zig";
class CatchedError extends Error {}
@ -23,6 +24,7 @@ Targets.set("ts-esm", ESMTypescriptTarget);
Targets.set("ts-node", NodeJSTypescriptTarget);
Targets.set("c#", CSharpTarget as typeof CompileTarget);
Targets.set("rust", RustTarget as typeof CompileTarget);
Targets.set("zig", ZIGTarget as typeof CompileTarget);
function indexToLineAndCol(src: string, index: number) {
let line = 1;

107
src/targets/zig.ts Normal file
View File

@ -0,0 +1,107 @@
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<{ csharp_namespace: string }> {
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 {
throw new Error("Method not implemented.");
}
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("WARNING:"),
"unimplemented step found:",
type
);
// case "service":
}
});
this.writeFile(`mod.zig`, getResult());
}
}

20
src/utils.ts Normal file
View File

@ -0,0 +1,20 @@
export type lineAppender = (ind: number, line: string | string[]) => void;
export function LineAppender(indentSize = 3): {
a: lineAppender;
getResult: () => string;
} {
const lines: string[] = [];
return {
a: (indentation: number, line: string | string[]) => {
if (!Array.isArray(line)) {
line = [line];
}
line.forEach((l) =>
lines.push(" ".repeat(indentation * indentSize) + l.trim())
);
},
getResult: () => lines.join("\n"),
};
}