Skip to content

Commit 5cfeba9

Browse files
ObserverOfTimeamaanq
authored andcommitted
feat(bindings): add opt-in zig bindings
1 parent 3074c0a commit 5cfeba9

File tree

7 files changed

+128
-5
lines changed

7 files changed

+128
-5
lines changed

cli/loader/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ pub struct Bindings {
239239
pub python: bool,
240240
pub rust: bool,
241241
pub swift: bool,
242+
pub zig: bool,
242243
}
243244

244245
impl Default for Bindings {
@@ -252,6 +253,7 @@ impl Default for Bindings {
252253
python: true,
253254
rust: true,
254255
swift: true,
256+
zig: false,
255257
}
256258
}
257259
}

cli/src/init.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ const TEST_BINDING_PY_TEMPLATE: &str = include_str!("./templates/test_binding.py
9595
const PACKAGE_SWIFT_TEMPLATE: &str = include_str!("./templates/package.swift");
9696
const TESTS_SWIFT_TEMPLATE: &str = include_str!("./templates/tests.swift");
9797

98+
const BUILD_ZIG_TEMPLATE: &str = include_str!("./templates/build.zig");
99+
const BUILD_ZIG_ZON_TEMPLATE: &str = include_str!("./templates/build.zig.zon");
100+
98101
const TREE_SITTER_JSON_SCHEMA: &str =
99102
"https://tree-sitter.github.io/tree-sitter/assets/schemas/config.schema.json";
100103

@@ -314,18 +317,37 @@ pub fn generate_grammar_files(
314317
}
315318

316319
// Write .gitignore file
317-
missing_path(repo_path.join(".gitignore"), |path| {
318-
generate_file(path, GITIGNORE_TEMPLATE, language_name, &generate_opts)
319-
})?;
320+
missing_path_else(
321+
repo_path.join(".gitignore"),
322+
allow_update,
323+
|path| generate_file(path, GITIGNORE_TEMPLATE, language_name, &generate_opts),
324+
|path| {
325+
let contents = fs::read_to_string(path)?;
326+
if !contents.contains("Zig artifacts") {
327+
eprintln!("Replacing .gitignore");
328+
generate_file(path, GITIGNORE_TEMPLATE, language_name, &generate_opts)?;
329+
}
330+
Ok(())
331+
},
332+
)?;
320333

321334
// Write .gitattributes file
322335
missing_path_else(
323336
repo_path.join(".gitattributes"),
324337
allow_update,
325338
|path| generate_file(path, GITATTRIBUTES_TEMPLATE, language_name, &generate_opts),
326339
|path| {
327-
let contents = fs::read_to_string(path)?;
328-
write_file(path, contents.replace("bindings/c/* ", "bindings/c/** "))?;
340+
let mut contents = fs::read_to_string(path)?;
341+
contents = contents.replace("bindings/c/* ", "bindings/c/** ");
342+
if !contents.contains("Zig bindings") {
343+
contents.push('\n');
344+
contents.push_str(indoc! {"
345+
# Zig bindings
346+
build.zig linguist-generated
347+
build.zig.zon linguist-generated
348+
"});
349+
}
350+
write_file(path, contents)?;
329351
Ok(())
330352
},
331353
)?;
@@ -658,6 +680,17 @@ pub fn generate_grammar_files(
658680
})?;
659681
}
660682

683+
// Generate Zig bindings
684+
if tree_sitter_config.bindings.zig {
685+
missing_path(repo_path.join("build.zig"), |path| {
686+
generate_file(path, BUILD_ZIG_TEMPLATE, language_name, &generate_opts)
687+
})?;
688+
689+
missing_path(repo_path.join("build.zig.zon"), |path| {
690+
generate_file(path, BUILD_ZIG_ZON_TEMPLATE, language_name, &generate_opts)
691+
})?;
692+
}
693+
661694
Ok(())
662695
}
663696

cli/src/templates/build.zig

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) !void {
4+
const target = b.standardTargetOptions(.{});
5+
const optimize = b.standardOptimizeOption(.{});
6+
7+
const shared = b.option(bool, "build-shared", "Build a shared library") orelse true;
8+
const reuse_alloc = b.option(bool, "reuse-allocator", "Reuse the library allocator") orelse false;
9+
10+
const lib: *std.Build.Step.Compile = if (shared) b.addSharedLibrary(.{
11+
.name = "tree-sitter-PARSER_NAME",
12+
.pic = true,
13+
.target = target,
14+
.optimize = optimize,
15+
.link_libc = true,
16+
}) else b.addStaticLibrary(.{
17+
.name = "tree-sitter-PARSER_NAME",
18+
.target = target,
19+
.optimize = optimize,
20+
.link_libc = true,
21+
});
22+
23+
lib.addCSourceFile(.{
24+
.file = b.path("src/parser.c"),
25+
.flags = &.{"-std=c11"},
26+
});
27+
if (hasScanner(b.build_root.handle)) {
28+
lib.addCSourceFile(.{
29+
.file = b.path("src/scanner.c"),
30+
.flags = &.{"-std=c11"},
31+
});
32+
}
33+
34+
if (reuse_alloc) {
35+
lib.root_module.addCMacro("TREE_SITTER_REUSE_ALLOCATOR", "");
36+
}
37+
if (optimize == .Debug) {
38+
lib.root_module.addCMacro("TREE_SITTER_DEBUG", "");
39+
}
40+
41+
lib.addIncludePath(b.path("src"));
42+
lib.installHeadersDirectory(b.path("bindings/c"), ".", .{});
43+
44+
b.installArtifact(lib);
45+
b.installFile("src/node-types.json", "node-types.json");
46+
b.installDirectory(.{
47+
.source_dir = b.path("queries"),
48+
.install_dir = .prefix,
49+
.install_subdir = "queries",
50+
.include_extensions = &.{"scm"}
51+
});
52+
53+
const test_cmd = b.addSystemCommand(&.{"tree-sitter", "test"});
54+
const test_step = b.step("test", "Run parser tests");
55+
test_step.dependOn(&test_cmd.step);
56+
}
57+
58+
inline fn hasScanner(dir: std.fs.Dir) bool {
59+
dir.access("src/scanner.c", .{}) catch return false;
60+
return true;
61+
}

cli/src/templates/build.zig.zon

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.{
2+
.name = "tree_sitter_PARSER_NAME",
3+
.version = "PARSER_VERSION",
4+
.dependencies = .{},
5+
.paths = .{
6+
"build.zig",
7+
"build.zig.zon",
8+
"bindings/c",
9+
"src",
10+
"queries",
11+
"LICENSE",
12+
"README.md",
13+
},
14+
}

cli/src/templates/gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ go.sum linguist-generated
3535
bindings/swift/** linguist-generated
3636
Package.swift linguist-generated
3737
Package.resolved linguist-generated
38+
39+
# Zig bindings
40+
build.zig linguist-generated
41+
build.zig.zon linguist-generated

cli/src/templates/gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ dist/
2828
*.exp
2929
*.lib
3030

31+
# Zig artifacts
32+
.zig-cache/
33+
zig-cache/
34+
zig-out/
35+
3136
# Example dirs
3237
/examples/*/
3338

docs/src/assets/schemas/config.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@
272272
"swift": {
273273
"type": "boolean",
274274
"default": true
275+
},
276+
"zig": {
277+
"type": "boolean",
278+
"default": false
275279
}
276280
},
277281
"additionalProperties": false

0 commit comments

Comments
 (0)