Start implementing ZIG
This commit is contained in:
parent
af4902c9a8
commit
8ee16fb09d
@ -9,3 +9,5 @@ insert_final_newline = true
|
|||||||
indent_size = 2
|
indent_size = 2
|
||||||
[*.md]
|
[*.md]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
[*.zig]
|
||||||
|
indent_size = 4
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
npmRegistryServer: https://npm.hibas123.de
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||||
|
2
examples/Zig/.gitignore
vendored
Normal file
2
examples/Zig/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
zig-cache/
|
||||||
|
generated/
|
34
examples/Zig/build.zig
Normal file
34
examples/Zig/build.zig
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.build.Builder) void {
|
||||||
|
// Standard target options allows the person running `zig build` to choose
|
||||||
|
// what target to build for. Here we do not override the defaults, which
|
||||||
|
// means any target is allowed, and the default is native. Other options
|
||||||
|
// for restricting supported target set are available.
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
|
// Standard release options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||||
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
|
const exe = b.addExecutable("ZigTests", "src/main.zig");
|
||||||
|
exe.setTarget(target);
|
||||||
|
exe.setBuildMode(mode);
|
||||||
|
exe.install();
|
||||||
|
|
||||||
|
const run_cmd = exe.run();
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
|
const exe_tests = b.addTest("src/main.zig");
|
||||||
|
exe_tests.setTarget(target);
|
||||||
|
exe_tests.setBuildMode(mode);
|
||||||
|
|
||||||
|
const test_step = b.step("test", "Run unit tests");
|
||||||
|
test_step.dependOn(&exe_tests.step);
|
||||||
|
}
|
20
examples/Zig/src/main.zig
Normal file
20
examples/Zig/src/main.zig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const t = @import("./generated/mod.zig");
|
||||||
|
|
||||||
|
var mygpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
const gpa = mygpa.allocator();
|
||||||
|
|
||||||
|
const payload =
|
||||||
|
\\{
|
||||||
|
\\ "val_number": 0.12,
|
||||||
|
\\ "val_boolean": true,
|
||||||
|
\\ "val_string": "Hallo Welt"
|
||||||
|
\\}
|
||||||
|
;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var stream = std.json.TokenStream.init(payload);
|
||||||
|
const res = std.json.parse(t.TestAtom, &stream, .{ .allocator = gpa }) catch unreachable;
|
||||||
|
|
||||||
|
std.log.info("{} {s}", .{ res, res.val_string });
|
||||||
|
}
|
25
src/index.ts
25
src/index.ts
@ -44,22 +44,29 @@ yargs(hideBin(process.argv))
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
(argv) => {
|
(argv) => {
|
||||||
if (argv.verbose) {dbg.enable("app");}
|
if (argv.verbose) {
|
||||||
|
dbg.enable("app");
|
||||||
|
}
|
||||||
log("Received compile command with args", argv);
|
log("Received compile command with args", argv);
|
||||||
|
|
||||||
startCompile({
|
startCompile({
|
||||||
input: argv.input,
|
input: argv.input,
|
||||||
targets: argv.output as any,
|
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", {
|
.option("verbose", {
|
||||||
alias: "v",
|
alias: "v",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from "./targets/typescript";
|
} from "./targets/typescript";
|
||||||
import { CSharpTarget } from "./targets/csharp";
|
import { CSharpTarget } from "./targets/csharp";
|
||||||
import { RustTarget } from "./targets/rust";
|
import { RustTarget } from "./targets/rust";
|
||||||
|
import { ZIGTarget } from "./targets/zig";
|
||||||
|
|
||||||
class CatchedError extends Error {}
|
class CatchedError extends Error {}
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ Targets.set("ts-esm", ESMTypescriptTarget);
|
|||||||
Targets.set("ts-node", NodeJSTypescriptTarget);
|
Targets.set("ts-node", NodeJSTypescriptTarget);
|
||||||
Targets.set("c#", CSharpTarget as typeof CompileTarget);
|
Targets.set("c#", CSharpTarget as typeof CompileTarget);
|
||||||
Targets.set("rust", RustTarget as typeof CompileTarget);
|
Targets.set("rust", RustTarget as typeof CompileTarget);
|
||||||
|
Targets.set("zig", ZIGTarget as typeof CompileTarget);
|
||||||
|
|
||||||
function indexToLineAndCol(src: string, index: number) {
|
function indexToLineAndCol(src: string, index: number) {
|
||||||
let line = 1;
|
let line = 1;
|
||||||
|
107
src/targets/zig.ts
Normal file
107
src/targets/zig.ts
Normal 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
20
src/utils.ts
Normal 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"),
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user