Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/src/** linguist-vendored
/src/scanner.cc linguist-vendored=false

# Zig bindings
build.zig linguist-generated
build.zig.zon linguist-generated
49 changes: 42 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
build
node_modules
Cargo.lock
package-lock.json
# Rust artifacts
target/
result*

# tree-sitter now generates a bunch of object files in the repository
# Node artifacts
build/
prebuilds/
node_modules/

# Swift artifacts
.build/

# Go artifacts
_obj/

# Python artifacts
.venv/
dist/
*.egg-info
*.whl

# C artifacts
*.a
*.so
*.o
*.so.*
*.dylib
*.dll
*.pc
*.exp
*.lib

# Zig artifacts
.zig-cache/
zig-cache/
zig-out/

# Example dirs
/examples/*/

# Grammar volatiles
*.wasm
*.obj
*.o

# Archives
*.tar.gz
*.tgz
*.zip
66 changes: 66 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.13)

project(tree-sitter-nickel
VERSION "0.1.0"
DESCRIPTION "Nickel grammar for tree-sitter"
HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-nickel"
LANGUAGES C)

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF)

set(TREE_SITTER_ABI_VERSION 15 CACHE STRING "Tree-sitter ABI version")
if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$")
unset(TREE_SITTER_ABI_VERSION CACHE)
message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer")
endif()

find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI")

add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json"
COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json
--abi=${TREE_SITTER_ABI_VERSION}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating parser.c")

add_library(tree-sitter-nickel src/parser.c)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c)
target_sources(tree-sitter-nickel PRIVATE src/scanner.c)
endif()
target_include_directories(tree-sitter-nickel
PRIVATE src
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bindings/c>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

target_compile_definitions(tree-sitter-nickel PRIVATE
$<$<BOOL:${TREE_SITTER_REUSE_ALLOCATOR}>:TREE_SITTER_REUSE_ALLOCATOR>
$<$<CONFIG:Debug>:TREE_SITTER_DEBUG>)

set_target_properties(tree-sitter-nickel
PROPERTIES
C_STANDARD 11
POSITION_INDEPENDENT_CODE ON
SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}"
DEFINE_SYMBOL "")

configure_file(bindings/c/tree-sitter-nickel.pc.in
"${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-nickel.pc" @ONLY)

include(GNUInstallDirs)

install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING PATTERN "*.h")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-nickel.pc"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig")
install(TARGETS tree-sitter-nickel
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")

file(GLOB QUERIES queries/*.scm)
install(FILES ${QUERIES}
DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/nickel")

add_custom_target(ts-test "${TREE_SITTER_CLI}" test
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "tree-sitter test")
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ $(PARSER): $(SRC_DIR)/grammar.json

install: all
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
Expand Down
9 changes: 9 additions & 0 deletions bindings/node/binding_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const assert = require("node:assert");
const { test } = require("node:test");

const Parser = require("tree-sitter");

test("can load grammar", () => {
const parser = new Parser();
assert.doesNotThrow(() => parser.setLanguage(require(".")));
});
6 changes: 5 additions & 1 deletion bindings/node/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const root = require("path").join(__dirname, "..", "..");

module.exports = require("node-gyp-build")(root);
module.exports =
typeof process.versions.bun === "string"
// Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time
? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-nickel.node`)
: require("node-gyp-build")(root);

try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
Expand Down
12 changes: 12 additions & 0 deletions bindings/python/tests/test_binding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from unittest import TestCase

import tree_sitter
import tree_sitter_nickel


class TestLanguage(TestCase):
def test_can_load_grammar(self):
try:
tree_sitter.Language(tree_sitter_nickel.language())
except Exception:
self.fail("Error loading Nickel grammar")
14 changes: 11 additions & 3 deletions bindings/python/tree_sitter_nickel/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ static PyObject* _binding_language(PyObject *self, PyObject *args) {
return PyLong_FromVoidPtr(tree_sitter_nickel());
}

static struct PyModuleDef_Slot slots[] = {
#ifdef Py_GIL_DISABLED
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
#endif
{0, NULL}
};

static PyMethodDef methods[] = {
{"language", _binding_language, METH_NOARGS,
"Get the tree-sitter language for this grammar."},
Expand All @@ -18,10 +25,11 @@ static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "_binding",
.m_doc = NULL,
.m_size = -1,
.m_methods = methods
.m_size = 0,
.m_methods = methods,
.m_slots = slots,
};

PyMODINIT_FUNC PyInit__binding(void) {
return PyModule_Create(&module);
return PyModuleDef_Init(&module);
}
20 changes: 10 additions & 10 deletions bindings/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ fn main() {
let src_dir = std::path::Path::new("src");

let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs")
.flag_if_supported("-O");
c_config.std("c11").include(src_dir);

#[cfg(target_env = "msvc")]
c_config.flag("-utf-8");

let parser_path = src_dir.join("parser.c");
let scanner_path = src_dir.join("scanner.c");
c_config.file(&parser_path);
c_config.file(&scanner_path);
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());

let scanner_path = src_dir.join("scanner.c");
if scanner_path.exists() {
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
}

c_config.compile("tree-sitter-nickel");
}
45 changes: 23 additions & 22 deletions bindings/rust/lib.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
//! This crate provides nickel language support for the [tree-sitter][] parsing library.
//! This crate provides Nickel language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! Typically, you will use the [LANGUAGE][] constant to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let code = r#"
//! "#;
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(&tree_sitter_nickel::language()).expect("Error loading nickel grammar");
//! let language = tree_sitter_nickel::LANGUAGE;
//! parser
//! .set_language(&language.into())
//! .expect("Error loading Nickel parser");
//! let tree = parser.parse(code, None).unwrap();
//! assert!(!tree.root_node().has_error());
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/

use tree_sitter::Language;
use tree_sitter_language::LanguageFn;

extern "C" {
fn tree_sitter_nickel() -> Language;
fn tree_sitter_nickel() -> *const ();
}

/// Get the tree-sitter [Language][] for this grammar.
/// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_nickel() }
}
/// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html
pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_nickel) };

/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");

// Uncomment these to include any queries that this grammar contains
// NOTE: uncomment these to include any queries that this grammar contains:

// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
// pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");

#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(&super::language())
.expect("Error loading nickel language");
.set_language(&super::LANGUAGE.into())
.expect("Error loading Nickel parser");
}
}
12 changes: 12 additions & 0 deletions bindings/swift/TreeSitterNickelTests/TreeSitterNickelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import XCTest
import SwiftTreeSitter
import TreeSitterNickel

final class TreeSitterNickelTests: XCTestCase {
func testCanLoadGrammar() throws {
let parser = Parser()
let language = Language(language: tree_sitter_nickel())
XCTAssertNoThrow(try parser.setLanguage(language),
"Error loading Nickel grammar")
}
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/tree-sitter/tree-sitter-nickel

go 1.22

require github.com/tree-sitter/go-tree-sitter v0.24.0
Loading