├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── build.yml │ └── test.yml ├── .gitignore ├── CMakeLists.txt ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-scheme.h │ └── tree-sitter-scheme.pc.in ├── go │ ├── binding.go │ └── binding_test.go ├── node │ ├── binding.cc │ ├── binding_test.js │ ├── index.d.ts │ └── index.js ├── python │ ├── tests │ │ └── test_binding.py │ └── tree_sitter_scheme │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ ├── TreeSitterScheme │ └── scheme.h │ └── TreeSitterSchemeTests │ └── TreeSitterSchemeTests.swift ├── go.mod ├── grammar.js ├── nodes.md ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── pyproject.toml ├── queries └── highlights.scm ├── setup.py ├── shell.nix ├── src ├── grammar.json ├── node-types.json ├── parser.c └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test └── corpus │ ├── common.scm │ ├── ext.scm │ ├── r5rs.scm │ ├── r6rs.scm │ └── r7rs.scm └── tree-sitter.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | 8 | [{*.js,*.scm,*.ss,package.json}] 9 | indent_style = space 10 | indent_size = 2 11 | 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | src/*.json linguist-generated 4 | src/parser.c linguist-generated 5 | src/tree_sitter/* linguist-generated 6 | 7 | bindings/** linguist-generated 8 | binding.gyp linguist-generated 9 | setup.py linguist-generated 10 | Makefile linguist-generated 11 | Package.swift linguist-generated 12 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | wasm: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - name: Set up tree sitter 12 | uses: tree-sitter/setup-action/cli@v1 13 | with: 14 | tree-sitter-ref: v0.24.7 15 | - name: wasm build 16 | run: tree-sitter build -w -o tree-sitter-scheme.wasm 17 | rust: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Set up Rust 22 | uses: actions-rust-lang/setup-rust-toolchain@v1 23 | - name: Set up tree sitter 24 | uses: tree-sitter/setup-action/cli@v1 25 | with: 26 | tree-sitter-ref: v0.24.7 27 | - name: rust build 28 | run: cargo test --all-features 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | test: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [macos-latest, ubuntu-latest, windows-latest] 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Set up tree sitter 15 | uses: tree-sitter/setup-action/cli@v1 16 | with: 17 | tree-sitter-ref: v0.24.7 18 | - name: Run tests 19 | run: tree-sitter test 20 | 21 | # chez: 22 | # runs-on: ubuntu-latest 23 | # steps: 24 | # - uses: actions/checkout@v3 25 | # - uses: actions/setup-node@v3 26 | # with: 27 | # node-version: 14 28 | # - run: npm install 29 | # - run: git clone --depth 1 https://github.com/cisco/ChezScheme.git 30 | # - run: npx tree-sitter parse $(find ./ChezScheme -type f -name "*.scm" -o -name "*.ss" -not -exec grep -q -e '<<' -e '(#' -e '#{' -e '#!eof' -e '(\\' {} \; -print) -qt 31 | 32 | sicp: 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v4 36 | - name: Set up tree sitter 37 | uses: tree-sitter/setup-action/cli@v1 38 | with: 39 | tree-sitter-ref: v0.24.7 40 | - name: Download sicp code 41 | run: | 42 | mkdir -p sicp && cd sicp 43 | curl https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/code/allcode.tar.gz -O 44 | tar xvf allcode.tar.gz 45 | - run: tree-sitter parse sicp/*.scm -qt 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | target/ 4 | test.scm 5 | unicode.js 6 | *.wasm 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-scheme 4 | VERSION "0.24.7" 5 | DESCRIPTION "Scheme grammar for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-scheme" 7 | LANGUAGES C) 8 | 9 | option(BUILD_SHARED_LIBS "Build using shared libraries" ON) 10 | option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF) 11 | 12 | set(TREE_SITTER_ABI_VERSION 14 CACHE STRING "Tree-sitter ABI version") 13 | if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$") 14 | unset(TREE_SITTER_ABI_VERSION CACHE) 15 | message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer") 16 | endif() 17 | 18 | find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") 19 | 20 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 21 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 22 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 23 | --abi=${TREE_SITTER_ABI_VERSION} 24 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 25 | COMMENT "Generating parser.c") 26 | 27 | add_library(tree-sitter-scheme src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-scheme PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-scheme PRIVATE src) 32 | 33 | target_compile_definitions(tree-sitter-scheme PRIVATE 34 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 35 | $<$:TREE_SITTER_DEBUG>) 36 | 37 | set_target_properties(tree-sitter-scheme 38 | PROPERTIES 39 | C_STANDARD 11 40 | POSITION_INDEPENDENT_CODE ON 41 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 42 | DEFINE_SYMBOL "") 43 | 44 | configure_file(bindings/c/tree-sitter-scheme.pc.in 45 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-scheme.pc" @ONLY) 46 | 47 | include(GNUInstallDirs) 48 | 49 | install(FILES bindings/c/tree-sitter-scheme.h 50 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") 51 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-scheme.pc" 52 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 53 | install(TARGETS tree-sitter-scheme 54 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 55 | 56 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 57 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 58 | COMMENT "tree-sitter test") 59 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you to contribute `tree-sitter-scheme`. 4 | 5 | ## Workflow 6 | 7 | It's recommended to use [nix](https://nixos.org/) package manager, and run 8 | 9 | ```shell 10 | nix-shell 11 | npm install # if you haven't install node modules 12 | ``` 13 | 14 | Then you can use `tree-sitter` command: 15 | 16 | ```shell 17 | tree-sitter generate 18 | tree-sitter test 19 | ``` 20 | 21 | If you dont't use nix, you should follow the [official setup](https://tree-sitter.github.io/tree-sitter/creating-parsers) to configure the dev environment. 22 | 23 | ## Todo 24 | 25 | * check the tracking issues 26 | * review the code to ensure it meets the standard 27 | * improve queries 28 | 29 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "cc" 16 | version = "1.2.20" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" 19 | dependencies = [ 20 | "shlex", 21 | ] 22 | 23 | [[package]] 24 | name = "memchr" 25 | version = "2.7.4" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 28 | 29 | [[package]] 30 | name = "regex" 31 | version = "1.10.6" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 34 | dependencies = [ 35 | "aho-corasick", 36 | "memchr", 37 | "regex-automata", 38 | "regex-syntax", 39 | ] 40 | 41 | [[package]] 42 | name = "regex-automata" 43 | version = "0.4.7" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 46 | dependencies = [ 47 | "aho-corasick", 48 | "memchr", 49 | "regex-syntax", 50 | ] 51 | 52 | [[package]] 53 | name = "regex-syntax" 54 | version = "0.8.4" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 57 | 58 | [[package]] 59 | name = "shlex" 60 | version = "1.3.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 63 | 64 | [[package]] 65 | name = "streaming-iterator" 66 | version = "0.1.9" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" 69 | 70 | [[package]] 71 | name = "tree-sitter" 72 | version = "0.24.7" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "a5387dffa7ffc7d2dae12b50c6f7aab8ff79d6210147c6613561fc3d474c6f75" 75 | dependencies = [ 76 | "cc", 77 | "regex", 78 | "regex-syntax", 79 | "streaming-iterator", 80 | "tree-sitter-language", 81 | ] 82 | 83 | [[package]] 84 | name = "tree-sitter-language" 85 | version = "0.1.0" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "2545046bd1473dac6c626659cc2567c6c0ff302fc8b84a56c4243378276f7f57" 88 | 89 | [[package]] 90 | name = "tree-sitter-scheme" 91 | version = "0.24.7" 92 | dependencies = [ 93 | "cc", 94 | "tree-sitter", 95 | "tree-sitter-language", 96 | ] 97 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-scheme" 3 | description = "Scheme grammar for tree-sitter" 4 | version = "0.24.7" 5 | authors = ["6cdh"] 6 | license = "MIT" 7 | readme = "README.md" 8 | keywords = ["incremental", "parsing", "tree-sitter", "scheme"] 9 | categories = ["parsing", "text-editors"] 10 | repository = "https://github.com/tree-sitter/tree-sitter-scheme" 11 | edition = "2021" 12 | autoexamples = false 13 | 14 | build = "bindings/rust/build.rs" 15 | include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*", "tree-sitter.json"] 16 | 17 | [lib] 18 | path = "bindings/rust/lib.rs" 19 | 20 | [dependencies] 21 | tree-sitter-language = "0.1" 22 | 23 | [build-dependencies] 24 | cc = "1.1.22" 25 | 26 | [dev-dependencies] 27 | tree-sitter = "0.24.7" 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 6cdh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-scheme 6 | HOMEPAGE_URL := https://github.com/6cdh/tree-sitter-scheme 7 | VERSION := 0.24.7 8 | 9 | # repository 10 | SRC_DIR := src 11 | 12 | TS ?= tree-sitter 13 | 14 | # install directory layout 15 | PREFIX ?= /usr/local 16 | INCLUDEDIR ?= $(PREFIX)/include 17 | LIBDIR ?= $(PREFIX)/lib 18 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 19 | 20 | # source/object files 21 | PARSER := $(SRC_DIR)/parser.c 22 | EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 23 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 24 | 25 | # flags 26 | ARFLAGS ?= rcs 27 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 28 | 29 | # ABI versioning 30 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 31 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 32 | 33 | # OS-specific bits 34 | ifeq ($(shell uname),Darwin) 35 | SOEXT = dylib 36 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 37 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 38 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 39 | else 40 | SOEXT = so 41 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 42 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 43 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 44 | endif 45 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 46 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 47 | endif 48 | 49 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 50 | 51 | lib$(LANGUAGE_NAME).a: $(OBJS) 52 | $(AR) $(ARFLAGS) $@ $^ 53 | 54 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 55 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 56 | ifneq ($(STRIP),) 57 | $(STRIP) $@ 58 | endif 59 | 60 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 61 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 62 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 63 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 64 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 65 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 66 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 67 | 68 | $(PARSER): $(SRC_DIR)/grammar.json 69 | $(TS) generate $^ 70 | 71 | install: all 72 | install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 73 | install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 74 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 75 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 76 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 77 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 78 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 79 | 80 | uninstall: 81 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 82 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 83 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 84 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 85 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 86 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 87 | 88 | clean: 89 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 90 | 91 | test: 92 | $(TS) test 93 | 94 | .PHONY: all install uninstall clean test 95 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "TreeSitterScheme", 6 | products: [ 7 | .library(name: "TreeSitterScheme", targets: ["TreeSitterScheme"]), 8 | ], 9 | dependencies: [ 10 | .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), 11 | ], 12 | targets: [ 13 | .target( 14 | name: "TreeSitterScheme", 15 | dependencies: [], 16 | path: ".", 17 | sources: [ 18 | "src/parser.c", 19 | // NOTE: if your language has an external scanner, add it here. 20 | ], 21 | resources: [ 22 | .copy("queries") 23 | ], 24 | publicHeadersPath: "bindings/swift", 25 | cSettings: [.headerSearchPath("src")] 26 | ), 27 | .testTarget( 28 | name: "TreeSitterSchemeTests", 29 | dependencies: [ 30 | "SwiftTreeSitter", 31 | "TreeSitterScheme", 32 | ], 33 | path: "bindings/swift/TreeSitterSchemeTests" 34 | ) 35 | ], 36 | cLanguageStandard: .c11 37 | ) 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-scheme 2 | 3 | [![Build/test](https://github.com/6cdh/tree-sitter-scheme/workflows/Build/test/badge.svg)](https://github.com/6cdh/tree-sitter-scheme/actions/workflows/test.yml) 4 | 5 | Scheme grammar for tree-sitter. 6 | 7 | ## Recent News 8 | 9 | * With R7RS support, a single `|` can no longer appear in the middle of an identifier. 10 | * The node `directive` no longer contains the sub node `symbol`. It is now a single node. 11 | * Some extensions were added, see below. 12 | 13 | ## Status 14 | 15 | ~~tree-sitter-scheme should work on a superset of Scheme.~~ 16 | 17 | Different implementations might have conflicting grammars. I am not sure if I should support 18 | them. If you need some implementation-specific features, please open an issue, then I will consider supporting it. 19 | 20 | current status: 21 | 22 | * [x] R5RS 23 | * [x] R6RS 24 | * [x] R7RS 25 | * [ ] Extensions 26 | * [x] `{}` as replacement for `()` or `[]` 27 | * [x] extend symbols which can start with digits, period, ... etc as long as it's not a number 28 | * [x] keyword `#:symbol` 29 | * [x] escape sequence in string `\` + any character 30 | * [x] characters `#\bel`, `#\ls`, `#\nel`, `#\rubout`, `#\vt` 31 | 32 | Please open an issue to let me know it's really used if you want to add new extensions. 33 | 34 | ## Implementation 35 | 36 | * [ ] Support for implementation 37 | * [ ] Chez Scheme ([#1](https://github.com/6cdh/tree-sitter-scheme/issues/1)) 38 | * [ ] Chicken Scheme ([#3](https://github.com/6cdh/tree-sitter-scheme/issues/3)) 39 | * [ ] Guile Scheme ([#7](https://github.com/6cdh/tree-sitter-scheme/issues/7)) 40 | 41 | ## Usage 42 | 43 | See [nodes.md](./nodes.md) for all visible nodes. 44 | 45 | This parser doesn't parse language constructs. Instead, it parses code as lists. 46 | 47 | If you want language constructs support, use custom queries (see [#5](https://github.com/6cdh/tree-sitter-scheme/issues/5)), also see [thchha/tree-sitter-scheme](https://gitlab.com/thchha/tree-sitter-scheme). 48 | 49 | ## Query 50 | 51 | The queries here are too simple and not intended to be useful in an editor. 52 | Please open an issue if you have suggestions. 53 | 54 | ## Reference 55 | 56 | Scheme 57 | 58 | * [R5RS](https://schemers.org/Documents/Standards/R5RS/) 59 | * [R6RS](http://www.r6rs.org/) 60 | * [R7RS](https://small.r7rs.org/) 61 | * [The Scheme Programming Language](https://www.scheme.com/tspl4/) 62 | 63 | Tree-sitter 64 | 65 | * [official documents](https://tree-sitter.github.io/tree-sitter) 66 | * [Guide to your first Tree-sitter grammar](https://gist.github.com/Aerijo/df27228d70c633e088b0591b8857eeef) 67 | * [tree-sitter-clojure](https://github.com/sogaiu/tree-sitter-clojure) 68 | * [tree-sitter-commonlisp](https://github.com/theHamsta/tree-sitter-commonlisp) 69 | * [tree-sitter-fennel](https://github.com/TravonteD/tree-sitter-fennel) 70 | 71 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_scheme_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_scheme(); 6 | 7 | // "tree-sitter", "language" hashed with BLAKE2 8 | const napi_type_tag LANGUAGE_TYPE_TAG = { 9 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 10 | }; 11 | 12 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 13 | exports["name"] = Napi::String::New(env, "scheme"); 14 | auto language = Napi::External::New(env, tree_sitter_scheme()); 15 | language.TypeTag(&LANGUAGE_TYPE_TAG); 16 | exports["language"] = language; 17 | return exports; 18 | } 19 | 20 | NODE_API_MODULE(tree_sitter_scheme_binding, Init) 21 | -------------------------------------------------------------------------------- /bindings/node/binding_test.js: -------------------------------------------------------------------------------- 1 | const assert = require("node:assert"); 2 | const { test } = require("node:test"); 3 | 4 | const Parser = require("tree-sitter"); 5 | 6 | test("can load grammar", () => { 7 | const parser = new Parser(); 8 | assert.doesNotThrow(() => parser.setLanguage(require("."))); 9 | }); 10 | -------------------------------------------------------------------------------- /bindings/node/index.d.ts: -------------------------------------------------------------------------------- 1 | type BaseNode = { 2 | type: string; 3 | named: boolean; 4 | }; 5 | 6 | type ChildNode = { 7 | multiple: boolean; 8 | required: boolean; 9 | types: BaseNode[]; 10 | }; 11 | 12 | type NodeInfo = 13 | | (BaseNode & { 14 | subtypes: BaseNode[]; 15 | }) 16 | | (BaseNode & { 17 | fields: { [name: string]: ChildNode }; 18 | children: ChildNode[]; 19 | }); 20 | 21 | type Language = { 22 | name: string; 23 | language: unknown; 24 | nodeTypeInfo: NodeInfo[]; 25 | }; 26 | 27 | declare const language: Language; 28 | export = language; 29 | -------------------------------------------------------------------------------- /bindings/node/index.js: -------------------------------------------------------------------------------- 1 | const root = require("path").join(__dirname, "..", ".."); 2 | 3 | module.exports = 4 | typeof process.versions.bun === "string" 5 | // Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time 6 | ? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-scheme.node`) 7 | : require("node-gyp-build")(root); 8 | 9 | try { 10 | module.exports.nodeTypeInfo = require("../../src/node-types.json"); 11 | } catch (_) {} 12 | -------------------------------------------------------------------------------- /bindings/python/tests/test_binding.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import tree_sitter, tree_sitter_scheme 4 | 5 | 6 | class TestLanguage(TestCase): 7 | def test_can_load_grammar(self): 8 | try: 9 | tree_sitter.Language(tree_sitter_scheme.language()) 10 | except Exception: 11 | self.fail("Error loading Scheme grammar") 12 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_scheme/__init__.py: -------------------------------------------------------------------------------- 1 | """Scheme grammar for tree-sitter""" 2 | 3 | from importlib.resources import files as _files 4 | 5 | from ._binding import language 6 | 7 | 8 | def _get_query(name, file): 9 | query = _files(f"{__package__}.queries") / file 10 | globals()[name] = query.read_text() 11 | return globals()[name] 12 | 13 | 14 | def __getattr__(name): 15 | # NOTE: uncomment these to include any queries that this grammar contains: 16 | 17 | # if name == "HIGHLIGHTS_QUERY": 18 | # return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 19 | # if name == "INJECTIONS_QUERY": 20 | # return _get_query("INJECTIONS_QUERY", "injections.scm") 21 | # if name == "LOCALS_QUERY": 22 | # return _get_query("LOCALS_QUERY", "locals.scm") 23 | # if name == "TAGS_QUERY": 24 | # return _get_query("TAGS_QUERY", "tags.scm") 25 | 26 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 27 | 28 | 29 | __all__ = [ 30 | "language", 31 | # "HIGHLIGHTS_QUERY", 32 | # "INJECTIONS_QUERY", 33 | # "LOCALS_QUERY", 34 | # "TAGS_QUERY", 35 | ] 36 | 37 | 38 | def __dir__(): 39 | return sorted(__all__ + [ 40 | "__all__", "__builtins__", "__cached__", "__doc__", "__file__", 41 | "__loader__", "__name__", "__package__", "__path__", "__spec__", 42 | ]) 43 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_scheme/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | # NOTE: uncomment these to include any queries that this grammar contains: 4 | 5 | # HIGHLIGHTS_QUERY: Final[str] 6 | # INJECTIONS_QUERY: Final[str] 7 | # LOCALS_QUERY: Final[str] 8 | # TAGS_QUERY: Final[str] 9 | 10 | def language() -> object: ... 11 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_scheme/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_scheme(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_scheme(), "tree_sitter.Language", NULL); 9 | } 10 | 11 | static PyMethodDef methods[] = { 12 | {"language", _binding_language, METH_NOARGS, 13 | "Get the tree-sitter language for this grammar."}, 14 | {NULL, NULL, 0, NULL} 15 | }; 16 | 17 | static struct PyModuleDef module = { 18 | .m_base = PyModuleDef_HEAD_INIT, 19 | .m_name = "_binding", 20 | .m_doc = NULL, 21 | .m_size = -1, 22 | .m_methods = methods 23 | }; 24 | 25 | PyMODINIT_FUNC PyInit__binding(void) { 26 | return PyModule_Create(&module); 27 | } 28 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_scheme/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/6cdh/tree-sitter-scheme/e35b41a183164f4a12e10da3d0c430e837c3d75a/bindings/python/tree_sitter_scheme/py.typed -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let src_dir = std::path::Path::new("src"); 3 | 4 | let mut c_config = cc::Build::new(); 5 | c_config.std("c11").include(src_dir); 6 | 7 | #[cfg(target_env = "msvc")] 8 | c_config.flag("-utf-8"); 9 | 10 | let parser_path = src_dir.join("parser.c"); 11 | c_config.file(&parser_path); 12 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 13 | 14 | // NOTE: if your language uses an external scanner, uncomment this block: 15 | /* 16 | let scanner_path = src_dir.join("scanner.c"); 17 | c_config.file(&scanner_path); 18 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 19 | */ 20 | 21 | c_config.compile("tree-sitter-scheme"); 22 | } 23 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides Scheme language support for the [tree-sitter][] parsing library. 2 | //! 3 | //! Typically, you will use the [LANGUAGE][] constant to add this language to a 4 | //! tree-sitter [Parser][], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! let code = r#" 8 | //! "#; 9 | //! let mut parser = tree_sitter::Parser::new(); 10 | //! let language = tree_sitter_scheme::LANGUAGE; 11 | //! parser 12 | //! .set_language(&language.into()) 13 | //! .expect("Error loading Scheme parser"); 14 | //! let tree = parser.parse(code, None).unwrap(); 15 | //! assert!(!tree.root_node().has_error()); 16 | //! ``` 17 | //! 18 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 19 | //! [tree-sitter]: https://tree-sitter.github.io/ 20 | 21 | use tree_sitter_language::LanguageFn; 22 | 23 | extern "C" { 24 | fn tree_sitter_scheme() -> *const (); 25 | } 26 | 27 | /// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar. 28 | /// 29 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 30 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_scheme) }; 31 | 32 | /// The content of the [`node-types.json`][] file for this grammar. 33 | /// 34 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 35 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 36 | 37 | // NOTE: uncomment these to include any queries that this grammar contains: 38 | 39 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 40 | // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); 41 | // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); 42 | // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); 43 | 44 | #[cfg(test)] 45 | mod tests { 46 | #[test] 47 | fn test_can_load_grammar() { 48 | let mut parser = tree_sitter::Parser::new(); 49 | parser 50 | .set_language(&super::LANGUAGE.into()) 51 | .expect("Error loading Scheme parser"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterScheme/scheme.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_SCHEME_H_ 2 | #define TREE_SITTER_SCHEME_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_scheme(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_SCHEME_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterSchemeTests/TreeSitterSchemeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterScheme 4 | 5 | final class TreeSitterSchemeTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_scheme()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading Scheme grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter/tree-sitter-scheme 2 | 3 | go 1.22 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | // r5rs: case insensitive 2 | // comment: only line comment 3 | // r6rs: case sensitive except boolean, number, unicode hex literals 4 | // comment: all 5 | // r7rs: case insensitive except letters, character names, mnemonic escapes. 6 | // comment: all 7 | 8 | const PREC = { 9 | first: $ => prec(100, $), 10 | last: $ => prec(-100, $), 11 | }; 12 | 13 | const common = { 14 | whitespace: /[ \r\n\t\f\v\p{Zs}\p{Zl}\p{Zp}]/, 15 | intra_whitespace: /[\t\p{Zs}]/, 16 | line_ending: /[\n\r\u{2028}\u{0085}]|(\r\n)|(\r\u{0085})/, 17 | any_char: /.|[\r\n\u{85}\u{2028}\u{2029}]/, 18 | 19 | symbol_element: /[^ \r\n\t\f\v\p{Zs}\p{Zl}\p{Zp}#;"'`,\(\)\{\}\[\]\\\|]/, 20 | }; 21 | 22 | const r5rs = { 23 | boolean: seq("#", /[tTfF]/), 24 | number: 25 | choice( 26 | r5rs_number_base(2), 27 | r5rs_number_base(8), 28 | r5rs_number_base(10), 29 | r5rs_number_base(16)), 30 | character: 31 | seq( 32 | "#\\", 33 | choice( 34 | /[sS][pP][aA][cC][eE]/, 35 | /[nN][eE][wW][lL][iI][nN][eE]/, 36 | common.any_char)), 37 | escape_sequence: 38 | choice( 39 | "\\\"", 40 | "\\\\"), 41 | }; 42 | 43 | const r6rs = { 44 | boolean: seq("#", /[tTfF]/), 45 | number: 46 | choice( 47 | r6rs_number_base(2), 48 | r6rs_number_base(8), 49 | r6rs_number_base(10), 50 | r6rs_number_base(16)), 51 | character: 52 | seq( 53 | "#\\", 54 | choice( 55 | "nul", "alarm", "backspace", "tab", 56 | "linefeed", "newline", "vtab", "page", 57 | "return", "esc", "space", "delete", 58 | /x[0-9a-fA-F]+/, 59 | common.any_char)), 60 | escape_sequence: 61 | seq( 62 | "\\", 63 | choice( 64 | /[abtnvfr"\\]/, 65 | /x[0-9a-fA-F]+;/, 66 | seq( 67 | common.intra_whitespace, 68 | common.line_ending, 69 | common.intra_whitespace))), 70 | }; 71 | 72 | const r7rs = { 73 | boolean: 74 | seq( 75 | "#", 76 | choice( 77 | /[tTfF]/, 78 | /[tT][rR][uU][eE]/, 79 | /[fF][aA][lL][sS][eE]/)), 80 | number: 81 | choice( 82 | r7rs_number_base(2), 83 | r7rs_number_base(8), 84 | r7rs_number_base(10), 85 | r7rs_number_base(16)), 86 | character: 87 | seq( 88 | "#\\", 89 | choice( 90 | "alarm", "backspace", "delete", 91 | "escape", "newline", "null", 92 | "return", "space", "tab", 93 | /[xX][0-9a-fA-F]+/, 94 | common.any_char)), 95 | escape_sequence: 96 | seq( 97 | "\\", 98 | choice( 99 | /[abtnr"\\]/, 100 | seq( 101 | repeat(common.intra_whitespace), 102 | common.line_ending, 103 | repeat(common.intra_whitespace)), 104 | /[xX][0-9a-fA-F]+;/)), 105 | symbol: 106 | seq( 107 | "|", 108 | repeat( 109 | choice( 110 | /[^\|\\]+/, 111 | /\\[xX][0-9a-fA-F]+;/, 112 | /\\[abtnr]/, 113 | "\\|")), 114 | "|") 115 | }; 116 | 117 | const extension = { 118 | escape_sequence: /\\./, 119 | character: 120 | seq( 121 | "#\\", 122 | choice("bel", "ls", "nel", "rubout", "vt")), 123 | }; 124 | 125 | const hidden_node = { 126 | symbol: 127 | token( 128 | choice( 129 | repeat1(common.symbol_element), 130 | r7rs.symbol)), 131 | }; 132 | 133 | module.exports = grammar({ 134 | name: "scheme", 135 | 136 | extras: _ => [], 137 | 138 | rules: { 139 | program: $ => repeat($._token), 140 | 141 | _token: $ => 142 | choice( 143 | $._intertoken, 144 | $._datum), 145 | 146 | _intertoken: $ => 147 | choice( 148 | // NOTE: `repeat1` here can significantly reduce code size than `repeat` 149 | token(repeat1(common.whitespace)), 150 | $.directive, 151 | $.comment, 152 | $.block_comment), 153 | 154 | comment: $ => 155 | choice( 156 | /;.*/, 157 | seq("#;", repeat($._intertoken), $._datum)), 158 | 159 | directive: $ => 160 | seq("#!", repeat($._intertoken), hidden_node.symbol), 161 | 162 | block_comment: $ => 163 | seq("#|", 164 | repeat( 165 | choice( 166 | PREC.first($.block_comment), 167 | common.any_char)), 168 | PREC.first("|#")), 169 | 170 | _datum: $ => choice( 171 | $.boolean, 172 | $.character, 173 | $.string, 174 | 175 | // number/symbol precedence 176 | // for same length token, prefer number 177 | // otherwise, prefer symbol which is also longer 178 | $.number, 179 | $.symbol, 180 | 181 | $.vector, 182 | $.byte_vector, 183 | $.list, 184 | 185 | $.quote, 186 | $.quasiquote, 187 | $.unquote, 188 | $.unquote_splicing, 189 | $.syntax, 190 | $.quasisyntax, 191 | $.unsyntax, 192 | $.unsyntax_splicing, 193 | 194 | $.keyword), 195 | 196 | // simple datum {{{ 197 | 198 | boolean: _ => 199 | token( 200 | choice( 201 | r5rs.boolean, 202 | r6rs.boolean, 203 | r7rs.boolean)), 204 | 205 | number: _ => 206 | token( 207 | choice( 208 | r5rs.number, 209 | r6rs.number, 210 | r7rs.number)), 211 | 212 | character: _ => 213 | token( 214 | choice( 215 | r5rs.character, 216 | r6rs.character, 217 | r7rs.character, 218 | extension.character)), 219 | 220 | string: $ => 221 | seq( 222 | '"', 223 | repeat( 224 | choice( 225 | $.escape_sequence, 226 | /[^"\\]+/)), 227 | '"'), 228 | 229 | escape_sequence: _ => 230 | token( 231 | choice( 232 | r5rs.escape_sequence, 233 | r6rs.escape_sequence, 234 | r7rs.escape_sequence, 235 | extension.escape_sequence)), 236 | 237 | symbol: _ => token(hidden_node.symbol), 238 | 239 | keyword: _ => 240 | token( 241 | seq( 242 | "#:", 243 | hidden_node.symbol)), 244 | 245 | // simple datum }}} 246 | 247 | // compound datum {{{ 248 | 249 | list: $ => 250 | choice( 251 | seq("(", repeat($._token), ")"), 252 | seq("[", repeat($._token), "]"), 253 | seq("{", repeat($._token), "}")), 254 | 255 | quote: $ => 256 | seq( 257 | "'", 258 | repeat($._intertoken), 259 | $._datum), 260 | 261 | quasiquote: $ => 262 | seq( 263 | "`", 264 | repeat($._intertoken), 265 | $._datum), 266 | 267 | syntax: $ => 268 | seq( 269 | "#'", 270 | repeat($._intertoken), 271 | $._datum), 272 | 273 | quasisyntax: $ => 274 | seq( 275 | "#`", 276 | repeat($._intertoken), 277 | $._datum), 278 | 279 | unquote: $ => 280 | seq( 281 | ",", 282 | repeat($._intertoken), 283 | $._datum), 284 | 285 | unquote_splicing: $ => 286 | seq( 287 | ",@", 288 | repeat($._intertoken), 289 | $._datum), 290 | 291 | unsyntax: $ => 292 | seq( 293 | "#,", 294 | repeat($._intertoken), 295 | $._datum), 296 | 297 | unsyntax_splicing: $ => 298 | seq( 299 | "#,@", 300 | repeat($._intertoken), 301 | $._datum), 302 | 303 | vector: $ => seq("#(", repeat($._token), ")"), 304 | 305 | byte_vector: $ => seq("#vu8(", repeat($._token), ")"), 306 | // compound datum }}} 307 | }, 308 | }); 309 | 310 | // number {{{ 311 | 312 | function r5rs_number_base(n) { 313 | const radixn = { 314 | 2: choice("#b", "#B"), 315 | 8: choice("#o", "#O"), 316 | 10: optional(choice("#d", "#D")), 317 | 16: choice("#x", "#X"), 318 | }; 319 | const digitsn = { 320 | 2: /[01]/, 321 | 8: /[0-7]/, 322 | 10: /[0-9]/, 323 | 16: /[0-9a-fA-F]/, 324 | }; 325 | 326 | const exactness = 327 | optional( 328 | choice("#i", "#e", "#I", "#E")); 329 | const radix = radixn[n]; 330 | const prefix = 331 | choice( 332 | seq(radix, exactness), 333 | seq(exactness, radix)); 334 | 335 | const sign = optional(/[+-]/); 336 | const digits = digitsn[n]; 337 | 338 | const exponent = /[eEsSfFdDlL]/; 339 | const suffix = 340 | optional( 341 | seq( 342 | exponent, 343 | sign, 344 | repeat1(digitsn[10]))); 345 | 346 | const uinteger = 347 | seq( 348 | repeat1(digits), 349 | repeat("#")); 350 | const decimal10 = choice( 351 | seq(uinteger, suffix), 352 | seq(".", repeat1(digits), repeat("#"), suffix), 353 | seq(repeat1(digits), ".", repeat(digits), repeat("#"), suffix), 354 | seq(repeat1(digits), repeat1("#"), ".", repeat("#"), suffix) 355 | ); 356 | const decimal = { 357 | 2: "", 358 | 8: "", 359 | 10: decimal10, 360 | 16: "", 361 | }[n]; 362 | 363 | const ureal = 364 | choice( 365 | uinteger, 366 | seq(uinteger, "/", uinteger), 367 | decimal); 368 | const real = seq(sign, ureal); 369 | const complex = choice( 370 | real, 371 | seq(real, "@", real), 372 | seq(optional(real), /[+-]/, optional(ureal), "i") 373 | ); 374 | 375 | return seq(prefix, complex); 376 | } 377 | 378 | function r6rs_number_base(n) { 379 | const radixn = { 380 | 2: choice("#b", "#B"), 381 | 8: choice("#o", "#O"), 382 | 10: optional(choice("#d", "#D")), 383 | 16: choice("#x", "#X"), 384 | }; 385 | const digitsn = { 386 | 2: /[01]/, 387 | 8: /[0-7]/, 388 | 10: /[0-9]/, 389 | 16: /[0-9a-fA-F]/, 390 | }; 391 | 392 | const exactness = 393 | optional( 394 | choice("#i", "#e", "#I", "#E")); 395 | const radix = radixn[n]; 396 | const prefix = 397 | choice( 398 | seq(radix, exactness), 399 | seq(exactness, radix)); 400 | 401 | const sign = optional(/[+-]/); 402 | const digits = digitsn[n]; 403 | const digits10 = digitsn[10]; 404 | 405 | const exponent = /[eEsSfFdDlL]/; 406 | const suffix = 407 | optional( 408 | seq( 409 | exponent, 410 | sign, 411 | repeat1(digits10))); 412 | 413 | const uinteger = repeat1(digits); 414 | const decimal10 = 415 | choice( 416 | seq(uinteger, suffix), 417 | seq(".", repeat1(digits), suffix), 418 | seq(repeat1(digits), ".", repeat(digits), suffix), 419 | seq(repeat1(digits), ".", suffix)); 420 | const decimal = { 421 | 2: "", 422 | 8: "", 423 | 10: decimal10, 424 | 16: "", 425 | }[n]; 426 | 427 | const mantissa_width = 428 | optional( 429 | seq("|", repeat1(digits10))); 430 | 431 | const naninf = choice("nan.0", "inf.0"); 432 | 433 | const ureal = 434 | seq( 435 | choice( 436 | uinteger, 437 | seq(uinteger, "/", uinteger), 438 | seq(decimal, mantissa_width))); 439 | const real = 440 | choice( 441 | seq(sign, ureal), 442 | seq(/[+-]/, naninf)); 443 | const complex = 444 | choice( 445 | real, 446 | seq(real, "@", real), 447 | seq( 448 | optional(real), 449 | /[+-]/, 450 | optional(choice(ureal, naninf)), 451 | "i")); 452 | 453 | return seq(prefix, complex); 454 | } 455 | 456 | function r7rs_number_base(n) { 457 | const infnan = 458 | choice( 459 | /[+-][iI][nN][fF]\.0/, 460 | /[+-][nN][aA][nN]\.0/); 461 | 462 | const exponent_marker = /[eE]/; 463 | const sign = optional(/[+-]/); 464 | const exactness = optional(/#[ieIE]/); 465 | const radix = 466 | { 467 | 2: /#[bB]/, 468 | 8: /#[oO]/, 469 | 10: optional(/#[dD]/), 470 | 16: /#[xX]/, 471 | }[n]; 472 | const digit = 473 | { 474 | 2: /[01]/, 475 | 8: /[0-7]/, 476 | 10: /[0-9]/, 477 | 16: /[0-9a-fA-F]/, 478 | }[n]; 479 | 480 | const suffix = 481 | optional( 482 | seq(exponent_marker, sign, repeat1(digit))); 483 | 484 | const prefix = 485 | choice( 486 | seq(radix, exactness), 487 | seq(exactness, radix)); 488 | 489 | const uinteger = repeat1(digit); 490 | 491 | const decimal = 492 | { 493 | 2: "", 494 | 8: "", 495 | 10: 496 | choice( 497 | seq(uinteger, suffix), 498 | seq(".", repeat1(digit), suffix), 499 | seq(repeat1(digit), ".", repeat(digit), suffix)), 500 | 16: "", 501 | }[n]; 502 | 503 | const ureal = 504 | choice( 505 | uinteger, 506 | seq(uinteger, "/", uinteger), 507 | decimal); 508 | 509 | const real = 510 | choice( 511 | seq(sign, ureal), 512 | infnan); 513 | 514 | const complex = 515 | choice( 516 | real, 517 | seq(real, "@", real), 518 | seq(real, /[+-]/, ureal, "i"), 519 | seq(real, /[+-]/, "i"), 520 | seq(real, infnan, "i"), 521 | seq(/[+-]/, ureal, "i"), 522 | seq(infnan, "i"), 523 | seq(/[+-]/, "i")); 524 | 525 | const num = 526 | seq( 527 | prefix, 528 | complex); 529 | 530 | return num; 531 | } 532 | 533 | // number }}} 534 | -------------------------------------------------------------------------------- /nodes.md: -------------------------------------------------------------------------------- 1 | ## Nodes 2 | 3 | This page contains all visible nodes in yaml format. 4 | 5 | ```yaml 6 | - comment 7 | - block_comment # for example, #| something |# 8 | - directive # for example, #!r6rs 9 | - boolean 10 | - character 11 | - string 12 | - escape_sequence # escape sequence in string, for example, \n in "abc\n" 13 | - number 14 | - symbol # identifier 15 | - keyword # #:identifier 16 | 17 | - list # things surrounded by () or [] or {} 18 | - quote # ' 19 | - quasiquote # ` 20 | - syntax # #' 21 | - quasisyntax #` 22 | - unquote # , 23 | - unquote_splicing # ,@ 24 | - unsyntax # #, 25 | - unsyntax_splicing # #,@ 26 | 27 | - vector 28 | - byte_vector 29 | ``` 30 | 31 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-scheme", 3 | "version": "0.24.7", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tree-sitter-scheme", 9 | "version": "0.24.7", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "dependencies": { 13 | "node-addon-api": "^8.0.0", 14 | "node-gyp-build": "^4.8.1" 15 | }, 16 | "devDependencies": { 17 | "prebuildify": "^6.0.1", 18 | "tree-sitter-cli": "^0.24.7" 19 | }, 20 | "peerDependencies": { 21 | "tree-sitter": "^0.21.1" 22 | }, 23 | "peerDependenciesMeta": { 24 | "tree_sitter": { 25 | "optional": true 26 | } 27 | } 28 | }, 29 | "node_modules/base64-js": { 30 | "version": "1.5.1", 31 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 32 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 33 | "dev": true, 34 | "funding": [ 35 | { 36 | "type": "github", 37 | "url": "https://github.com/sponsors/feross" 38 | }, 39 | { 40 | "type": "patreon", 41 | "url": "https://www.patreon.com/feross" 42 | }, 43 | { 44 | "type": "consulting", 45 | "url": "https://feross.org/support" 46 | } 47 | ], 48 | "license": "MIT" 49 | }, 50 | "node_modules/bl": { 51 | "version": "4.1.0", 52 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 53 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 54 | "dev": true, 55 | "license": "MIT", 56 | "dependencies": { 57 | "buffer": "^5.5.0", 58 | "inherits": "^2.0.4", 59 | "readable-stream": "^3.4.0" 60 | } 61 | }, 62 | "node_modules/buffer": { 63 | "version": "5.7.1", 64 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 65 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 66 | "dev": true, 67 | "funding": [ 68 | { 69 | "type": "github", 70 | "url": "https://github.com/sponsors/feross" 71 | }, 72 | { 73 | "type": "patreon", 74 | "url": "https://www.patreon.com/feross" 75 | }, 76 | { 77 | "type": "consulting", 78 | "url": "https://feross.org/support" 79 | } 80 | ], 81 | "license": "MIT", 82 | "dependencies": { 83 | "base64-js": "^1.3.1", 84 | "ieee754": "^1.1.13" 85 | } 86 | }, 87 | "node_modules/chownr": { 88 | "version": "1.1.4", 89 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 90 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 91 | "dev": true, 92 | "license": "ISC" 93 | }, 94 | "node_modules/end-of-stream": { 95 | "version": "1.4.4", 96 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 97 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 98 | "dev": true, 99 | "license": "MIT", 100 | "dependencies": { 101 | "once": "^1.4.0" 102 | } 103 | }, 104 | "node_modules/fs-constants": { 105 | "version": "1.0.0", 106 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 107 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 108 | "dev": true, 109 | "license": "MIT" 110 | }, 111 | "node_modules/ieee754": { 112 | "version": "1.2.1", 113 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 114 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 115 | "dev": true, 116 | "funding": [ 117 | { 118 | "type": "github", 119 | "url": "https://github.com/sponsors/feross" 120 | }, 121 | { 122 | "type": "patreon", 123 | "url": "https://www.patreon.com/feross" 124 | }, 125 | { 126 | "type": "consulting", 127 | "url": "https://feross.org/support" 128 | } 129 | ], 130 | "license": "BSD-3-Clause" 131 | }, 132 | "node_modules/inherits": { 133 | "version": "2.0.4", 134 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 135 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 136 | "dev": true, 137 | "license": "ISC" 138 | }, 139 | "node_modules/minimist": { 140 | "version": "1.2.8", 141 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 142 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 143 | "dev": true, 144 | "license": "MIT", 145 | "funding": { 146 | "url": "https://github.com/sponsors/ljharb" 147 | } 148 | }, 149 | "node_modules/mkdirp-classic": { 150 | "version": "0.5.3", 151 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 152 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", 153 | "dev": true, 154 | "license": "MIT" 155 | }, 156 | "node_modules/node-abi": { 157 | "version": "3.67.0", 158 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", 159 | "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", 160 | "dev": true, 161 | "license": "MIT", 162 | "dependencies": { 163 | "semver": "^7.3.5" 164 | }, 165 | "engines": { 166 | "node": ">=10" 167 | } 168 | }, 169 | "node_modules/node-addon-api": { 170 | "version": "8.1.0", 171 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz", 172 | "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==", 173 | "license": "MIT", 174 | "engines": { 175 | "node": "^18 || ^20 || >= 21" 176 | } 177 | }, 178 | "node_modules/node-gyp-build": { 179 | "version": "4.8.2", 180 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", 181 | "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", 182 | "license": "MIT", 183 | "bin": { 184 | "node-gyp-build": "bin.js", 185 | "node-gyp-build-optional": "optional.js", 186 | "node-gyp-build-test": "build-test.js" 187 | } 188 | }, 189 | "node_modules/npm-run-path": { 190 | "version": "3.1.0", 191 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", 192 | "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", 193 | "dev": true, 194 | "license": "MIT", 195 | "dependencies": { 196 | "path-key": "^3.0.0" 197 | }, 198 | "engines": { 199 | "node": ">=8" 200 | } 201 | }, 202 | "node_modules/once": { 203 | "version": "1.4.0", 204 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 205 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 206 | "dev": true, 207 | "license": "ISC", 208 | "dependencies": { 209 | "wrappy": "1" 210 | } 211 | }, 212 | "node_modules/path-key": { 213 | "version": "3.1.1", 214 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 215 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 216 | "dev": true, 217 | "license": "MIT", 218 | "engines": { 219 | "node": ">=8" 220 | } 221 | }, 222 | "node_modules/prebuildify": { 223 | "version": "6.0.1", 224 | "resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz", 225 | "integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==", 226 | "dev": true, 227 | "license": "MIT", 228 | "dependencies": { 229 | "minimist": "^1.2.5", 230 | "mkdirp-classic": "^0.5.3", 231 | "node-abi": "^3.3.0", 232 | "npm-run-path": "^3.1.0", 233 | "pump": "^3.0.0", 234 | "tar-fs": "^2.1.0" 235 | }, 236 | "bin": { 237 | "prebuildify": "bin.js" 238 | } 239 | }, 240 | "node_modules/pump": { 241 | "version": "3.0.0", 242 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 243 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 244 | "dev": true, 245 | "license": "MIT", 246 | "dependencies": { 247 | "end-of-stream": "^1.1.0", 248 | "once": "^1.3.1" 249 | } 250 | }, 251 | "node_modules/readable-stream": { 252 | "version": "3.6.2", 253 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 254 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 255 | "dev": true, 256 | "license": "MIT", 257 | "dependencies": { 258 | "inherits": "^2.0.3", 259 | "string_decoder": "^1.1.1", 260 | "util-deprecate": "^1.0.1" 261 | }, 262 | "engines": { 263 | "node": ">= 6" 264 | } 265 | }, 266 | "node_modules/safe-buffer": { 267 | "version": "5.2.1", 268 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 269 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 270 | "dev": true, 271 | "funding": [ 272 | { 273 | "type": "github", 274 | "url": "https://github.com/sponsors/feross" 275 | }, 276 | { 277 | "type": "patreon", 278 | "url": "https://www.patreon.com/feross" 279 | }, 280 | { 281 | "type": "consulting", 282 | "url": "https://feross.org/support" 283 | } 284 | ], 285 | "license": "MIT" 286 | }, 287 | "node_modules/semver": { 288 | "version": "7.6.3", 289 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 290 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 291 | "dev": true, 292 | "license": "ISC", 293 | "bin": { 294 | "semver": "bin/semver.js" 295 | }, 296 | "engines": { 297 | "node": ">=10" 298 | } 299 | }, 300 | "node_modules/string_decoder": { 301 | "version": "1.3.0", 302 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 303 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 304 | "dev": true, 305 | "license": "MIT", 306 | "dependencies": { 307 | "safe-buffer": "~5.2.0" 308 | } 309 | }, 310 | "node_modules/tar-fs": { 311 | "version": "2.1.1", 312 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 313 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 314 | "dev": true, 315 | "license": "MIT", 316 | "dependencies": { 317 | "chownr": "^1.1.1", 318 | "mkdirp-classic": "^0.5.2", 319 | "pump": "^3.0.0", 320 | "tar-stream": "^2.1.4" 321 | } 322 | }, 323 | "node_modules/tar-stream": { 324 | "version": "2.2.0", 325 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 326 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 327 | "dev": true, 328 | "license": "MIT", 329 | "dependencies": { 330 | "bl": "^4.0.3", 331 | "end-of-stream": "^1.4.1", 332 | "fs-constants": "^1.0.0", 333 | "inherits": "^2.0.3", 334 | "readable-stream": "^3.1.1" 335 | }, 336 | "engines": { 337 | "node": ">=6" 338 | } 339 | }, 340 | "node_modules/tree-sitter": { 341 | "version": "0.21.1", 342 | "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", 343 | "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", 344 | "hasInstallScript": true, 345 | "license": "MIT", 346 | "peer": true, 347 | "dependencies": { 348 | "node-addon-api": "^8.0.0", 349 | "node-gyp-build": "^4.8.0" 350 | } 351 | }, 352 | "node_modules/tree-sitter-cli": { 353 | "version": "0.24.7", 354 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.24.7.tgz", 355 | "integrity": "sha512-o4gnE82pVmMMhJbWwD6+I9yr4lXii5Ci5qEQ2pFpUbVy1YiD8cizTJaqdcznA0qEbo7l2OneI1GocChPrI4YGQ==", 356 | "dev": true, 357 | "hasInstallScript": true, 358 | "license": "MIT", 359 | "bin": { 360 | "tree-sitter": "cli.js" 361 | }, 362 | "engines": { 363 | "node": ">=12.0.0" 364 | } 365 | }, 366 | "node_modules/util-deprecate": { 367 | "version": "1.0.2", 368 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 369 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 370 | "dev": true, 371 | "license": "MIT" 372 | }, 373 | "node_modules/wrappy": { 374 | "version": "1.0.2", 375 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 376 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 377 | "dev": true, 378 | "license": "ISC" 379 | } 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-scheme", 3 | "version": "0.24.7", 4 | "description": "Tree-sitter grammar for Scheme", 5 | "main": "bindings/node", 6 | "types": "bindings/node", 7 | "scripts": { 8 | "install": "node-gyp-build", 9 | "prestart": "tree-sitter build --wasm", 10 | "start": "tree-sitter playground", 11 | "test": "node --test bindings/node/*_test.js" 12 | }, 13 | "author": "6cdh", 14 | "license": "MIT", 15 | "dependencies": { 16 | "node-addon-api": "^8.0.0", 17 | "node-gyp-build": "^4.8.1" 18 | }, 19 | "peerDependencies": { 20 | "tree-sitter": "^0.21.1" 21 | }, 22 | "peerDependenciesMeta": { 23 | "tree_sitter": { 24 | "optional": true 25 | } 26 | }, 27 | "devDependencies": { 28 | "prebuildify": "^6.0.1", 29 | "tree-sitter-cli": "^0.24.7" 30 | }, 31 | "files": [ 32 | "grammar.js", 33 | "binding.gyp", 34 | "prebuilds/**", 35 | "bindings/node/*", 36 | "queries/*", 37 | "src/**", 38 | "*.wasm" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | node-addon-api: 12 | specifier: ^8.0.0 13 | version: 8.1.0 14 | node-gyp-build: 15 | specifier: ^4.8.1 16 | version: 4.8.2 17 | tree-sitter: 18 | specifier: ^0.21.1 19 | version: 0.21.1 20 | devDependencies: 21 | prebuildify: 22 | specifier: ^6.0.1 23 | version: 6.0.1 24 | tree-sitter-cli: 25 | specifier: ^0.24.7 26 | version: 0.24.7 27 | 28 | packages: 29 | 30 | base64-js@1.5.1: 31 | resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 32 | 33 | bl@4.1.0: 34 | resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} 35 | 36 | buffer@5.7.1: 37 | resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} 38 | 39 | chownr@1.1.4: 40 | resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} 41 | 42 | end-of-stream@1.4.4: 43 | resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} 44 | 45 | fs-constants@1.0.0: 46 | resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} 47 | 48 | ieee754@1.2.1: 49 | resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 50 | 51 | inherits@2.0.4: 52 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 53 | 54 | minimist@1.2.8: 55 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 56 | 57 | mkdirp-classic@0.5.3: 58 | resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} 59 | 60 | node-abi@3.67.0: 61 | resolution: {integrity: sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==} 62 | engines: {node: '>=10'} 63 | 64 | node-addon-api@8.1.0: 65 | resolution: {integrity: sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==} 66 | engines: {node: ^18 || ^20 || >= 21} 67 | 68 | node-gyp-build@4.8.2: 69 | resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} 70 | hasBin: true 71 | 72 | npm-run-path@3.1.0: 73 | resolution: {integrity: sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==} 74 | engines: {node: '>=8'} 75 | 76 | once@1.4.0: 77 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 78 | 79 | path-key@3.1.1: 80 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 81 | engines: {node: '>=8'} 82 | 83 | prebuildify@6.0.1: 84 | resolution: {integrity: sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==} 85 | hasBin: true 86 | 87 | pump@3.0.0: 88 | resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} 89 | 90 | readable-stream@3.6.2: 91 | resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 92 | engines: {node: '>= 6'} 93 | 94 | safe-buffer@5.2.1: 95 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 96 | 97 | semver@7.6.3: 98 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} 99 | engines: {node: '>=10'} 100 | hasBin: true 101 | 102 | string_decoder@1.3.0: 103 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 104 | 105 | tar-fs@2.1.1: 106 | resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} 107 | 108 | tar-stream@2.2.0: 109 | resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} 110 | engines: {node: '>=6'} 111 | 112 | tree-sitter-cli@0.24.7: 113 | resolution: {integrity: sha512-o4gnE82pVmMMhJbWwD6+I9yr4lXii5Ci5qEQ2pFpUbVy1YiD8cizTJaqdcznA0qEbo7l2OneI1GocChPrI4YGQ==} 114 | engines: {node: '>=12.0.0'} 115 | hasBin: true 116 | 117 | tree-sitter@0.21.1: 118 | resolution: {integrity: sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==} 119 | 120 | util-deprecate@1.0.2: 121 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 122 | 123 | wrappy@1.0.2: 124 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 125 | 126 | snapshots: 127 | 128 | base64-js@1.5.1: {} 129 | 130 | bl@4.1.0: 131 | dependencies: 132 | buffer: 5.7.1 133 | inherits: 2.0.4 134 | readable-stream: 3.6.2 135 | 136 | buffer@5.7.1: 137 | dependencies: 138 | base64-js: 1.5.1 139 | ieee754: 1.2.1 140 | 141 | chownr@1.1.4: {} 142 | 143 | end-of-stream@1.4.4: 144 | dependencies: 145 | once: 1.4.0 146 | 147 | fs-constants@1.0.0: {} 148 | 149 | ieee754@1.2.1: {} 150 | 151 | inherits@2.0.4: {} 152 | 153 | minimist@1.2.8: {} 154 | 155 | mkdirp-classic@0.5.3: {} 156 | 157 | node-abi@3.67.0: 158 | dependencies: 159 | semver: 7.6.3 160 | 161 | node-addon-api@8.1.0: {} 162 | 163 | node-gyp-build@4.8.2: {} 164 | 165 | npm-run-path@3.1.0: 166 | dependencies: 167 | path-key: 3.1.1 168 | 169 | once@1.4.0: 170 | dependencies: 171 | wrappy: 1.0.2 172 | 173 | path-key@3.1.1: {} 174 | 175 | prebuildify@6.0.1: 176 | dependencies: 177 | minimist: 1.2.8 178 | mkdirp-classic: 0.5.3 179 | node-abi: 3.67.0 180 | npm-run-path: 3.1.0 181 | pump: 3.0.0 182 | tar-fs: 2.1.1 183 | 184 | pump@3.0.0: 185 | dependencies: 186 | end-of-stream: 1.4.4 187 | once: 1.4.0 188 | 189 | readable-stream@3.6.2: 190 | dependencies: 191 | inherits: 2.0.4 192 | string_decoder: 1.3.0 193 | util-deprecate: 1.0.2 194 | 195 | safe-buffer@5.2.1: {} 196 | 197 | semver@7.6.3: {} 198 | 199 | string_decoder@1.3.0: 200 | dependencies: 201 | safe-buffer: 5.2.1 202 | 203 | tar-fs@2.1.1: 204 | dependencies: 205 | chownr: 1.1.4 206 | mkdirp-classic: 0.5.3 207 | pump: 3.0.0 208 | tar-stream: 2.2.0 209 | 210 | tar-stream@2.2.0: 211 | dependencies: 212 | bl: 4.1.0 213 | end-of-stream: 1.4.4 214 | fs-constants: 1.0.0 215 | inherits: 2.0.4 216 | readable-stream: 3.6.2 217 | 218 | tree-sitter-cli@0.24.7: {} 219 | 220 | tree-sitter@0.21.1: 221 | dependencies: 222 | node-addon-api: 8.1.0 223 | node-gyp-build: 4.8.2 224 | 225 | util-deprecate@1.0.2: {} 226 | 227 | wrappy@1.0.2: {} 228 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-scheme" 7 | description = "Scheme grammar for tree-sitter" 8 | version = "0.24.7" 9 | keywords = ["incremental", "parsing", "tree-sitter", "scheme"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "Topic :: Software Development :: Compilers", 13 | "Topic :: Text Processing :: Linguistic", 14 | "Typing :: Typed", 15 | ] 16 | authors = [{ name = "6cdh" }] 17 | requires-python = ">=3.9" 18 | license.text = "MIT" 19 | readme = "README.md" 20 | 21 | [project.urls] 22 | Homepage = "https://github.com/tree-sitter/tree-sitter-scheme" 23 | 24 | [project.optional-dependencies] 25 | core = ["tree-sitter~=0.22"] 26 | 27 | [tool.cibuildwheel] 28 | build = "cp39-*" 29 | build-frontend = "build" 30 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | ["(" ")" "[" "]" "{" "}"] @punctuation.bracket 2 | 3 | (number) @number 4 | (character) @constant.builtin 5 | (boolean) @constant.builtin 6 | (symbol) @variable 7 | 8 | (string) @string 9 | 10 | (escape_sequence) @escape 11 | 12 | (list 13 | . 14 | (symbol) @function) 15 | 16 | (list 17 | . 18 | "[" 19 | . 20 | (symbol)+ @variable 21 | . 22 | "]") 23 | 24 | ((symbol) @operator 25 | (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) 26 | 27 | (list 28 | . 29 | (symbol) @keyword 30 | (#match? @keyword 31 | "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$" 32 | )) 33 | 34 | (list 35 | . 36 | (symbol) @function.builtin 37 | (#match? @function.builtin 38 | "^(caar|cadr|call-with-input-file|call-with-output-file|cdar|cddr|list|open-input-file|open-output-file|with-input-from-file|with-output-to-file|\\*|\\+|-|/|<|<=|=|>|>=|abs|acos|angle|append|apply|asin|assoc|assq|assv|atan|boolean\\?|caaaar|caaadr|caaar|caadar|caaddr|caadr|cadaar|cadadr|cadar|caddar|cadddr|caddr|call-with-current-continuation|call-with-values|car|cdaaar|cdaadr|cdaar|cdadar|cdaddr|cdadr|cddaar|cddadr|cddar|cdddar|cddddr|cdddr|cdr|ceiling|char->integer|char-alphabetic\\?|char-ci<=\\?|char-ci<\\?|char-ci=\\?|char-ci>=\\?|char-ci>\\?|char-downcase|char-lower-case\\?|char-numeric\\?|char-ready\\?|char-upcase|char-upper-case\\?|char-whitespace\\?|char<=\\?|char<\\?|char=\\?|char>=\\?|char>\\?|char\\?|close-input-port|close-output-port|complex\\?|cons|cos|current-error-port|current-input-port|current-output-port|denominator|display|dynamic-wind|eof-object\\?|eq\\?|equal\\?|eqv\\?|eval|even\\?|exact->inexact|exact\\?|exp|expt|floor|flush-output|for-each|force|gcd|imag-part|inexact->exact|inexact\\?|input-port\\?|integer->char|integer\\?|interaction-environment|lcm|length|list->string|list->vector|list-ref|list-tail|list\\?|load|log|magnitude|make-polar|make-rectangular|make-string|make-vector|map|max|member|memq|memv|min|modulo|negative\\?|newline|not|null-environment|null\\?|number->string|number\\?|numerator|odd\\?|output-port\\?|pair\\?|peek-char|positive\\?|procedure\\?|quotient|rational\\?|rationalize|read|read-char|real-part|real\\?|remainder|reverse|round|scheme-report-environment|set-car!|set-cdr!|sin|sqrt|string|string->list|string->number|string->symbol|string-append|string-ci<=\\?|string-ci<\\?|string-ci=\\?|string-ci>=\\?|string-ci>\\?|string-copy|string-fill!|string-length|string-ref|string-set!|string<=\\?|string<\\?|string=\\?|string>=\\?|string>\\?|string\\?|substring|symbol->string|symbol\\?|tan|transcript-off|transcript-on|truncate|values|vector|vector->list|vector-fill!|vector-length|vector-ref|vector-set!|vector\\?|write|write-char|zero\\?)$" 39 | )) 40 | 41 | ;; quote ;; 42 | 43 | ;; hardcoded highlight four levels of nested structure 44 | 45 | ; 'atom 46 | (quote 47 | _ @constant) 48 | 49 | ; '() 50 | (quote 51 | (_ _* @constant)) 52 | 53 | ; '(()) 54 | (quote 55 | (_ (_ _* @constant))) 56 | 57 | ; '((())) 58 | (quote 59 | (_ (_ (_ _* @constant)))) 60 | 61 | ;; sexp comment ;; 62 | 63 | ;; hardcoded highlight four levels of nested structure 64 | 65 | ; #;atom 66 | (comment 67 | _ @comment) 68 | 69 | ; #;(list) 70 | (comment 71 | (_ _* @comment)) 72 | 73 | ; #;(list (list)) 74 | (comment 75 | (_ (_ _* @comment))) 76 | 77 | ; #;(list (list (list))) 78 | (comment 79 | (_ (_ (_ _ @comment)))) 80 | 81 | [(comment) 82 | (block_comment) 83 | (directive)] @comment 84 | 85 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os.path import isdir, join 2 | from platform import system 3 | 4 | from setuptools import Extension, find_packages, setup 5 | from setuptools.command.build import build 6 | from wheel.bdist_wheel import bdist_wheel 7 | 8 | 9 | class Build(build): 10 | def run(self): 11 | if isdir("queries"): 12 | dest = join(self.build_lib, "tree_sitter_scheme", "queries") 13 | self.copy_tree("queries", dest) 14 | super().run() 15 | 16 | 17 | class BdistWheel(bdist_wheel): 18 | def get_tag(self): 19 | python, abi, platform = super().get_tag() 20 | if python.startswith("cp"): 21 | python, abi = "cp39", "abi3" 22 | return python, abi, platform 23 | 24 | 25 | setup( 26 | packages=find_packages("bindings/python"), 27 | package_dir={"": "bindings/python"}, 28 | package_data={ 29 | "tree_sitter_scheme": ["*.pyi", "py.typed"], 30 | "tree_sitter_scheme.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_scheme", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_scheme/binding.c", 38 | "src/parser.c", 39 | # NOTE: if your language uses an external scanner, add it here. 40 | ], 41 | extra_compile_args=[ 42 | "-std=c11", 43 | "-fvisibility=hidden", 44 | ] if system() != "Windows" else [ 45 | "/std:c11", 46 | "/utf-8", 47 | ], 48 | define_macros=[ 49 | ("Py_LIMITED_API", "0x03090000"), 50 | ("PY_SSIZE_T_CLEAN", None), 51 | ("TREE_SITTER_HIDE_SYMBOLS", None), 52 | ], 53 | include_dirs=["src"], 54 | py_limited_api=True, 55 | ) 56 | ], 57 | cmdclass={ 58 | "build": Build, 59 | "bdist_wheel": BdistWheel 60 | }, 61 | zip_safe=False 62 | ) 63 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { } }: 2 | pkgs.mkShell { 3 | nativeBuildInputs = with pkgs; [ 4 | nodejs 5 | gcc 6 | ]; 7 | shellHook = '' 8 | PATH=./node_modules/.bin:$PATH 9 | ''; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "block_comment", 4 | "named": true, 5 | "fields": {}, 6 | "children": { 7 | "multiple": true, 8 | "required": false, 9 | "types": [ 10 | { 11 | "type": "block_comment", 12 | "named": true 13 | } 14 | ] 15 | } 16 | }, 17 | { 18 | "type": "byte_vector", 19 | "named": true, 20 | "fields": {}, 21 | "children": { 22 | "multiple": true, 23 | "required": false, 24 | "types": [ 25 | { 26 | "type": "block_comment", 27 | "named": true 28 | }, 29 | { 30 | "type": "boolean", 31 | "named": true 32 | }, 33 | { 34 | "type": "byte_vector", 35 | "named": true 36 | }, 37 | { 38 | "type": "character", 39 | "named": true 40 | }, 41 | { 42 | "type": "comment", 43 | "named": true 44 | }, 45 | { 46 | "type": "directive", 47 | "named": true 48 | }, 49 | { 50 | "type": "keyword", 51 | "named": true 52 | }, 53 | { 54 | "type": "list", 55 | "named": true 56 | }, 57 | { 58 | "type": "number", 59 | "named": true 60 | }, 61 | { 62 | "type": "quasiquote", 63 | "named": true 64 | }, 65 | { 66 | "type": "quasisyntax", 67 | "named": true 68 | }, 69 | { 70 | "type": "quote", 71 | "named": true 72 | }, 73 | { 74 | "type": "string", 75 | "named": true 76 | }, 77 | { 78 | "type": "symbol", 79 | "named": true 80 | }, 81 | { 82 | "type": "syntax", 83 | "named": true 84 | }, 85 | { 86 | "type": "unquote", 87 | "named": true 88 | }, 89 | { 90 | "type": "unquote_splicing", 91 | "named": true 92 | }, 93 | { 94 | "type": "unsyntax", 95 | "named": true 96 | }, 97 | { 98 | "type": "unsyntax_splicing", 99 | "named": true 100 | }, 101 | { 102 | "type": "vector", 103 | "named": true 104 | } 105 | ] 106 | } 107 | }, 108 | { 109 | "type": "comment", 110 | "named": true, 111 | "fields": {}, 112 | "children": { 113 | "multiple": true, 114 | "required": false, 115 | "types": [ 116 | { 117 | "type": "block_comment", 118 | "named": true 119 | }, 120 | { 121 | "type": "boolean", 122 | "named": true 123 | }, 124 | { 125 | "type": "byte_vector", 126 | "named": true 127 | }, 128 | { 129 | "type": "character", 130 | "named": true 131 | }, 132 | { 133 | "type": "comment", 134 | "named": true 135 | }, 136 | { 137 | "type": "directive", 138 | "named": true 139 | }, 140 | { 141 | "type": "keyword", 142 | "named": true 143 | }, 144 | { 145 | "type": "list", 146 | "named": true 147 | }, 148 | { 149 | "type": "number", 150 | "named": true 151 | }, 152 | { 153 | "type": "quasiquote", 154 | "named": true 155 | }, 156 | { 157 | "type": "quasisyntax", 158 | "named": true 159 | }, 160 | { 161 | "type": "quote", 162 | "named": true 163 | }, 164 | { 165 | "type": "string", 166 | "named": true 167 | }, 168 | { 169 | "type": "symbol", 170 | "named": true 171 | }, 172 | { 173 | "type": "syntax", 174 | "named": true 175 | }, 176 | { 177 | "type": "unquote", 178 | "named": true 179 | }, 180 | { 181 | "type": "unquote_splicing", 182 | "named": true 183 | }, 184 | { 185 | "type": "unsyntax", 186 | "named": true 187 | }, 188 | { 189 | "type": "unsyntax_splicing", 190 | "named": true 191 | }, 192 | { 193 | "type": "vector", 194 | "named": true 195 | } 196 | ] 197 | } 198 | }, 199 | { 200 | "type": "directive", 201 | "named": true, 202 | "fields": {}, 203 | "children": { 204 | "multiple": true, 205 | "required": false, 206 | "types": [ 207 | { 208 | "type": "block_comment", 209 | "named": true 210 | }, 211 | { 212 | "type": "comment", 213 | "named": true 214 | }, 215 | { 216 | "type": "directive", 217 | "named": true 218 | } 219 | ] 220 | } 221 | }, 222 | { 223 | "type": "list", 224 | "named": true, 225 | "fields": {}, 226 | "children": { 227 | "multiple": true, 228 | "required": false, 229 | "types": [ 230 | { 231 | "type": "block_comment", 232 | "named": true 233 | }, 234 | { 235 | "type": "boolean", 236 | "named": true 237 | }, 238 | { 239 | "type": "byte_vector", 240 | "named": true 241 | }, 242 | { 243 | "type": "character", 244 | "named": true 245 | }, 246 | { 247 | "type": "comment", 248 | "named": true 249 | }, 250 | { 251 | "type": "directive", 252 | "named": true 253 | }, 254 | { 255 | "type": "keyword", 256 | "named": true 257 | }, 258 | { 259 | "type": "list", 260 | "named": true 261 | }, 262 | { 263 | "type": "number", 264 | "named": true 265 | }, 266 | { 267 | "type": "quasiquote", 268 | "named": true 269 | }, 270 | { 271 | "type": "quasisyntax", 272 | "named": true 273 | }, 274 | { 275 | "type": "quote", 276 | "named": true 277 | }, 278 | { 279 | "type": "string", 280 | "named": true 281 | }, 282 | { 283 | "type": "symbol", 284 | "named": true 285 | }, 286 | { 287 | "type": "syntax", 288 | "named": true 289 | }, 290 | { 291 | "type": "unquote", 292 | "named": true 293 | }, 294 | { 295 | "type": "unquote_splicing", 296 | "named": true 297 | }, 298 | { 299 | "type": "unsyntax", 300 | "named": true 301 | }, 302 | { 303 | "type": "unsyntax_splicing", 304 | "named": true 305 | }, 306 | { 307 | "type": "vector", 308 | "named": true 309 | } 310 | ] 311 | } 312 | }, 313 | { 314 | "type": "program", 315 | "named": true, 316 | "root": true, 317 | "fields": {}, 318 | "children": { 319 | "multiple": true, 320 | "required": false, 321 | "types": [ 322 | { 323 | "type": "block_comment", 324 | "named": true 325 | }, 326 | { 327 | "type": "boolean", 328 | "named": true 329 | }, 330 | { 331 | "type": "byte_vector", 332 | "named": true 333 | }, 334 | { 335 | "type": "character", 336 | "named": true 337 | }, 338 | { 339 | "type": "comment", 340 | "named": true 341 | }, 342 | { 343 | "type": "directive", 344 | "named": true 345 | }, 346 | { 347 | "type": "keyword", 348 | "named": true 349 | }, 350 | { 351 | "type": "list", 352 | "named": true 353 | }, 354 | { 355 | "type": "number", 356 | "named": true 357 | }, 358 | { 359 | "type": "quasiquote", 360 | "named": true 361 | }, 362 | { 363 | "type": "quasisyntax", 364 | "named": true 365 | }, 366 | { 367 | "type": "quote", 368 | "named": true 369 | }, 370 | { 371 | "type": "string", 372 | "named": true 373 | }, 374 | { 375 | "type": "symbol", 376 | "named": true 377 | }, 378 | { 379 | "type": "syntax", 380 | "named": true 381 | }, 382 | { 383 | "type": "unquote", 384 | "named": true 385 | }, 386 | { 387 | "type": "unquote_splicing", 388 | "named": true 389 | }, 390 | { 391 | "type": "unsyntax", 392 | "named": true 393 | }, 394 | { 395 | "type": "unsyntax_splicing", 396 | "named": true 397 | }, 398 | { 399 | "type": "vector", 400 | "named": true 401 | } 402 | ] 403 | } 404 | }, 405 | { 406 | "type": "quasiquote", 407 | "named": true, 408 | "fields": {}, 409 | "children": { 410 | "multiple": true, 411 | "required": true, 412 | "types": [ 413 | { 414 | "type": "block_comment", 415 | "named": true 416 | }, 417 | { 418 | "type": "boolean", 419 | "named": true 420 | }, 421 | { 422 | "type": "byte_vector", 423 | "named": true 424 | }, 425 | { 426 | "type": "character", 427 | "named": true 428 | }, 429 | { 430 | "type": "comment", 431 | "named": true 432 | }, 433 | { 434 | "type": "directive", 435 | "named": true 436 | }, 437 | { 438 | "type": "keyword", 439 | "named": true 440 | }, 441 | { 442 | "type": "list", 443 | "named": true 444 | }, 445 | { 446 | "type": "number", 447 | "named": true 448 | }, 449 | { 450 | "type": "quasiquote", 451 | "named": true 452 | }, 453 | { 454 | "type": "quasisyntax", 455 | "named": true 456 | }, 457 | { 458 | "type": "quote", 459 | "named": true 460 | }, 461 | { 462 | "type": "string", 463 | "named": true 464 | }, 465 | { 466 | "type": "symbol", 467 | "named": true 468 | }, 469 | { 470 | "type": "syntax", 471 | "named": true 472 | }, 473 | { 474 | "type": "unquote", 475 | "named": true 476 | }, 477 | { 478 | "type": "unquote_splicing", 479 | "named": true 480 | }, 481 | { 482 | "type": "unsyntax", 483 | "named": true 484 | }, 485 | { 486 | "type": "unsyntax_splicing", 487 | "named": true 488 | }, 489 | { 490 | "type": "vector", 491 | "named": true 492 | } 493 | ] 494 | } 495 | }, 496 | { 497 | "type": "quasisyntax", 498 | "named": true, 499 | "fields": {}, 500 | "children": { 501 | "multiple": true, 502 | "required": true, 503 | "types": [ 504 | { 505 | "type": "block_comment", 506 | "named": true 507 | }, 508 | { 509 | "type": "boolean", 510 | "named": true 511 | }, 512 | { 513 | "type": "byte_vector", 514 | "named": true 515 | }, 516 | { 517 | "type": "character", 518 | "named": true 519 | }, 520 | { 521 | "type": "comment", 522 | "named": true 523 | }, 524 | { 525 | "type": "directive", 526 | "named": true 527 | }, 528 | { 529 | "type": "keyword", 530 | "named": true 531 | }, 532 | { 533 | "type": "list", 534 | "named": true 535 | }, 536 | { 537 | "type": "number", 538 | "named": true 539 | }, 540 | { 541 | "type": "quasiquote", 542 | "named": true 543 | }, 544 | { 545 | "type": "quasisyntax", 546 | "named": true 547 | }, 548 | { 549 | "type": "quote", 550 | "named": true 551 | }, 552 | { 553 | "type": "string", 554 | "named": true 555 | }, 556 | { 557 | "type": "symbol", 558 | "named": true 559 | }, 560 | { 561 | "type": "syntax", 562 | "named": true 563 | }, 564 | { 565 | "type": "unquote", 566 | "named": true 567 | }, 568 | { 569 | "type": "unquote_splicing", 570 | "named": true 571 | }, 572 | { 573 | "type": "unsyntax", 574 | "named": true 575 | }, 576 | { 577 | "type": "unsyntax_splicing", 578 | "named": true 579 | }, 580 | { 581 | "type": "vector", 582 | "named": true 583 | } 584 | ] 585 | } 586 | }, 587 | { 588 | "type": "quote", 589 | "named": true, 590 | "fields": {}, 591 | "children": { 592 | "multiple": true, 593 | "required": true, 594 | "types": [ 595 | { 596 | "type": "block_comment", 597 | "named": true 598 | }, 599 | { 600 | "type": "boolean", 601 | "named": true 602 | }, 603 | { 604 | "type": "byte_vector", 605 | "named": true 606 | }, 607 | { 608 | "type": "character", 609 | "named": true 610 | }, 611 | { 612 | "type": "comment", 613 | "named": true 614 | }, 615 | { 616 | "type": "directive", 617 | "named": true 618 | }, 619 | { 620 | "type": "keyword", 621 | "named": true 622 | }, 623 | { 624 | "type": "list", 625 | "named": true 626 | }, 627 | { 628 | "type": "number", 629 | "named": true 630 | }, 631 | { 632 | "type": "quasiquote", 633 | "named": true 634 | }, 635 | { 636 | "type": "quasisyntax", 637 | "named": true 638 | }, 639 | { 640 | "type": "quote", 641 | "named": true 642 | }, 643 | { 644 | "type": "string", 645 | "named": true 646 | }, 647 | { 648 | "type": "symbol", 649 | "named": true 650 | }, 651 | { 652 | "type": "syntax", 653 | "named": true 654 | }, 655 | { 656 | "type": "unquote", 657 | "named": true 658 | }, 659 | { 660 | "type": "unquote_splicing", 661 | "named": true 662 | }, 663 | { 664 | "type": "unsyntax", 665 | "named": true 666 | }, 667 | { 668 | "type": "unsyntax_splicing", 669 | "named": true 670 | }, 671 | { 672 | "type": "vector", 673 | "named": true 674 | } 675 | ] 676 | } 677 | }, 678 | { 679 | "type": "string", 680 | "named": true, 681 | "fields": {}, 682 | "children": { 683 | "multiple": true, 684 | "required": false, 685 | "types": [ 686 | { 687 | "type": "escape_sequence", 688 | "named": true 689 | } 690 | ] 691 | } 692 | }, 693 | { 694 | "type": "syntax", 695 | "named": true, 696 | "fields": {}, 697 | "children": { 698 | "multiple": true, 699 | "required": true, 700 | "types": [ 701 | { 702 | "type": "block_comment", 703 | "named": true 704 | }, 705 | { 706 | "type": "boolean", 707 | "named": true 708 | }, 709 | { 710 | "type": "byte_vector", 711 | "named": true 712 | }, 713 | { 714 | "type": "character", 715 | "named": true 716 | }, 717 | { 718 | "type": "comment", 719 | "named": true 720 | }, 721 | { 722 | "type": "directive", 723 | "named": true 724 | }, 725 | { 726 | "type": "keyword", 727 | "named": true 728 | }, 729 | { 730 | "type": "list", 731 | "named": true 732 | }, 733 | { 734 | "type": "number", 735 | "named": true 736 | }, 737 | { 738 | "type": "quasiquote", 739 | "named": true 740 | }, 741 | { 742 | "type": "quasisyntax", 743 | "named": true 744 | }, 745 | { 746 | "type": "quote", 747 | "named": true 748 | }, 749 | { 750 | "type": "string", 751 | "named": true 752 | }, 753 | { 754 | "type": "symbol", 755 | "named": true 756 | }, 757 | { 758 | "type": "syntax", 759 | "named": true 760 | }, 761 | { 762 | "type": "unquote", 763 | "named": true 764 | }, 765 | { 766 | "type": "unquote_splicing", 767 | "named": true 768 | }, 769 | { 770 | "type": "unsyntax", 771 | "named": true 772 | }, 773 | { 774 | "type": "unsyntax_splicing", 775 | "named": true 776 | }, 777 | { 778 | "type": "vector", 779 | "named": true 780 | } 781 | ] 782 | } 783 | }, 784 | { 785 | "type": "unquote", 786 | "named": true, 787 | "fields": {}, 788 | "children": { 789 | "multiple": true, 790 | "required": true, 791 | "types": [ 792 | { 793 | "type": "block_comment", 794 | "named": true 795 | }, 796 | { 797 | "type": "boolean", 798 | "named": true 799 | }, 800 | { 801 | "type": "byte_vector", 802 | "named": true 803 | }, 804 | { 805 | "type": "character", 806 | "named": true 807 | }, 808 | { 809 | "type": "comment", 810 | "named": true 811 | }, 812 | { 813 | "type": "directive", 814 | "named": true 815 | }, 816 | { 817 | "type": "keyword", 818 | "named": true 819 | }, 820 | { 821 | "type": "list", 822 | "named": true 823 | }, 824 | { 825 | "type": "number", 826 | "named": true 827 | }, 828 | { 829 | "type": "quasiquote", 830 | "named": true 831 | }, 832 | { 833 | "type": "quasisyntax", 834 | "named": true 835 | }, 836 | { 837 | "type": "quote", 838 | "named": true 839 | }, 840 | { 841 | "type": "string", 842 | "named": true 843 | }, 844 | { 845 | "type": "symbol", 846 | "named": true 847 | }, 848 | { 849 | "type": "syntax", 850 | "named": true 851 | }, 852 | { 853 | "type": "unquote", 854 | "named": true 855 | }, 856 | { 857 | "type": "unquote_splicing", 858 | "named": true 859 | }, 860 | { 861 | "type": "unsyntax", 862 | "named": true 863 | }, 864 | { 865 | "type": "unsyntax_splicing", 866 | "named": true 867 | }, 868 | { 869 | "type": "vector", 870 | "named": true 871 | } 872 | ] 873 | } 874 | }, 875 | { 876 | "type": "unquote_splicing", 877 | "named": true, 878 | "fields": {}, 879 | "children": { 880 | "multiple": true, 881 | "required": true, 882 | "types": [ 883 | { 884 | "type": "block_comment", 885 | "named": true 886 | }, 887 | { 888 | "type": "boolean", 889 | "named": true 890 | }, 891 | { 892 | "type": "byte_vector", 893 | "named": true 894 | }, 895 | { 896 | "type": "character", 897 | "named": true 898 | }, 899 | { 900 | "type": "comment", 901 | "named": true 902 | }, 903 | { 904 | "type": "directive", 905 | "named": true 906 | }, 907 | { 908 | "type": "keyword", 909 | "named": true 910 | }, 911 | { 912 | "type": "list", 913 | "named": true 914 | }, 915 | { 916 | "type": "number", 917 | "named": true 918 | }, 919 | { 920 | "type": "quasiquote", 921 | "named": true 922 | }, 923 | { 924 | "type": "quasisyntax", 925 | "named": true 926 | }, 927 | { 928 | "type": "quote", 929 | "named": true 930 | }, 931 | { 932 | "type": "string", 933 | "named": true 934 | }, 935 | { 936 | "type": "symbol", 937 | "named": true 938 | }, 939 | { 940 | "type": "syntax", 941 | "named": true 942 | }, 943 | { 944 | "type": "unquote", 945 | "named": true 946 | }, 947 | { 948 | "type": "unquote_splicing", 949 | "named": true 950 | }, 951 | { 952 | "type": "unsyntax", 953 | "named": true 954 | }, 955 | { 956 | "type": "unsyntax_splicing", 957 | "named": true 958 | }, 959 | { 960 | "type": "vector", 961 | "named": true 962 | } 963 | ] 964 | } 965 | }, 966 | { 967 | "type": "unsyntax", 968 | "named": true, 969 | "fields": {}, 970 | "children": { 971 | "multiple": true, 972 | "required": true, 973 | "types": [ 974 | { 975 | "type": "block_comment", 976 | "named": true 977 | }, 978 | { 979 | "type": "boolean", 980 | "named": true 981 | }, 982 | { 983 | "type": "byte_vector", 984 | "named": true 985 | }, 986 | { 987 | "type": "character", 988 | "named": true 989 | }, 990 | { 991 | "type": "comment", 992 | "named": true 993 | }, 994 | { 995 | "type": "directive", 996 | "named": true 997 | }, 998 | { 999 | "type": "keyword", 1000 | "named": true 1001 | }, 1002 | { 1003 | "type": "list", 1004 | "named": true 1005 | }, 1006 | { 1007 | "type": "number", 1008 | "named": true 1009 | }, 1010 | { 1011 | "type": "quasiquote", 1012 | "named": true 1013 | }, 1014 | { 1015 | "type": "quasisyntax", 1016 | "named": true 1017 | }, 1018 | { 1019 | "type": "quote", 1020 | "named": true 1021 | }, 1022 | { 1023 | "type": "string", 1024 | "named": true 1025 | }, 1026 | { 1027 | "type": "symbol", 1028 | "named": true 1029 | }, 1030 | { 1031 | "type": "syntax", 1032 | "named": true 1033 | }, 1034 | { 1035 | "type": "unquote", 1036 | "named": true 1037 | }, 1038 | { 1039 | "type": "unquote_splicing", 1040 | "named": true 1041 | }, 1042 | { 1043 | "type": "unsyntax", 1044 | "named": true 1045 | }, 1046 | { 1047 | "type": "unsyntax_splicing", 1048 | "named": true 1049 | }, 1050 | { 1051 | "type": "vector", 1052 | "named": true 1053 | } 1054 | ] 1055 | } 1056 | }, 1057 | { 1058 | "type": "unsyntax_splicing", 1059 | "named": true, 1060 | "fields": {}, 1061 | "children": { 1062 | "multiple": true, 1063 | "required": true, 1064 | "types": [ 1065 | { 1066 | "type": "block_comment", 1067 | "named": true 1068 | }, 1069 | { 1070 | "type": "boolean", 1071 | "named": true 1072 | }, 1073 | { 1074 | "type": "byte_vector", 1075 | "named": true 1076 | }, 1077 | { 1078 | "type": "character", 1079 | "named": true 1080 | }, 1081 | { 1082 | "type": "comment", 1083 | "named": true 1084 | }, 1085 | { 1086 | "type": "directive", 1087 | "named": true 1088 | }, 1089 | { 1090 | "type": "keyword", 1091 | "named": true 1092 | }, 1093 | { 1094 | "type": "list", 1095 | "named": true 1096 | }, 1097 | { 1098 | "type": "number", 1099 | "named": true 1100 | }, 1101 | { 1102 | "type": "quasiquote", 1103 | "named": true 1104 | }, 1105 | { 1106 | "type": "quasisyntax", 1107 | "named": true 1108 | }, 1109 | { 1110 | "type": "quote", 1111 | "named": true 1112 | }, 1113 | { 1114 | "type": "string", 1115 | "named": true 1116 | }, 1117 | { 1118 | "type": "symbol", 1119 | "named": true 1120 | }, 1121 | { 1122 | "type": "syntax", 1123 | "named": true 1124 | }, 1125 | { 1126 | "type": "unquote", 1127 | "named": true 1128 | }, 1129 | { 1130 | "type": "unquote_splicing", 1131 | "named": true 1132 | }, 1133 | { 1134 | "type": "unsyntax", 1135 | "named": true 1136 | }, 1137 | { 1138 | "type": "unsyntax_splicing", 1139 | "named": true 1140 | }, 1141 | { 1142 | "type": "vector", 1143 | "named": true 1144 | } 1145 | ] 1146 | } 1147 | }, 1148 | { 1149 | "type": "vector", 1150 | "named": true, 1151 | "fields": {}, 1152 | "children": { 1153 | "multiple": true, 1154 | "required": false, 1155 | "types": [ 1156 | { 1157 | "type": "block_comment", 1158 | "named": true 1159 | }, 1160 | { 1161 | "type": "boolean", 1162 | "named": true 1163 | }, 1164 | { 1165 | "type": "byte_vector", 1166 | "named": true 1167 | }, 1168 | { 1169 | "type": "character", 1170 | "named": true 1171 | }, 1172 | { 1173 | "type": "comment", 1174 | "named": true 1175 | }, 1176 | { 1177 | "type": "directive", 1178 | "named": true 1179 | }, 1180 | { 1181 | "type": "keyword", 1182 | "named": true 1183 | }, 1184 | { 1185 | "type": "list", 1186 | "named": true 1187 | }, 1188 | { 1189 | "type": "number", 1190 | "named": true 1191 | }, 1192 | { 1193 | "type": "quasiquote", 1194 | "named": true 1195 | }, 1196 | { 1197 | "type": "quasisyntax", 1198 | "named": true 1199 | }, 1200 | { 1201 | "type": "quote", 1202 | "named": true 1203 | }, 1204 | { 1205 | "type": "string", 1206 | "named": true 1207 | }, 1208 | { 1209 | "type": "symbol", 1210 | "named": true 1211 | }, 1212 | { 1213 | "type": "syntax", 1214 | "named": true 1215 | }, 1216 | { 1217 | "type": "unquote", 1218 | "named": true 1219 | }, 1220 | { 1221 | "type": "unquote_splicing", 1222 | "named": true 1223 | }, 1224 | { 1225 | "type": "unsyntax", 1226 | "named": true 1227 | }, 1228 | { 1229 | "type": "unsyntax_splicing", 1230 | "named": true 1231 | }, 1232 | { 1233 | "type": "vector", 1234 | "named": true 1235 | } 1236 | ] 1237 | } 1238 | }, 1239 | { 1240 | "type": "\"", 1241 | "named": false 1242 | }, 1243 | { 1244 | "type": "#!", 1245 | "named": false 1246 | }, 1247 | { 1248 | "type": "#'", 1249 | "named": false 1250 | }, 1251 | { 1252 | "type": "#(", 1253 | "named": false 1254 | }, 1255 | { 1256 | "type": "#,", 1257 | "named": false 1258 | }, 1259 | { 1260 | "type": "#,@", 1261 | "named": false 1262 | }, 1263 | { 1264 | "type": "#;", 1265 | "named": false 1266 | }, 1267 | { 1268 | "type": "#`", 1269 | "named": false 1270 | }, 1271 | { 1272 | "type": "#vu8(", 1273 | "named": false 1274 | }, 1275 | { 1276 | "type": "#|", 1277 | "named": false 1278 | }, 1279 | { 1280 | "type": "'", 1281 | "named": false 1282 | }, 1283 | { 1284 | "type": "(", 1285 | "named": false 1286 | }, 1287 | { 1288 | "type": ")", 1289 | "named": false 1290 | }, 1291 | { 1292 | "type": ",", 1293 | "named": false 1294 | }, 1295 | { 1296 | "type": ",@", 1297 | "named": false 1298 | }, 1299 | { 1300 | "type": "[", 1301 | "named": false 1302 | }, 1303 | { 1304 | "type": "]", 1305 | "named": false 1306 | }, 1307 | { 1308 | "type": "`", 1309 | "named": false 1310 | }, 1311 | { 1312 | "type": "boolean", 1313 | "named": true 1314 | }, 1315 | { 1316 | "type": "character", 1317 | "named": true 1318 | }, 1319 | { 1320 | "type": "escape_sequence", 1321 | "named": true 1322 | }, 1323 | { 1324 | "type": "keyword", 1325 | "named": true 1326 | }, 1327 | { 1328 | "type": "number", 1329 | "named": true 1330 | }, 1331 | { 1332 | "type": "symbol", 1333 | "named": true 1334 | }, 1335 | { 1336 | "type": "{", 1337 | "named": false 1338 | }, 1339 | { 1340 | "type": "|#", 1341 | "named": false 1342 | }, 1343 | { 1344 | "type": "}", 1345 | "named": false 1346 | } 1347 | ] -------------------------------------------------------------------------------- /src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | void (*log)(const TSLexer *, const char *, ...); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef union { 61 | struct { 62 | uint8_t type; 63 | TSStateId state; 64 | bool extra; 65 | bool repetition; 66 | } shift; 67 | struct { 68 | uint8_t type; 69 | uint8_t child_count; 70 | TSSymbol symbol; 71 | int16_t dynamic_precedence; 72 | uint16_t production_id; 73 | } reduce; 74 | uint8_t type; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | typedef struct { 91 | int32_t start; 92 | int32_t end; 93 | } TSCharacterRange; 94 | 95 | struct TSLanguage { 96 | uint32_t version; 97 | uint32_t symbol_count; 98 | uint32_t alias_count; 99 | uint32_t token_count; 100 | uint32_t external_token_count; 101 | uint32_t state_count; 102 | uint32_t large_state_count; 103 | uint32_t production_id_count; 104 | uint32_t field_count; 105 | uint16_t max_alias_sequence_length; 106 | const uint16_t *parse_table; 107 | const uint16_t *small_parse_table; 108 | const uint32_t *small_parse_table_map; 109 | const TSParseActionEntry *parse_actions; 110 | const char * const *symbol_names; 111 | const char * const *field_names; 112 | const TSFieldMapSlice *field_map_slices; 113 | const TSFieldMapEntry *field_map_entries; 114 | const TSSymbolMetadata *symbol_metadata; 115 | const TSSymbol *public_symbol_map; 116 | const uint16_t *alias_map; 117 | const TSSymbol *alias_sequences; 118 | const TSLexMode *lex_modes; 119 | bool (*lex_fn)(TSLexer *, TSStateId); 120 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 121 | TSSymbol keyword_capture_token; 122 | struct { 123 | const bool *states; 124 | const TSSymbol *symbol_map; 125 | void *(*create)(void); 126 | void (*destroy)(void *); 127 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 128 | unsigned (*serialize)(void *, char *); 129 | void (*deserialize)(void *, const char *, unsigned); 130 | } external_scanner; 131 | const TSStateId *primary_state_ids; 132 | }; 133 | 134 | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 135 | uint32_t index = 0; 136 | uint32_t size = len - index; 137 | while (size > 1) { 138 | uint32_t half_size = size / 2; 139 | uint32_t mid_index = index + half_size; 140 | TSCharacterRange *range = &ranges[mid_index]; 141 | if (lookahead >= range->start && lookahead <= range->end) { 142 | return true; 143 | } else if (lookahead > range->end) { 144 | index = mid_index; 145 | } 146 | size -= half_size; 147 | } 148 | TSCharacterRange *range = &ranges[index]; 149 | return (lookahead >= range->start && lookahead <= range->end); 150 | } 151 | 152 | /* 153 | * Lexer Macros 154 | */ 155 | 156 | #ifdef _MSC_VER 157 | #define UNUSED __pragma(warning(suppress : 4101)) 158 | #else 159 | #define UNUSED __attribute__((unused)) 160 | #endif 161 | 162 | #define START_LEXER() \ 163 | bool result = false; \ 164 | bool skip = false; \ 165 | UNUSED \ 166 | bool eof = false; \ 167 | int32_t lookahead; \ 168 | goto start; \ 169 | next_state: \ 170 | lexer->advance(lexer, skip); \ 171 | start: \ 172 | skip = false; \ 173 | lookahead = lexer->lookahead; 174 | 175 | #define ADVANCE(state_value) \ 176 | { \ 177 | state = state_value; \ 178 | goto next_state; \ 179 | } 180 | 181 | #define ADVANCE_MAP(...) \ 182 | { \ 183 | static const uint16_t map[] = { __VA_ARGS__ }; \ 184 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 185 | if (map[i] == lookahead) { \ 186 | state = map[i + 1]; \ 187 | goto next_state; \ 188 | } \ 189 | } \ 190 | } 191 | 192 | #define SKIP(state_value) \ 193 | { \ 194 | skip = true; \ 195 | state = state_value; \ 196 | goto next_state; \ 197 | } 198 | 199 | #define ACCEPT_TOKEN(symbol_value) \ 200 | result = true; \ 201 | lexer->result_symbol = symbol_value; \ 202 | lexer->mark_end(lexer); 203 | 204 | #define END_STATE() return result; 205 | 206 | /* 207 | * Parse Table Macros 208 | */ 209 | 210 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 211 | 212 | #define STATE(id) id 213 | 214 | #define ACTIONS(id) id 215 | 216 | #define SHIFT(state_value) \ 217 | {{ \ 218 | .shift = { \ 219 | .type = TSParseActionTypeShift, \ 220 | .state = (state_value) \ 221 | } \ 222 | }} 223 | 224 | #define SHIFT_REPEAT(state_value) \ 225 | {{ \ 226 | .shift = { \ 227 | .type = TSParseActionTypeShift, \ 228 | .state = (state_value), \ 229 | .repetition = true \ 230 | } \ 231 | }} 232 | 233 | #define SHIFT_EXTRA() \ 234 | {{ \ 235 | .shift = { \ 236 | .type = TSParseActionTypeShift, \ 237 | .extra = true \ 238 | } \ 239 | }} 240 | 241 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 242 | {{ \ 243 | .reduce = { \ 244 | .type = TSParseActionTypeReduce, \ 245 | .symbol = symbol_name, \ 246 | .child_count = children, \ 247 | .dynamic_precedence = precedence, \ 248 | .production_id = prod_id \ 249 | }, \ 250 | }} 251 | 252 | #define RECOVER() \ 253 | {{ \ 254 | .type = TSParseActionTypeRecover \ 255 | }} 256 | 257 | #define ACCEPT_INPUT() \ 258 | {{ \ 259 | .type = TSParseActionTypeAccept \ 260 | }} 261 | 262 | #ifdef __cplusplus 263 | } 264 | #endif 265 | 266 | #endif // TREE_SITTER_PARSER_H_ 267 | -------------------------------------------------------------------------------- /test/corpus/common.scm: -------------------------------------------------------------------------------- 1 | === 2 | symbol 3 | === 4 | + 5 | - 6 | * 7 | / 8 | ! 9 | even? 10 | odd? 11 | set! 12 | hello 13 | ar!$->2 14 | -> 15 | variable 16 | 123app123 17 | 变量 18 | 19 | --- 20 | (program 21 | (symbol) 22 | (symbol) 23 | (symbol) 24 | (symbol) 25 | (symbol) 26 | (symbol) 27 | (symbol) 28 | (symbol) 29 | (symbol) 30 | (symbol) 31 | (symbol) 32 | (symbol) 33 | (symbol) 34 | (symbol)) 35 | 36 | === 37 | list 38 | === 39 | (quote) 40 | (sym) 41 | (define x 1) 42 | (if (= 1 1) 1 0) 43 | #(1 2) 44 | #vu8(0 1) 45 | 46 | --- 47 | (program 48 | (list (symbol)) 49 | (list (symbol)) 50 | (list 51 | (symbol) 52 | (symbol) 53 | (number)) 54 | (list 55 | (symbol) 56 | (list 57 | (symbol) 58 | (number) 59 | (number)) 60 | (number) 61 | (number)) 62 | (vector 63 | (number) 64 | (number)) 65 | (byte_vector 66 | (number) 67 | (number))) 68 | 69 | === 70 | procedure 71 | === 72 | (lambda (x) (+ x 1)) 73 | 74 | (define (fib n) 75 | (if (< n 2) 1 76 | (+ (fib (- n 1)) 77 | (fib (- n 2))))) 78 | 79 | --- 80 | (program 81 | (list 82 | (symbol) 83 | (list 84 | (symbol)) 85 | (list 86 | (symbol) 87 | (symbol) 88 | (number))) 89 | 90 | (list 91 | (symbol) 92 | (list 93 | (symbol) 94 | (symbol)) 95 | (list 96 | (symbol) 97 | (list 98 | (symbol) 99 | (symbol) 100 | (number)) 101 | (number) 102 | (list 103 | (symbol) 104 | (list 105 | (symbol) 106 | (list 107 | (symbol) 108 | (symbol) 109 | (number))) 110 | (list 111 | (symbol) 112 | (list 113 | (symbol) 114 | (symbol) 115 | (number))))))) 116 | 117 | === 118 | macro 119 | === 120 | (define ~> 121 | (symtax-rules () 122 | [(_ val) 123 | val] 124 | [(_ val (f args ...) body ...) 125 | (~> (f val args ...) 126 | body ...)])) 127 | 128 | --- 129 | (program 130 | (list 131 | (symbol) 132 | (symbol) 133 | (list 134 | (symbol) 135 | (list) 136 | (list 137 | (list 138 | (symbol) 139 | (symbol)) 140 | (symbol)) 141 | (list 142 | (list 143 | (symbol) 144 | (symbol) 145 | (list 146 | (symbol) 147 | (symbol) 148 | (symbol)) 149 | (symbol) 150 | (symbol)) 151 | (list 152 | (symbol) 153 | (list 154 | (symbol) 155 | (symbol) 156 | (symbol) 157 | (symbol)) 158 | (symbol) 159 | (symbol)))))) 160 | -------------------------------------------------------------------------------- /test/corpus/ext.scm: -------------------------------------------------------------------------------- 1 | === 2 | list 3 | === 4 | 5 | {define x 1} 6 | 7 | --- 8 | (program 9 | (list 10 | (symbol) 11 | (symbol) 12 | (number))) 13 | 14 | === 15 | keyword 16 | === 17 | 18 | #:abc 19 | #:1abc 20 | 21 | --- 22 | (program 23 | (keyword) 24 | (keyword)) 25 | 26 | === 27 | character 28 | === 29 | 30 | #\bel 31 | #\ls 32 | #\nel 33 | #\rubout 34 | #\vt 35 | 36 | --- 37 | (program 38 | (character) 39 | (character) 40 | (character) 41 | (character) 42 | (character)) 43 | 44 | === 45 | string 46 | === 47 | 48 | "\. \'" 49 | 50 | --- 51 | (program 52 | (string 53 | (escape_sequence) 54 | (escape_sequence))) 55 | -------------------------------------------------------------------------------- /test/corpus/r5rs.scm: -------------------------------------------------------------------------------- 1 | === 2 | boolean 3 | === 4 | 5 | #t 6 | #f 7 | #T 8 | #F 9 | 10 | --- 11 | (program 12 | (boolean) 13 | (boolean) 14 | (boolean) 15 | (boolean)) 16 | 17 | === 18 | character 19 | === 20 | 21 | #\SpAcE 22 | #\NewLiNe 23 | #\1 24 | #\x 25 | 26 | --- 27 | (program 28 | (character) 29 | (character) 30 | (character) 31 | (character)) 32 | 33 | === 34 | string 35 | === 36 | ";;; abcd" 37 | "str\\\\" 38 | "str\\" 39 | "str\"" 40 | " ; abc ; " 41 | " " 42 | " 43 | abc" 44 | 45 | --- 46 | (program 47 | (string) 48 | (string 49 | (escape_sequence) 50 | (escape_sequence)) 51 | (string 52 | (escape_sequence)) 53 | (string 54 | (escape_sequence)) 55 | (string) 56 | (string) 57 | (string)) 58 | 59 | === 60 | comment 61 | === 62 | 63 | ; abc 64 | 65 | --- 66 | (program 67 | (comment)) 68 | 69 | === 70 | quote 71 | === 72 | 73 | 'abc 74 | `abc 75 | #'abc 76 | #`abc 77 | 78 | --- 79 | (program 80 | (quote (symbol)) 81 | (quasiquote (symbol)) 82 | (syntax (symbol)) 83 | (quasisyntax (symbol))) 84 | 85 | === 86 | unquote 87 | === 88 | 89 | ,abc 90 | ,@abc 91 | #,abc 92 | #,@abc 93 | 94 | --- 95 | (program 96 | (unquote (symbol)) 97 | (unquote_splicing (symbol)) 98 | (unsyntax (symbol)) 99 | (unsyntax_splicing (symbol))) 100 | 101 | === 102 | number 103 | === 104 | 105 | 1 106 | 1.0 107 | +1 108 | -1 109 | #d1 110 | #b010101011 111 | #B010101011 112 | #o7 113 | -i 114 | -1i 115 | 1-2i 116 | 1e12312 117 | #b#e-1######/1########-1#######/1########i 118 | #e-1010#######/1######### 119 | 120 | --- 121 | (program 122 | (number) 123 | (number) 124 | (number) 125 | (number) 126 | (number) 127 | (number) 128 | (number) 129 | (number) 130 | (number) 131 | (number) 132 | (number) 133 | (number) 134 | (number) 135 | (number)) 136 | -------------------------------------------------------------------------------- /test/corpus/r6rs.scm: -------------------------------------------------------------------------------- 1 | === 2 | boolean 3 | === 4 | 5 | #t 6 | #f 7 | #T 8 | #F 9 | 10 | --- 11 | (program 12 | (boolean) 13 | (boolean) 14 | (boolean) 15 | (boolean)) 16 | 17 | === 18 | character 19 | === 20 | 21 | #\1 22 | #\x 23 | #\nul #\alarm #\backspace 24 | #\tab #\linefeed #\newline 25 | #\vtab #\page #\return #\esc 26 | #\space #\delete 27 | #\x0 28 | #\xF 29 | #\xFFAA00 30 | 31 | --- 32 | (program 33 | (character) 34 | (character) 35 | (character) 36 | (character) 37 | (character) 38 | (character) 39 | (character) 40 | (character) 41 | (character) 42 | (character) 43 | (character) 44 | (character) 45 | (character) 46 | (character) 47 | (character) 48 | (character) 49 | (character)) 50 | 51 | === 52 | string 53 | === 54 | ";;; abcd" 55 | "str\\\\" 56 | "str\\" 57 | "str\"" 58 | " ; abc ; " 59 | " " 60 | " 61 | abc" 62 | "\a\b\t\n\v\f\r\"\\\\ 63 | \\" 64 | 65 | --- 66 | (program 67 | (string) 68 | (string 69 | (escape_sequence) 70 | (escape_sequence)) 71 | (string 72 | (escape_sequence)) 73 | (string 74 | (escape_sequence)) 75 | (string) 76 | (string) 77 | (string) 78 | (string 79 | (escape_sequence) 80 | (escape_sequence) 81 | (escape_sequence) 82 | (escape_sequence) 83 | (escape_sequence) 84 | (escape_sequence) 85 | (escape_sequence) 86 | (escape_sequence) 87 | (escape_sequence) 88 | (escape_sequence) 89 | (escape_sequence))) 90 | 91 | === 92 | directive 93 | === 94 | 95 | #!r6rs 96 | 97 | --- 98 | (program 99 | (directive)) 100 | 101 | === 102 | comment 103 | === 104 | ; abc 105 | #; (list) 106 | #| comment |# 107 | #| 108 | |comment 109 | |# 110 | #| a #| b |# |# 111 | #|#|#||##|x|#|##||#|# 112 | 113 | --- 114 | (program 115 | (comment) 116 | (comment (list (symbol))) 117 | (block_comment) 118 | (block_comment) 119 | (block_comment 120 | (block_comment)) 121 | (block_comment 122 | (block_comment 123 | (block_comment) 124 | (block_comment)) 125 | (block_comment))) 126 | 127 | === 128 | quote 129 | === 130 | 131 | 'abc 132 | `abc 133 | #'abc 134 | #`abc 135 | 136 | --- 137 | (program 138 | (quote (symbol)) 139 | (quasiquote (symbol)) 140 | (syntax (symbol)) 141 | (quasisyntax (symbol))) 142 | 143 | === 144 | unquote 145 | === 146 | 147 | ,abc 148 | ,@abc 149 | #,abc 150 | #,@abc 151 | 152 | --- 153 | (program 154 | (unquote (symbol)) 155 | (unquote_splicing (symbol)) 156 | (unsyntax (symbol)) 157 | (unsyntax_splicing (symbol))) 158 | 159 | === 160 | number 161 | === 162 | 163 | #X01AF 164 | 100000|10 165 | +nan.0 166 | -inf.0 167 | #E#D+10000.1098|100-1000i 168 | 169 | --- 170 | (program 171 | (number) 172 | (number) 173 | (number) 174 | (number) 175 | (number)) 176 | 177 | -------------------------------------------------------------------------------- /test/corpus/r7rs.scm: -------------------------------------------------------------------------------- 1 | === 2 | boolean 3 | === 4 | 5 | #t #T 6 | #f #F 7 | #TruE 8 | #FaLse 9 | 10 | --- 11 | (program 12 | (boolean) 13 | (boolean) 14 | (boolean) 15 | (boolean) 16 | (boolean) 17 | (boolean)) 18 | 19 | === 20 | character 21 | === 22 | 23 | #\. 24 | #\1 25 | #\alarm #\backspace #\delete #\escape 26 | #\newline #\null #\return #\space #\tab 27 | #\X09abcDEF 28 | 29 | --- 30 | (program 31 | (character) 32 | (character) 33 | (character) 34 | (character) 35 | (character) 36 | (character) 37 | (character) 38 | (character) 39 | (character) 40 | (character) 41 | (character) 42 | (character)) 43 | 44 | === 45 | string 46 | === 47 | 48 | " " 49 | "\ 50 | 123" 51 | "\X09abcDEF;" 52 | "\a\t \b \n \r" 53 | 54 | --- 55 | (program 56 | (string) 57 | (string 58 | (escape_sequence)) 59 | (string 60 | (escape_sequence)) 61 | (string 62 | (escape_sequence) 63 | (escape_sequence) 64 | (escape_sequence) 65 | (escape_sequence) 66 | (escape_sequence))) 67 | 68 | === 69 | directive 70 | === 71 | 72 | #!fold-case 73 | #!no-fold-case 74 | 75 | --- 76 | (program 77 | (directive) 78 | (directive)) 79 | 80 | === 81 | comment 82 | === 83 | 84 | ; cmt 85 | #| #| 86 | |# |# 87 | 88 | #; #;1 2 89 | 90 | --- 91 | (program 92 | (comment) 93 | (block_comment 94 | (block_comment)) 95 | (comment 96 | (comment 97 | (number)) 98 | (number))) 99 | 100 | === 101 | quote 102 | === 103 | 104 | 'sym 105 | `(1 ,2 ,@3 . 4) 106 | 107 | --- 108 | (program 109 | (quote (symbol)) 110 | (quasiquote 111 | (list 112 | (number) 113 | (unquote 114 | (number)) 115 | (unquote_splicing 116 | (number)) 117 | (symbol) 118 | (number)))) 119 | 120 | === 121 | number 122 | === 123 | 124 | 1 125 | 0.0 126 | #I#d+inf.0 127 | #i#D10/99+99/1i 128 | #i#D10/99-0123.0E+1i 129 | 130 | --- 131 | (program 132 | (number) 133 | (number) 134 | (number) 135 | (number) 136 | (number)) 137 | 138 | === 139 | symbol 140 | === 141 | 142 | a 143 | Z 144 | ! $ % & * / : < = > ? ^ _ ~ 145 | + - 146 | ++ 147 | -- 148 | +@ 149 | +! 150 | +!. 151 | +..!$ 152 | 1+ 153 | 123abc123 154 | | abc | 155 | | 156 | #;abc 157 | | 158 | |\| \a\b\t\n\r\X0AF;| 159 | 160 | --- 161 | (program 162 | (symbol) 163 | (symbol) 164 | (symbol) 165 | (symbol) 166 | (symbol) 167 | (symbol) 168 | (symbol) 169 | (symbol) 170 | (symbol) 171 | (symbol) 172 | (symbol) 173 | (symbol) 174 | (symbol) 175 | (symbol) 176 | (symbol) 177 | (symbol) 178 | (symbol) 179 | (symbol) 180 | (symbol) 181 | (symbol) 182 | (symbol) 183 | (symbol) 184 | (symbol) 185 | (symbol) 186 | (symbol) 187 | (symbol) 188 | (symbol) 189 | (symbol) 190 | (symbol)) 191 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "scheme", 5 | "camelcase": "Scheme", 6 | "scope": "source.scheme", 7 | "path": ".", 8 | "file-types": [ 9 | "scm", 10 | "ss" 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "version": "0.24.7", 16 | "license": "MIT", 17 | "description": "Tree-sitter grammar for Scheme", 18 | "authors": [ 19 | { 20 | "name": "6cdh" 21 | } 22 | ], 23 | "links": { 24 | "repository": "https://github.com/tree-sitter/tree-sitter-scheme" 25 | } 26 | }, 27 | "bindings": { 28 | "c": true, 29 | "go": true, 30 | "node": true, 31 | "python": true, 32 | "rust": true, 33 | "swift": true 34 | } 35 | } 36 | --------------------------------------------------------------------------------