├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-teal.pc.in │ └── tree_sitter │ │ └── tree-sitter-teal.h ├── go │ ├── binding.go │ └── binding_test.go ├── node │ ├── binding.cc │ ├── binding_test.js │ ├── index.d.ts │ └── index.js ├── python │ ├── tests │ │ └── test_binding.py │ └── tree_sitter_teal │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs ├── swift │ ├── TreeSitterTeal │ │ └── teal.h │ └── TreeSitterTealTests │ │ └── TreeSitterTealTests.swift └── zig │ └── root.zig ├── build.zig ├── build.zig.zon ├── eslint.config.mjs ├── go.mod ├── grammar.js ├── package-lock.json ├── package.json ├── pyproject.toml ├── queries ├── folds.scm ├── highlights.scm └── locals.scm ├── setup.py ├── src ├── grammar.json ├── node-types.json ├── parser.c ├── scanner.c └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test └── corpus │ ├── break.txt │ ├── casting.txt │ ├── comments.txt │ ├── do_blocks.txt │ ├── enum_block.txt │ ├── function_call.txt │ ├── function_declaration.txt │ ├── function_types.txt │ ├── generic_functions.txt │ ├── goto.txt │ ├── if_statements.txt │ ├── indexing.txt │ ├── interface_block.txt │ ├── macroexp.txt │ ├── numbers.txt │ ├── operators.txt │ ├── parenthesized.txt │ ├── record_block.txt │ ├── return.txt │ ├── semi-colons.txt │ ├── simple_types.txt │ ├── strings.txt │ ├── table_constructor.txt │ ├── table_types.txt │ ├── variable_assignment.txt │ └── variable_declaration.txt └── tree-sitter.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /.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 | 13 | # Zig bindings 14 | build.zig linguist-generated 15 | build.zig.zon linguist-generated 16 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - grammar.js 8 | - src/** 9 | - test/** 10 | - bindings/** 11 | - binding.gyp 12 | - examples/** 13 | pull_request: 14 | paths: 15 | - grammar.js 16 | - src/** 17 | - test/** 18 | - bindings/** 19 | - binding.gyp 20 | - examples/** 21 | 22 | concurrency: 23 | group: ${{github.workflow}}-${{github.ref}} 24 | cancel-in-progress: true 25 | 26 | jobs: 27 | test: 28 | name: Test parser 29 | runs-on: ${{matrix.os}} 30 | strategy: 31 | fail-fast: false 32 | matrix: 33 | os: [ubuntu-latest, windows-latest, macos-latest] 34 | steps: 35 | - name: Checkout repository 36 | uses: actions/checkout@v4 37 | - name: Set up tree-sitter 38 | uses: tree-sitter/setup-action/cli@v2 39 | - name: Run tests 40 | uses: tree-sitter/parser-test-action@v2 41 | with: 42 | test-rust: true 43 | test-node: true 44 | test-python: true 45 | test-go: true 46 | test-swift: true 47 | - name: Parse examples 48 | uses: tree-sitter/parse-action@v4 49 | with: 50 | files: examples/* 51 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - grammar.js 8 | pull_request: 9 | paths: 10 | - grammar.js 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | cache: npm 22 | node-version: ${{vars.NODE_VERSION}} 23 | - name: Install modules 24 | run: npm ci --legacy-peer-deps 25 | - name: Run ESLint 26 | run: npm run lint 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish packages 2 | 3 | on: 4 | push: 5 | tags: ["*"] 6 | 7 | permissions: 8 | contents: write 9 | id-token: write 10 | attestations: write 11 | 12 | jobs: 13 | github: 14 | uses: tree-sitter/workflows/.github/workflows/release.yml@main 15 | with: 16 | generate: true 17 | attestations: true 18 | # would need to setup the requisite tokens and then re-enable. 19 | # npm: 20 | # uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main 21 | # secrets: 22 | # NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 23 | # with: 24 | # generate: true 25 | # crates: 26 | # uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main 27 | # secrets: 28 | # CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}} 29 | # with: 30 | # generate: true 31 | # pypi: 32 | # uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main 33 | # secrets: 34 | # PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}} 35 | # with: 36 | # generate: true 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rust artifacts 2 | target/ 3 | 4 | # Node artifacts 5 | build/ 6 | prebuilds/ 7 | node_modules/ 8 | 9 | # Swift artifacts 10 | .build/ 11 | 12 | # Go artifacts 13 | _obj/ 14 | 15 | # Python artifacts 16 | .venv/ 17 | dist/ 18 | *.egg-info 19 | *.whl 20 | 21 | # C artifacts 22 | *.a 23 | *.so 24 | *.so.* 25 | *.dylib 26 | *.dll 27 | *.pc 28 | *.exp 29 | *.lib 30 | 31 | # Zig artifacts 32 | .zig-cache/ 33 | zig-cache/ 34 | zig-out/ 35 | 36 | # Example dirs 37 | /examples/*/ 38 | 39 | # Grammar volatiles 40 | *.wasm 41 | *.obj 42 | *.o 43 | 44 | # Archives 45 | *.tar.gz 46 | *.tgz 47 | *.zip 48 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-teal 4 | VERSION "0.1.0" 5 | DESCRIPTION "Tree sitter parser for Teal, a typed dialect of Lua." 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-teal" 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 15 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-teal src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-teal PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-teal 32 | PRIVATE src 33 | INTERFACE $ 34 | $) 35 | 36 | target_compile_definitions(tree-sitter-teal PRIVATE 37 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 38 | $<$:TREE_SITTER_DEBUG>) 39 | 40 | set_target_properties(tree-sitter-teal 41 | PROPERTIES 42 | C_STANDARD 11 43 | POSITION_INDEPENDENT_CODE ON 44 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 45 | DEFINE_SYMBOL "") 46 | 47 | configure_file(bindings/c/tree-sitter-teal.pc.in 48 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-teal.pc" @ONLY) 49 | 50 | include(GNUInstallDirs) 51 | 52 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter" 53 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 54 | FILES_MATCHING PATTERN "*.h") 55 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-teal.pc" 56 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 57 | install(TARGETS tree-sitter-teal 58 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 59 | 60 | file(GLOB QUERIES queries/*.scm) 61 | install(FILES ${QUERIES} 62 | DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/teal") 63 | 64 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 65 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 66 | COMMENT "tree-sitter test") 67 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-teal" 3 | description = "Tree sitter parser for Teal, a typed dialect of Lua." 4 | version = "0.1.0" 5 | authors = ["euclidianAce"] 6 | license = "MIT" 7 | readme = "README.md" 8 | keywords = ["incremental", "parsing", "tree-sitter", "teal"] 9 | categories = ["parser-implementations", "parsing", "text-editors"] 10 | repository = "https://github.com/tree-sitter/tree-sitter-teal" 11 | edition = "2021" 12 | autoexamples = false 13 | 14 | build = "bindings/rust/build.rs" 15 | include = [ 16 | "bindings/rust/*", 17 | "grammar.js", 18 | "queries/*", 19 | "src/*", 20 | "tree-sitter.json", 21 | "LICENSE", 22 | ] 23 | 24 | [lib] 25 | path = "bindings/rust/lib.rs" 26 | 27 | [dependencies] 28 | tree-sitter-language = "0.1" 29 | 30 | [build-dependencies] 31 | cc = "1.2" 32 | 33 | [dev-dependencies] 34 | tree-sitter = "0.25.3" 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 The tree-sitter-teal maintainers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-teal 6 | HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-teal 7 | VERSION := 0.1.0 8 | 9 | # repository 10 | SRC_DIR := src 11 | 12 | TS ?= tree-sitter 13 | 14 | # install directory layout 15 | PREFIX ?= /usr/local 16 | DATADIR ?= $(PREFIX)/share 17 | INCLUDEDIR ?= $(PREFIX)/include 18 | LIBDIR ?= $(PREFIX)/lib 19 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 20 | 21 | # source/object files 22 | PARSER := $(SRC_DIR)/parser.c 23 | EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 24 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 25 | 26 | # flags 27 | ARFLAGS ?= rcs 28 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 29 | 30 | # ABI versioning 31 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 32 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 33 | 34 | # OS-specific bits 35 | ifeq ($(shell uname),Darwin) 36 | SOEXT = dylib 37 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 38 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 39 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 40 | else 41 | SOEXT = so 42 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 43 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 44 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 45 | endif 46 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 47 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 48 | endif 49 | 50 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 51 | 52 | lib$(LANGUAGE_NAME).a: $(OBJS) 53 | $(AR) $(ARFLAGS) $@ $^ 54 | 55 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 56 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 57 | ifneq ($(STRIP),) 58 | $(STRIP) $@ 59 | endif 60 | 61 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 62 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 63 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 64 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 65 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 66 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 67 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 68 | 69 | $(PARSER): $(SRC_DIR)/grammar.json 70 | $(TS) generate $^ 71 | 72 | install: all 73 | install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/teal '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 74 | install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 75 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 76 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 77 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 78 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 79 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 80 | install -m644 queries/*.scm '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/teal 81 | 82 | uninstall: 83 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 84 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 85 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 86 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 87 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 88 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 89 | $(RM) -r '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/teal 90 | 91 | clean: 92 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 93 | 94 | test: 95 | $(TS) test 96 | 97 | .PHONY: all install uninstall clean test 98 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | 3 | import Foundation 4 | import PackageDescription 5 | 6 | var sources = ["src/parser.c"] 7 | if FileManager.default.fileExists(atPath: "src/scanner.c") { 8 | sources.append("src/scanner.c") 9 | } 10 | 11 | let package = Package( 12 | name: "TreeSitterTeal", 13 | products: [ 14 | .library(name: "TreeSitterTeal", targets: ["TreeSitterTeal"]), 15 | ], 16 | dependencies: [ 17 | .package(url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.8.0"), 18 | ], 19 | targets: [ 20 | .target( 21 | name: "TreeSitterTeal", 22 | dependencies: [], 23 | path: ".", 24 | sources: sources, 25 | resources: [ 26 | .copy("queries") 27 | ], 28 | publicHeadersPath: "bindings/swift", 29 | cSettings: [.headerSearchPath("src")] 30 | ), 31 | .testTarget( 32 | name: "TreeSitterTealTests", 33 | dependencies: [ 34 | "SwiftTreeSitter", 35 | "TreeSitterTeal", 36 | ], 37 | path: "bindings/swift/TreeSitterTealTests" 38 | ) 39 | ], 40 | cLanguageStandard: .c11 41 | ) 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-teal 2 | 3 | [![CI](https://github.com/euclidianAce/tree-sitter-teal/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/euclidianAce/tree-sitter-teal/actions/workflows/ci.yml) 4 | 5 | It's a tree-sitter parser for Teal 6 | 7 | Teal is a typed dialect of Lua, [get it here](https://github.com/teal-language/tl) 8 | 9 | ## Maintenance 10 | 11 | There are a couple of things that occaisionally need to be done after updating the grammar or going to a new tree-sitter version. 12 | 13 | ### Updating the version 14 | The version number should be updated using [semver](https://semver.org/). The `tree-sitter version` [command](https://tree-sitter.github.io/tree-sitter/creating-parsers#command-version) should be run to update the version across all the bindings: 15 | 16 | - tree-sitter.json 17 | - Cargo.toml 18 | - package.json 19 | - Makefile 20 | - CMakeLists.txt 21 | - pyproject.toml 22 | 23 | NOTE: this command is not yet available in `tree-sitter` (as of 11/2024, version: 0.24.0), so these files _need to be updated manually_. 24 | 25 | Afterwards, a new git tag can be created and a release will be generated by the GHA publish workflow. 26 | 27 | ### Updating to a new tree-sitter version 28 | We're still figuring out the best way to do this, so some of the steps below may not be fully correct. It is best to check the tree-sitter [changelog](https://github.com/tree-sitter/tree-sitter/releases) and see what bindings were updated and ensure the changes are reflected correctly. 29 | 30 | Update via `tree-sitter init --update` command: 31 | - The `--update` flag that should update the generated code accordingly. 32 | - Check if the files updated are in-accordance with what the changelog indicates. If they aren't, you may need to fully regenerate the bindings. 33 | 34 | Fully regenerate bindings: 35 | 1. Delete the language folder in `bindings` 36 | 2. Delete the corresponding package file (ex: Cargo.toml for rust, pyproject.toml for python, etc) 37 | 3. Run `tree-sitter init` to recreate the files. 38 | 4. From there, grep for "scanner", "query", and "queries" in the associated files (including the package files) and add/update the files as necessary 39 | - The code that needs to be added is usually explained in the comments, the grep will help find the comments. 40 | 41 | The GHA CI workflow will try and build for the various languages and will error out if there are any issues. 42 | 43 | 44 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_teal_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_teal(); 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 | auto language = Napi::External::New(env, tree_sitter_teal()); 14 | language.TypeTag(&LANGUAGE_TYPE_TAG); 15 | exports["language"] = language; 16 | return exports; 17 | } 18 | 19 | NODE_API_MODULE(tree_sitter_teal_binding, Init) 20 | -------------------------------------------------------------------------------- /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 | language: unknown; 23 | nodeTypeInfo: NodeInfo[]; 24 | }; 25 | 26 | declare const language: Language; 27 | export = language; 28 | -------------------------------------------------------------------------------- /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-teal.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 4 | import tree_sitter_teal 5 | 6 | 7 | class TestLanguage(TestCase): 8 | def test_can_load_grammar(self): 9 | try: 10 | tree_sitter.Language(tree_sitter_teal.language()) 11 | except Exception: 12 | self.fail("Error loading Teal grammar") 13 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_teal/__init__.py: -------------------------------------------------------------------------------- 1 | """Tree sitter parser for Teal, a typed dialect of Lua.""" 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_teal/__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_teal/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_teal(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_teal(), "tree_sitter.Language", NULL); 9 | } 10 | 11 | static struct PyModuleDef_Slot slots[] = { 12 | #ifdef Py_GIL_DISABLED 13 | {Py_mod_gil, Py_MOD_GIL_NOT_USED}, 14 | #endif 15 | {0, NULL} 16 | }; 17 | 18 | static PyMethodDef methods[] = { 19 | {"language", _binding_language, METH_NOARGS, 20 | "Get the tree-sitter language for this grammar."}, 21 | {NULL, NULL, 0, NULL} 22 | }; 23 | 24 | static struct PyModuleDef module = { 25 | .m_base = PyModuleDef_HEAD_INIT, 26 | .m_name = "_binding", 27 | .m_doc = NULL, 28 | .m_size = 0, 29 | .m_methods = methods, 30 | .m_slots = slots, 31 | }; 32 | 33 | PyMODINIT_FUNC PyInit__binding(void) { 34 | return PyModuleDef_Init(&module); 35 | } 36 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_teal/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/euclidianAce/tree-sitter-teal/05d276e737055e6f77a21335b7573c9d3c091e2f/bindings/python/tree_sitter_teal/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 | let scanner_path = src_dir.join("scanner.c"); 15 | if scanner_path.exists() { 16 | c_config.file(&scanner_path); 17 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 18 | } 19 | 20 | c_config.compile("tree-sitter-teal"); 21 | } 22 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides Teal 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_teal::LANGUAGE; 11 | //! parser 12 | //! .set_language(&language.into()) 13 | //! .expect("Error loading Teal 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_teal() -> *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_teal) }; 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/6-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 Teal parser"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterTeal/teal.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_TEAL_H_ 2 | #define TREE_SITTER_TEAL_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_teal(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_TEAL_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterTealTests/TreeSitterTealTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterTeal 4 | 5 | final class TreeSitterTealTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_teal()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading Teal grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /bindings/zig/root.zig: -------------------------------------------------------------------------------- 1 | const testing = @import("std").testing; 2 | 3 | const ts = @import("tree-sitter"); 4 | const Language = ts.Language; 5 | const Parser = ts.Parser; 6 | 7 | pub extern fn tree_sitter_teal() callconv(.C) *const Language; 8 | 9 | pub export fn language() *const Language { 10 | return tree_sitter_teal(); 11 | } 12 | 13 | test "can load grammar" { 14 | const parser = Parser.create(); 15 | defer parser.destroy(); 16 | try testing.expectEqual(parser.setLanguage(language()), void{}); 17 | try testing.expectEqual(parser.getLanguage(), tree_sitter_teal()); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.Build) !void { 4 | const target = b.standardTargetOptions(.{}); 5 | const optimize = b.standardOptimizeOption(.{}); 6 | 7 | const shared = b.option(bool, "build-shared", "Build a shared library") orelse true; 8 | const reuse_alloc = b.option(bool, "reuse-allocator", "Reuse the library allocator") orelse false; 9 | 10 | const lib: *std.Build.Step.Compile = if (shared) b.addSharedLibrary(.{ 11 | .name = "tree-sitter-teal", 12 | .pic = true, 13 | .target = target, 14 | .optimize = optimize, 15 | .link_libc = true, 16 | }) else b.addStaticLibrary(.{ 17 | .name = "tree-sitter-teal", 18 | .target = target, 19 | .optimize = optimize, 20 | .link_libc = true, 21 | }); 22 | 23 | lib.addCSourceFile(.{ 24 | .file = b.path("src/parser.c"), 25 | .flags = &.{"-std=c11"}, 26 | }); 27 | if (hasScanner(b.build_root.handle)) { 28 | lib.addCSourceFile(.{ 29 | .file = b.path("src/scanner.c"), 30 | .flags = &.{"-std=c11"}, 31 | }); 32 | } 33 | 34 | if (reuse_alloc) { 35 | lib.root_module.addCMacro("TREE_SITTER_REUSE_ALLOCATOR", ""); 36 | } 37 | if (optimize == .Debug) { 38 | lib.root_module.addCMacro("TREE_SITTER_DEBUG", ""); 39 | } 40 | 41 | lib.addIncludePath(b.path("src")); 42 | 43 | b.installArtifact(lib); 44 | b.installFile("src/node-types.json", "node-types.json"); 45 | b.installDirectory(.{ .source_dir = b.path("queries"), .install_dir = .prefix, .install_subdir = "queries", .include_extensions = &.{"scm"} }); 46 | 47 | const module = b.addModule("tree-sitter-teal", .{ 48 | .root_source_file = b.path("bindings/zig/root.zig"), 49 | .target = target, 50 | .optimize = optimize, 51 | }); 52 | module.linkLibrary(lib); 53 | 54 | const ts_dep = b.dependency("tree-sitter", .{}); 55 | const ts_mod = ts_dep.module("tree-sitter"); 56 | module.addImport("tree-sitter", ts_mod); 57 | 58 | // ╭─────────────────╮ 59 | // │ Tests │ 60 | // ╰─────────────────╯ 61 | 62 | const tests = b.addTest(.{ 63 | .root_source_file = b.path("bindings/zig/root.zig"), 64 | .target = target, 65 | .optimize = optimize, 66 | }); 67 | tests.linkLibrary(lib); 68 | tests.root_module.addImport("tree-sitter", ts_mod); 69 | 70 | const run_tests = b.addRunArtifact(tests); 71 | 72 | const test_step = b.step("test", "Run unit tests"); 73 | test_step.dependOn(&run_tests.step); 74 | } 75 | 76 | inline fn hasScanner(dir: std.fs.Dir) bool { 77 | dir.access("src/scanner.c", .{}) catch return false; 78 | return true; 79 | } 80 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = "tree-sitter-teal", 3 | .version = "0.0.4", 4 | .dependencies = .{ .@"tree-sitter" = .{ 5 | .url = "https://github.com/tree-sitter/zig-tree-sitter/archive/refs/tags/v0.25.0.tar.gz", 6 | .hash = "12201a8d5e840678bbbf5128e605519c4024af422295d68e2ba2090e675328e5811d", 7 | } }, 8 | .paths = .{ 9 | "build.zig", 10 | "build.zig.zon", 11 | "bindings/zig", 12 | "src", 13 | "queries", 14 | "LICENSE", 15 | "README.md", 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from 'eslint-config-treesitter'; 2 | 3 | export default [ 4 | ...treesitter, 5 | ]; 6 | 7 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter/tree-sitter-teal 2 | 3 | go 1.22 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | const list = (item, sep = ',') => seq(item, repeat(seq(sep, item))); 2 | 3 | const prec_op = { 4 | or: 1, 5 | and: 2, 6 | is: 3, 7 | comp: 4, 8 | bor: 5, 9 | bnot: 6, 10 | band: 7, 11 | bshift: 8, 12 | concat: 9, 13 | plus: 10, 14 | mult: 11, 15 | unary: 12, 16 | power: 13, 17 | 18 | as: 100, 19 | 20 | index: 1000, 21 | 22 | expr_for_statement: 10000, 23 | }; 24 | 25 | const prec_type_op = { 26 | union: 100, 27 | index: 1000, 28 | }; 29 | 30 | module.exports = grammar({ 31 | name: 'teal', 32 | 33 | extras: $ => [ 34 | $.comment, 35 | /[\s\n]/, 36 | ], 37 | 38 | externals: $ => [ 39 | $.comment, 40 | 41 | $._long_string_start, 42 | $._long_string_char, 43 | $._long_string_end, 44 | 45 | $._short_string_start, 46 | $._short_string_char, 47 | $._short_string_end, 48 | ], 49 | 50 | inline: $ => [ 51 | $.scope, 52 | $._partypelist, 53 | $._parnamelist, 54 | $._type_list_maybe_vararg, 55 | ], 56 | 57 | conflicts: $ => [ 58 | // conflict lies in table entries with type annotations vs array entry of a method call 59 | // ex: { foo: bar = nil } vs { foo:bar() } 60 | [$._var, $.table_entry], 61 | [$.return_type], 62 | ], 63 | 64 | word: $ => $.identifier, 65 | 66 | rules: { 67 | program: $ => seq( 68 | alias(optional(token.immediate(/#![^\n\r]*/)), $.shebang_comment), 69 | repeat($._statement), 70 | ), 71 | 72 | _statement: $ => prec(1, seq(choice( 73 | $.var_declaration, 74 | $.var_assignment, 75 | $.type_declaration, 76 | $.record_declaration, 77 | $.interface_declaration, 78 | $.enum_declaration, 79 | $.return_statement, 80 | $.break, 81 | $._for_statement, 82 | $.do_statement, 83 | $.while_statement, 84 | $.repeat_statement, 85 | $.function_call, 86 | $.function_statement, 87 | $.macroexp_statement, 88 | $.if_statement, 89 | seq('::', alias($.identifier, $.label), '::'), 90 | $.goto, 91 | ), optional(';'))), 92 | 93 | return_statement: $ => prec.right(1, seq( 94 | 'return', 95 | optional(choice( 96 | list($._expression), 97 | seq('(', list($._expression), ')'), 98 | )), 99 | )), 100 | 101 | break: $ => 'break', 102 | 103 | if_statement: $ => seq( 104 | 'if', field('condition', $._expression), 'then', 105 | repeat($._statement), 106 | repeat($.elseif_block), 107 | optional($.else_block), 108 | 'end', 109 | ), 110 | 111 | elseif_block: $ => seq('elseif', field('condition', $._expression), 'then', repeat($._statement)), 112 | else_block: $ => seq('else', repeat($._statement)), 113 | 114 | numeric_for_statement: $ => seq( 115 | 'for', field('variable', $.identifier), '=', field('initializer', $._expression), 116 | ',', field('target', $._expression), 117 | optional(seq(',', field('step', $._expression))), field('body', alias($.do_statement, $.for_body)), 118 | ), 119 | 120 | generic_for_statement: $ => seq( 121 | 'for', field('variable', list($.identifier)), 'in', field('iterator', list($._expression)), field('body', alias($.do_statement, $.for_body)), 122 | ), 123 | 124 | _for_statement: $ => choice( 125 | $.numeric_for_statement, 126 | $.generic_for_statement, 127 | ), 128 | 129 | while_statement: $ => seq( 130 | 'while', field('condition', $._expression), alias($.do_statement, $.while_body), 131 | ), 132 | 133 | repeat_statement: $ => seq( 134 | 'repeat', repeat($._statement), 135 | 'until', field('condition', $._expression), 136 | ), 137 | 138 | do_statement: $ => seq( 139 | 'do', 140 | repeat($._statement), 141 | 'end', 142 | ), 143 | 144 | _expression: $ => choice( 145 | $.identifier, 146 | $._var, 147 | $.number, 148 | $.string, 149 | $.boolean, 150 | $.nil, 151 | $.table_constructor, 152 | $.anon_function, 153 | $.function_call, 154 | $._prefix_expression, 155 | $.bin_op, 156 | $.unary_op, 157 | $.varargs, 158 | $.type_cast, 159 | $.parenthesized_expression, 160 | ), 161 | 162 | parenthesized_expression: $ => seq('(', $._expression, ')'), 163 | 164 | unary_op: $ => prec.left(prec_op.unary, seq( 165 | field('op', alias(choice('not', '#', '-', '~'), $.op)), 166 | field('right', $._expression), 167 | )), 168 | 169 | bin_op: $ => choice( 170 | ...[ 171 | ['or', prec_op.or], 172 | ['and', prec_op.and], 173 | ['<', prec_op.comp], 174 | ['<=', prec_op.comp], 175 | ['==', prec_op.comp], 176 | ['~=', prec_op.comp], 177 | ['>=', prec_op.comp], 178 | ['>', prec_op.comp], 179 | ['|', prec_op.bor], 180 | ['~', prec_op.bnot], 181 | ['&', prec_op.band], 182 | ['<<', prec_op.bshift], 183 | ['>>', prec_op.bshift], 184 | ['+', prec_op.plus], 185 | ['-', prec_op.plus], 186 | ['*', prec_op.mult], 187 | ['/', prec_op.mult], 188 | ['//', prec_op.mult], 189 | ['%', prec_op.mult], 190 | ].map(([operator, precedence]) => prec.left(precedence, seq( 191 | field('left', $._expression), 192 | field('op', alias(operator, $.op)), 193 | field('right', $._expression), 194 | ))), 195 | ...[ 196 | ['..', prec_op.concat], 197 | ['^', prec_op.power], 198 | ].map(([operator, precedence]) => prec.right(precedence, seq( 199 | field('left', $._expression), 200 | field('op', alias(operator, $.op)), 201 | field('right', $._expression), 202 | ))), 203 | prec.right(prec_op.is, seq( 204 | field('left', $._expression), 205 | field('op', alias('is', $.op)), 206 | field('right', $._type), 207 | )), 208 | ), 209 | 210 | type_cast: $ => prec.right(prec_op.as, seq( 211 | $._expression, 212 | 'as', 213 | choice($._type, $.type_tuple), 214 | )), 215 | 216 | type_tuple: $ => prec(10, seq('(', list($._type), ')')), 217 | type_union: $ => prec.left(prec_type_op.union, seq($._type, '|', $._type)), 218 | 219 | var_declarator: $ => seq( 220 | field('name', $.identifier), 221 | optional(seq('<', field('attribute', alias($.identifier, $.attribute)), '>')), 222 | ), 223 | 224 | var_declarators: $ => list(alias($.var_declarator, $.var)), 225 | 226 | expressions: $ => list($._expression), 227 | 228 | var_declaration: $ => seq( 229 | $.scope, 230 | field('declarators', $.var_declarators), 231 | optional(field('type_annotation', $.type_annotation)), 232 | optional(seq('=', field('initializers', $.expressions))), 233 | ), 234 | 235 | _type_def: $ => seq( 236 | 'type', 237 | field('name', $.identifier), 238 | '=', 239 | field('value', choice( 240 | $._type, $._newtype, 241 | )), 242 | ), 243 | 244 | type_declaration: $ => choice( 245 | seq( 246 | field('scope', $.scope), 247 | $._type_def, 248 | ), 249 | $.record_declaration, 250 | $.interface_declaration, 251 | $.enum_declaration, 252 | ), 253 | 254 | assignment_variables: $ => list(alias($._var, $.var)), 255 | 256 | var_assignment: $ => seq( 257 | field('variables', $.assignment_variables), '=', field('expressions', $.expressions), 258 | ), 259 | 260 | _prefix_expression: $ => prec(10, choice( 261 | $._var, 262 | $.function_call, 263 | $.parenthesized_expression, 264 | )), 265 | method_index: $ => seq($._prefix_expression, ':', field('key', $.identifier)), 266 | arguments: $ => choice( 267 | seq('(', optional(list($._expression)), ')'), 268 | $.string, 269 | $.table_constructor, 270 | ), 271 | function_call: $ => prec(10, seq( 272 | field('called_object', choice( 273 | $._prefix_expression, 274 | $.method_index, 275 | )), 276 | field('arguments', $.arguments), 277 | )), 278 | 279 | table_entry: $ => choice( 280 | seq('[', field('expr_key', $._expression), ']', '=', field('value', $._expression)), 281 | prec(1, seq( 282 | field('key', $.identifier), 283 | field('type', optional(seq(':', $._type))), 284 | '=', 285 | field('value', $._expression), 286 | )), 287 | prec(1, field('value', $._expression)), 288 | ), 289 | 290 | table_constructor: $ => seq( 291 | '{', 292 | optional(list($.table_entry, choice(',', ';'))), 293 | optional(choice(',', ';')), 294 | '}', 295 | ), 296 | 297 | function_name: $ => seq( 298 | field('base', $.identifier), 299 | choice( 300 | seq( 301 | repeat(seq('.', field('entry', $.identifier))), 302 | seq(':', field('method', $.identifier)), 303 | ), 304 | repeat1(seq('.', field('entry', $.identifier))), 305 | ), 306 | ), 307 | 308 | scope: $ => field('scope', choice('local', 'global')), 309 | 310 | function_statement: $ => choice( 311 | seq( 312 | $.scope, 313 | 'function', 314 | field('name', $.identifier), 315 | field('signature', $.function_signature), 316 | field('body', $.function_body), 317 | ), 318 | seq( 319 | 'function', 320 | field('name', $.function_name), 321 | field('signature', $.function_signature), 322 | field('body', $.function_body), 323 | ), 324 | ), 325 | 326 | macroexp_statement: $ => seq( 327 | 'local', 328 | $._macroexp_def, 329 | ), 330 | 331 | _macroexp_def: $ => seq( 332 | 'macroexp', 333 | field('name', $.identifier), 334 | field('signature', alias($.function_signature, $.macroexp_signature)), 335 | field('body', $.macroexp_body), 336 | ), 337 | 338 | macroexp_body: $ => seq( 339 | $.return_statement, 340 | 'end', 341 | ), 342 | 343 | variadic_type: $ => prec(prec_type_op.index - 1, seq($._type, '...')), 344 | _type_list_maybe_vararg: $ => seq(list($._type), optional(seq(',', $.variadic_type))), 345 | return_type: $ => choice( 346 | $.variadic_type, 347 | prec.dynamic(1, $._type_list_maybe_vararg), 348 | prec.dynamic(10, seq('(', $._type_list_maybe_vararg, ')')), 349 | ), 350 | 351 | _partypelist: $ => list(alias($._partype, $.arg)), 352 | _partype: $ => seq(optional(seq(field('name', $.identifier), ':')), field('type', $._type)), 353 | _parnamelist: $ => list(alias($._parname, $.arg)), 354 | _parname: $ => seq( 355 | field('name', $.identifier), 356 | optional(field('optional_marker', $.optional_marker)), 357 | optional(seq(':', field('type', $._type))), 358 | ), 359 | typearg: $ => choice( 360 | field('name', $.identifier), 361 | seq(field('name', $.identifier), 'is', field('constraint', $._type)) 362 | ), 363 | typeargs: $ => seq('<', list($.typearg), '>'), 364 | 365 | anon_function: $ => seq( 366 | 'function', 367 | field('signature', $.function_signature), 368 | field('body', $.function_body), 369 | ), 370 | 371 | optional_marker: $ => '?', 372 | 373 | _annotated_var_arg: $ => seq('...', ':', field('type', $._type)), 374 | signature_arguments: $ => seq('(', 375 | optional(choice( 376 | $._parnamelist, 377 | seq( 378 | $._parnamelist, 379 | ',', 380 | alias($._annotated_var_arg, $.varargs), 381 | ), 382 | alias($._annotated_var_arg, $.varargs), 383 | )), 384 | ')', 385 | ), 386 | 387 | function_signature: $ => seq( 388 | field('typeargs', optional($.typeargs)), 389 | field('arguments', alias($.signature_arguments, $.arguments)), 390 | optional(seq(':', field('return_type', $.return_type))), 391 | ), 392 | 393 | function_body: $ => seq( 394 | repeat($._statement), 395 | 'end', 396 | ), 397 | 398 | record_field: $ => choice( 399 | seq( 400 | field('key', $.identifier), 401 | ':', field('type', $._type), 402 | ), 403 | seq( 404 | '[', field('key', $.string), ']', 405 | ':', field('type', $._type), 406 | ), 407 | // TODO: there has to be a way around doing this, but I can't figure it out 408 | ...['type', 'record', 'interface', 'enum', 'userdata', 'metamethod'].map((reserved_id) => seq( 409 | field('key', alias(reserved_id, $.identifier)), 410 | ':', field('type', $._type), 411 | )), 412 | ), 413 | 414 | _record_entry: $ => choice( 415 | alias($.record_field, $.field), 416 | alias($._type_def, $.typedef), 417 | alias($._interface_def, $.interface_declaration), 418 | alias($._record_def, $.record_declaration), 419 | alias($._enum_def, $.enum_declaration), 420 | alias($._interface_def, $.interface_declaration), 421 | alias($._macroexp_def, $.macroexp_declaration), 422 | ), 423 | 424 | metamethod_annotation: $ => seq( 425 | 'metamethod', field('name', $.identifier), ':', field('type', $._type), 426 | ), 427 | 428 | record_body: $ => seq( 429 | optional(seq( 430 | field('is_types', seq('is', list($._type))), 431 | optional(field('where', seq('where', $._expression))), 432 | )), 433 | optional(seq('{', alias($._type, $.record_array_type), '}')), 434 | repeat(choice( 435 | $._record_entry, 436 | alias('userdata', $.userdata), 437 | field('metamethod', alias($.metamethod_annotation, $.metamethod)), 438 | )), 439 | 'end', 440 | ), 441 | 442 | _record_def: $ => seq( 443 | 'record', 444 | field('name', $.identifier), 445 | field('typeargs', optional($.typeargs)), 446 | field('record_body', $.record_body), 447 | ), 448 | 449 | _interface_def: $ => seq( 450 | 'interface', 451 | field('name', $.identifier), 452 | field('typeargs', optional($.typeargs)), 453 | field('interface_body', alias($.record_body, $.interface_body)), 454 | ), 455 | 456 | interface_declaration: $ => seq( 457 | $.scope, 458 | $._interface_def, 459 | ), 460 | 461 | record_declaration: $ => seq( 462 | $.scope, 463 | $._record_def, 464 | ), 465 | 466 | enum_body: $ => seq( 467 | repeat($.string), 468 | 'end', 469 | ), 470 | 471 | _enum_def: $ => seq( 472 | 'enum', 473 | field('name', $.identifier), 474 | field('enum_body', $.enum_body), 475 | ), 476 | 477 | enum_declaration: $ => seq( 478 | $.scope, 479 | $._enum_def, 480 | ), 481 | 482 | anon_interface: $ => seq( 483 | 'interface', 484 | optional($.typeargs), 485 | field('interface_body', alias($.record_body, $.interface_body)), 486 | ), 487 | 488 | anon_record: $ => seq( 489 | 'record', 490 | optional($.typeargs), 491 | field('record_body', $.record_body), 492 | ), 493 | 494 | _anon_enum: $ => seq( 495 | 'enum', 496 | $.enum_body, 497 | ), 498 | 499 | _newtype: $ => choice( 500 | $._anon_enum, 501 | $.anon_record, 502 | $.anon_interface, 503 | ), 504 | 505 | type_annotation: $ => seq( 506 | ':', 507 | list($._type), 508 | ), 509 | 510 | _type: $ => prec(2, choice( 511 | $.simple_type, 512 | $.type_index, 513 | $.table_type, 514 | $.function_type, 515 | $.type_union, 516 | seq('(', $._type, ')'), 517 | )), 518 | 519 | typearg_params: $ => prec.right(1000, seq( 520 | '<', list($._type), '>', 521 | )), 522 | 523 | type_index: $ => prec.right(prec_type_op.index, seq( 524 | choice($.identifier, $.type_index), '.', $.identifier, 525 | optional(alias($.typearg_params, $.typeargs)), 526 | )), 527 | 528 | simple_type: $ => prec.right(1000, seq( 529 | field('name', $.identifier), 530 | optional(alias($.typearg_params, $.typeargs)), 531 | )), 532 | 533 | table_type: $ => seq( 534 | '{', 535 | choice( 536 | field('value_type', $._type), 537 | seq( 538 | field('key_type', $._type), 539 | ':', 540 | field('value_type', $._type), 541 | ), 542 | seq( 543 | field('tuple_type', $._type), 544 | repeat1(seq(',', field('tuple_type', $._type))), 545 | ), 546 | ), 547 | '}', 548 | ), 549 | 550 | function_type_args: $ => seq( 551 | '(', 552 | optional(choice( 553 | seq( 554 | $._partypelist, 555 | optional(seq(',', alias($._annotated_var_arg, $.varargs))), 556 | ), 557 | alias($._annotated_var_arg, $.varargs), 558 | )), 559 | ')', 560 | ), 561 | 562 | function_type: $ => prec.right(1, seq( 563 | 'function', 564 | field('typeargs', optional($.typeargs)), 565 | optional(seq( 566 | field('arguments', alias($.function_type_args, $.arguments)), 567 | optional(seq( 568 | ':', 569 | field('return_type', $.return_type), 570 | )), 571 | )), 572 | )), 573 | 574 | goto: $ => seq('goto', $.identifier), 575 | 576 | index: $ => prec(1, seq( 577 | $._prefix_expression, 578 | choice( 579 | field('key', seq('.', $.identifier)), 580 | field('expr_key', seq('[', $._expression, ']')), 581 | ), 582 | )), 583 | 584 | _var: $ => prec(1, choice( 585 | $.identifier, 586 | $.index, 587 | )), 588 | 589 | varargs: $ => '...', 590 | identifier: $ => /[a-zA-Z_][a-zA-Z_0-9]*/, 591 | number: $ => choice( 592 | /\d+(\.\d+)?(e\d+)?/i, 593 | /\.\d+(e\d+)?/i, 594 | /0x[0-9a-fA-F]+(\.[0-9a-fA-F]+)?(p\d+)?/, 595 | ), 596 | boolean: $ => choice('true', 'false'), 597 | 598 | _short_string_content: $ => alias(repeat1(choice( 599 | $.format_specifier, 600 | $.escape_sequence, 601 | token.immediate(prec(1, '%')), 602 | prec(0, $._short_string_char), 603 | )), $.string_content), 604 | 605 | _long_string_content: $ => alias(repeat1(choice( 606 | $.format_specifier, 607 | $._long_string_char, 608 | token.immediate(prec(1, '%')), 609 | )), $.string_content), 610 | 611 | string: $ => prec(2, choice( 612 | seq( 613 | field('start', alias($._short_string_start, 'short_string_start')), 614 | field('content', optional($._short_string_content)), 615 | field('end', alias($._short_string_end, 'short_string_end')), 616 | ), 617 | 618 | seq( 619 | field('start', alias($._long_string_start, 'long_string_start')), 620 | field('content', optional($._long_string_content)), 621 | field('end', alias($._long_string_end, 'long_string_end')), 622 | ), 623 | )), 624 | 625 | format_specifier: $ => token.immediate(prec(3, seq( 626 | '%', 627 | choice( 628 | '%', 629 | seq( 630 | optional(choice( 631 | '+', '-', 632 | )), 633 | optional(' '), 634 | optional('#'), 635 | optional(/[0-9]+/), 636 | optional('.'), 637 | optional(/[0-9]+/), 638 | /[AaEefGgcdiouXxpqs]/, 639 | ), 640 | ), 641 | ))), 642 | 643 | escape_sequence: $ => token.immediate(prec(3, seq( 644 | '\\', 645 | choice( 646 | /[abfnrtvz"'\\]/, 647 | seq('x', /[0-9a-fA-F]{2}/), 648 | seq('d', /[0-7]{3}/), 649 | seq('u{', /[0-9a-fA-F]{1,8}/, '}'), 650 | ), 651 | ))), 652 | 653 | nil: $ => 'nil', 654 | }, 655 | }); 656 | 657 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-teal", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tree-sitter-teal", 9 | "version": "0.1.0", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "dependencies": { 13 | "node-addon-api": "^8.2.1", 14 | "node-gyp-build": "^4.8.2" 15 | }, 16 | "devDependencies": { 17 | "prebuildify": "^6.0.1", 18 | "tree-sitter-cli": "^0.25.3" 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.75.0", 158 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", 159 | "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", 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.3.1", 171 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", 172 | "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", 173 | "license": "MIT", 174 | "engines": { 175 | "node": "^18 || ^20 || >= 21" 176 | } 177 | }, 178 | "node_modules/node-gyp-build": { 179 | "version": "4.8.4", 180 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", 181 | "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", 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.2", 242 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", 243 | "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", 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.7.2", 289 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 290 | "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 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.2", 312 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", 313 | "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", 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-cli": { 341 | "version": "0.25.4", 342 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.4.tgz", 343 | "integrity": "sha512-tSOgiUuNH1xgSopWHMb+2EPuzIawj7/7/k0cNTNInBde21R0e53ElygJ+76PLjai2BOjnCzy9n8W0o7Eo9GVgA==", 344 | "dev": true, 345 | "hasInstallScript": true, 346 | "license": "MIT", 347 | "bin": { 348 | "tree-sitter": "cli.js" 349 | }, 350 | "engines": { 351 | "node": ">=12.0.0" 352 | } 353 | }, 354 | "node_modules/util-deprecate": { 355 | "version": "1.0.2", 356 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 357 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 358 | "dev": true, 359 | "license": "MIT" 360 | }, 361 | "node_modules/wrappy": { 362 | "version": "1.0.2", 363 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 364 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 365 | "dev": true, 366 | "license": "ISC" 367 | } 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-teal", 3 | "version": "0.1.0", 4 | "description": "Tree sitter parser for Teal, a typed dialect of Lua.", 5 | "repository": "https://github.com/tree-sitter/tree-sitter-teal", 6 | "license": "MIT", 7 | "author": { 8 | "name": "euclidianAce" 9 | }, 10 | "main": "bindings/node", 11 | "types": "bindings/node", 12 | "keywords": [ 13 | "incremental", 14 | "parsing", 15 | "tree-sitter", 16 | "teal" 17 | ], 18 | "files": [ 19 | "grammar.js", 20 | "tree-sitter.json", 21 | "binding.gyp", 22 | "prebuilds/**", 23 | "bindings/node/*", 24 | "queries/*", 25 | "src/**", 26 | "*.wasm" 27 | ], 28 | "dependencies": { 29 | "node-addon-api": "^8.2.1", 30 | "node-gyp-build": "^4.8.2" 31 | }, 32 | "devDependencies": { 33 | "prebuildify": "^6.0.1", 34 | "tree-sitter-cli": "^0.25.3" 35 | }, 36 | "peerDependencies": { 37 | "tree-sitter": "^0.21.1" 38 | }, 39 | "peerDependenciesMeta": { 40 | "tree-sitter": { 41 | "optional": true 42 | } 43 | }, 44 | "scripts": { 45 | "install": "node-gyp-build", 46 | "prestart": "tree-sitter build --wasm", 47 | "start": "tree-sitter playground", 48 | "test": "node --test bindings/node/*_test.js" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-teal" 7 | description = "Tree sitter parser for Teal, a typed dialect of Lua." 8 | version = "0.1.0" 9 | keywords = ["incremental", "parsing", "tree-sitter", "teal"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "Topic :: Software Development :: Compilers", 13 | "Topic :: Text Processing :: Linguistic", 14 | "Typing :: Typed", 15 | ] 16 | authors = [{ name = "euclidianAce" }] 17 | requires-python = ">=3.10" 18 | license.text = "MIT" 19 | readme = "README.md" 20 | 21 | [project.urls] 22 | Homepage = "https://github.com/tree-sitter/tree-sitter-teal" 23 | 24 | [project.optional-dependencies] 25 | core = ["tree-sitter~=0.24"] 26 | 27 | [tool.cibuildwheel] 28 | build = "cp310-*" 29 | build-frontend = "build" 30 | -------------------------------------------------------------------------------- /queries/folds.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (do_statement) 3 | (numeric_for_statement) 4 | (generic_for_statement) 5 | (while_statement) 6 | (repeat_statement) 7 | (if_statement) 8 | (function_statement) 9 | (record_declaration) 10 | (interface_declaration) 11 | (enum_declaration) 12 | (anon_function) 13 | (table_constructor) 14 | ] @fold 15 | 16 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | 2 | ;; Primitives 3 | (boolean) @boolean 4 | (comment) @comment 5 | (shebang_comment) @comment 6 | (identifier) @variable 7 | ((identifier) @variable.builtin 8 | (#eq? @variable.builtin "self")) 9 | (nil) @constant.builtin 10 | (number) @number 11 | (string) @string 12 | (table_constructor ["{" "}"] @constructor) 13 | (varargs "..." @constant.builtin) 14 | [ "," "." ":" ";" ] @punctuation.delimiter 15 | 16 | (escape_sequence) @string.escape 17 | (format_specifier) @string.escape 18 | 19 | ;; Basic statements/Keywords 20 | [ "if" "then" "elseif" "else" ] @conditional 21 | [ "for" "while" "repeat" "until" ] @repeat 22 | [ "in" "local" "return" (break) (goto) "do" "end" ] @keyword 23 | (label) @label 24 | 25 | ;; Global isn't a real keyword, but it gets special treatment in these places 26 | (var_declaration "global" @keyword) 27 | (type_declaration "global" @keyword) 28 | (function_statement "global" @keyword) 29 | (record_declaration "global" @keyword) 30 | (interface_declaration "global" @keyword) 31 | (enum_declaration "global" @keyword) 32 | 33 | (macroexp_statement "macroexp" @keyword) 34 | 35 | ;; Ops 36 | (bin_op (op) @operator) 37 | (unary_op (op) @operator) 38 | [ "=" "as" ] @operator 39 | 40 | ;; Functions 41 | (function_statement 42 | "function" @keyword.function 43 | . name: (_) @function) 44 | (anon_function 45 | "function" @keyword.function) 46 | (function_body "end" @keyword.function) 47 | 48 | (arg name: (identifier) @parameter) 49 | 50 | (function_signature 51 | (arguments 52 | . (arg name: (identifier) @variable.builtin)) 53 | (#eq? @variable.builtin "self")) 54 | 55 | (typeargs 56 | "<" @punctuation.bracket 57 | . (_) @parameter 58 | . ("," . (_) @parameter)* 59 | . ">" @punctuation.bracket) 60 | 61 | (function_call 62 | (identifier) @function . (arguments)) 63 | (function_call 64 | (index (_) key: (identifier) @function) . (arguments)) 65 | (function_call 66 | (method_index (_) key: (identifier) @function) . (arguments)) 67 | 68 | ;; Types 69 | 70 | ; Contextual keywords in record bodies 71 | (record_declaration 72 | . [ "record" ] @keyword 73 | name: (identifier) @type) 74 | (anon_record . "record" @keyword) 75 | (record_body 76 | (record_declaration 77 | . [ "record" ] @keyword 78 | . name: (identifier) @type)) 79 | (record_body 80 | (enum_declaration 81 | . [ "enum" ] @keyword 82 | . name: (identifier) @type)) 83 | (record_body 84 | (interface_declaration 85 | . [ "interface" ] @keyword 86 | . name: (identifier) @type)) 87 | (record_body 88 | (typedef 89 | . "type" @keyword 90 | . name: (identifier) @type . "=")) 91 | (record_body 92 | (macroexp_declaration 93 | . [ "macroexp" ] @keyword)) 94 | (record_body (metamethod "metamethod" @keyword)) 95 | (record_body (userdata) @keyword) 96 | 97 | ; Contextual keywords in interface bodies 98 | (interface_declaration 99 | . [ "interface" ] @keyword 100 | name: (identifier) @type) 101 | (anon_interface . "interface" @keyword) 102 | (interface_body 103 | (record_declaration 104 | . [ "record" ] @keyword 105 | . name: (identifier) @type)) 106 | (interface_body 107 | (enum_declaration 108 | . [ "enum" ] @keyword 109 | . name: (identifier) @type)) 110 | (interface_body 111 | (interface_declaration 112 | . [ "interface" ] @keyword 113 | . name: (identifier) @type)) 114 | (interface_body 115 | (typedef 116 | . "type" @keyword 117 | . name: (identifier) @type . "=")) 118 | (interface_body 119 | (macroexp_declaration 120 | . [ "macroexp" ] @keyword)) 121 | (interface_body (metamethod "metamethod" @keyword)) 122 | (interface_body (userdata) @keyword) 123 | 124 | (enum_declaration 125 | "enum" @keyword 126 | name: (identifier) @type) 127 | 128 | (type_declaration "type" @keyword) 129 | (type_declaration (identifier) @type) 130 | (simple_type) @type 131 | (type_index) @type 132 | (type_union "|" @operator) 133 | (function_type "function" @type) 134 | 135 | ;; The rest of it 136 | (var_declaration 137 | declarators: (var_declarators 138 | (var name: (identifier) @variable))) 139 | (var_declaration 140 | declarators: (var_declarators 141 | (var 142 | "<" @punctuation.bracket 143 | . attribute: (attribute) @attribute 144 | . ">" @punctuation.bracket))) 145 | [ "(" ")" "[" "]" "{" "}" ] @punctuation.bracket 146 | 147 | ;; Only highlight format specifiers in calls to string.format 148 | ;; string.format('...') 149 | ;(function_call 150 | ; called_object: (index 151 | ; (identifier) @base 152 | ; key: (identifier) @entry) 153 | ; arguments: (arguments . 154 | ; (string (format_specifier) @string.escape)) 155 | ; 156 | ; (#eq? @base "string") 157 | ; (#eq? @entry "format")) 158 | 159 | ;; ('...'):format() 160 | ;(function_call 161 | ; called_object: (method_index 162 | ; (string (format_specifier) @string.escape) 163 | ; key: (identifier) @func-name) 164 | ; (#eq? @func-name "format")) 165 | 166 | 167 | (ERROR) @error 168 | -------------------------------------------------------------------------------- /queries/locals.scm: -------------------------------------------------------------------------------- 1 | 2 | (var_declaration 3 | declarators: (var_declarators 4 | (var (identifier)) @definition.var)) 5 | 6 | (var_assignment 7 | variables: (assignment_variables 8 | (var (identifier) @definition.var) @definition.associated)) 9 | 10 | (arg name: (identifier) @definition.parameter) 11 | 12 | (anon_function) @scope 13 | ((function_statement 14 | (function_name) @definition.function) @scope 15 | (#set! definition.function.scope "parent")) 16 | 17 | (program) @scope 18 | (if_statement) @scope 19 | (generic_for_statement (for_body) @scope) 20 | (numeric_for_statement (for_body) @scope) 21 | (repeat_statement) @scope 22 | (while_statement (while_body) @scope) 23 | (do_statement) @scope 24 | 25 | (identifier) @reference 26 | 27 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | from platform import system 3 | from sysconfig import get_config_var 4 | 5 | from setuptools import Extension, find_packages, setup 6 | from setuptools.command.build import build 7 | from setuptools.command.egg_info import egg_info 8 | from wheel.bdist_wheel import bdist_wheel 9 | 10 | sources = [ 11 | "bindings/python/tree_sitter_teal/binding.c", 12 | "src/parser.c", 13 | ] 14 | if path.exists("src/scanner.c"): 15 | sources.append("src/scanner.c") 16 | 17 | macros: list[tuple[str, str | None]] = [ 18 | ("PY_SSIZE_T_CLEAN", None), 19 | ("TREE_SITTER_HIDE_SYMBOLS", None), 20 | ] 21 | if limited_api := not get_config_var("Py_GIL_DISABLED"): 22 | macros.append(("Py_LIMITED_API", "0x030A0000")) 23 | 24 | if system() != "Windows": 25 | cflags = ["-std=c11", "-fvisibility=hidden"] 26 | else: 27 | cflags = ["/std:c11", "/utf-8"] 28 | 29 | 30 | class Build(build): 31 | def run(self): 32 | if path.isdir("queries"): 33 | dest = path.join(self.build_lib, "tree_sitter_teal", "queries") 34 | self.copy_tree("queries", dest) 35 | super().run() 36 | 37 | 38 | class BdistWheel(bdist_wheel): 39 | def get_tag(self): 40 | python, abi, platform = super().get_tag() 41 | if python.startswith("cp"): 42 | python, abi = "cp310", "abi3" 43 | return python, abi, platform 44 | 45 | 46 | class EggInfo(egg_info): 47 | def find_sources(self): 48 | super().find_sources() 49 | self.filelist.recursive_include("queries", "*.scm") 50 | self.filelist.include("src/tree_sitter/*.h") 51 | 52 | 53 | setup( 54 | packages=find_packages("bindings/python"), 55 | package_dir={"": "bindings/python"}, 56 | package_data={ 57 | "tree_sitter_teal": ["*.pyi", "py.typed"], 58 | "tree_sitter_teal.queries": ["*.scm"], 59 | }, 60 | ext_package="tree_sitter_teal", 61 | ext_modules=[ 62 | Extension( 63 | name="_binding", 64 | sources=sources, 65 | extra_compile_args=cflags, 66 | define_macros=macros, 67 | include_dirs=["src"], 68 | py_limited_api=limited_api, 69 | ) 70 | ], 71 | cmdclass={ 72 | "build": Build, 73 | "bdist_wheel": BdistWheel, 74 | "egg_info": EggInfo, 75 | }, 76 | zip_safe=False 77 | ) 78 | -------------------------------------------------------------------------------- /src/scanner.c: -------------------------------------------------------------------------------- 1 | #include "tree_sitter/parser.h" 2 | #include "tree_sitter/alloc.h" 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | uint32_t opening_eqs; 8 | bool in_str; 9 | char opening_quote; 10 | } State; 11 | 12 | void *tree_sitter_teal_external_scanner_create() { return ts_calloc(1, sizeof(State)); } 13 | void tree_sitter_teal_external_scanner_destroy(void *payload) { ts_free(payload); } 14 | 15 | static inline void consume(TSLexer *lexer) { lexer->advance(lexer, false); } 16 | static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); } 17 | 18 | enum TokenType { 19 | COMMENT, 20 | 21 | LONG_STRING_START, 22 | LONG_STRING_CHAR, 23 | LONG_STRING_END, 24 | 25 | SHORT_STRING_START, 26 | SHORT_STRING_CHAR, 27 | SHORT_STRING_END, 28 | }; 29 | 30 | #define EXPECT(char) do { if (lexer->lookahead != char) { return false; } consume(lexer); } while (0) 31 | static inline uint32_t consume_eqs(TSLexer *lexer) { 32 | uint32_t result = 0; 33 | while (!lexer->eof(lexer) && lexer->lookahead == '=') { 34 | consume(lexer); 35 | result += 1; 36 | } 37 | return result; 38 | } 39 | 40 | static void consume_rest_of_line(TSLexer *lexer) { 41 | while (!lexer->eof(lexer)) { 42 | switch (lexer->lookahead) { 43 | case '\n': case '\r': return; 44 | default: consume(lexer); 45 | } 46 | } 47 | } 48 | 49 | static bool scan_comment(TSLexer *lexer) { 50 | EXPECT('-'); EXPECT('-'); 51 | lexer->result_symbol = COMMENT; 52 | 53 | if (lexer->lookahead != '[') { 54 | consume_rest_of_line(lexer); 55 | return true; 56 | } 57 | 58 | consume(lexer); 59 | uint32_t eqs = consume_eqs(lexer); 60 | 61 | if (lexer->lookahead != '[') { 62 | consume_rest_of_line(lexer); 63 | return true; 64 | } 65 | 66 | while (!lexer->eof(lexer)) { 67 | while (!lexer->eof(lexer) && lexer->lookahead != ']') 68 | consume(lexer); 69 | 70 | EXPECT(']'); 71 | uint32_t test_eq = consume_eqs(lexer); 72 | if (lexer->lookahead == ']') { 73 | consume(lexer); 74 | if (test_eq == eqs) { 75 | return true; 76 | } 77 | } else if (!lexer->eof(lexer)) { 78 | consume(lexer); 79 | } 80 | } 81 | 82 | return true; 83 | } 84 | 85 | static inline void reset_state(State *state) { 86 | *state = (State) { 87 | .opening_eqs = 0, 88 | .in_str = false, 89 | .opening_quote = 0, 90 | }; 91 | } 92 | 93 | unsigned tree_sitter_teal_external_scanner_serialize(void *payload, char *buffer) { 94 | memcpy(buffer, payload, sizeof(State)); 95 | return sizeof(State); 96 | } 97 | 98 | void tree_sitter_teal_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) { 99 | if (length < sizeof(State)) 100 | return; 101 | memcpy(payload, buffer, sizeof(State)); 102 | } 103 | 104 | static bool scan_short_string_start(State *state, TSLexer *lexer) { 105 | if ((lexer->lookahead == '"') || (lexer->lookahead == '\'')) { 106 | state->opening_quote = (char)lexer->lookahead; 107 | state->in_str = true; 108 | consume(lexer); 109 | lexer->result_symbol = SHORT_STRING_START; 110 | return true; 111 | } 112 | return false; 113 | } 114 | 115 | static bool scan_short_string_end(State *state, TSLexer *lexer) { 116 | if (state->in_str && lexer->lookahead == state->opening_quote) { 117 | consume(lexer); 118 | lexer->result_symbol = SHORT_STRING_END; 119 | reset_state(state); 120 | return true; 121 | } 122 | return false; 123 | } 124 | 125 | static bool scan_short_string_char(State *state, TSLexer *lexer) { 126 | if ( 127 | state->in_str 128 | && state->opening_quote > 0 129 | && lexer->lookahead != state->opening_quote 130 | && lexer->lookahead != '\n' 131 | && lexer->lookahead != '\r' 132 | && lexer->lookahead != '\\' 133 | && lexer->lookahead != '%' 134 | ) { 135 | consume(lexer); 136 | lexer->result_symbol = SHORT_STRING_CHAR; 137 | return true; 138 | } 139 | return false; 140 | } 141 | 142 | static bool scan_long_string_start(State *state, TSLexer *lexer) { 143 | EXPECT('['); 144 | reset_state(state); 145 | uint32_t eqs = consume_eqs(lexer); 146 | EXPECT('['); 147 | state->in_str = true; 148 | lexer->result_symbol = LONG_STRING_START; 149 | state->opening_eqs = eqs; 150 | return true; 151 | } 152 | 153 | static bool scan_long_string_end(State *state, TSLexer *lexer) { 154 | EXPECT(']'); 155 | 156 | uint32_t eqs = consume_eqs(lexer); 157 | if (state->opening_eqs == eqs && lexer->lookahead == ']') { 158 | consume(lexer); 159 | lexer->result_symbol = LONG_STRING_END; 160 | reset_state(state); 161 | return true; 162 | } 163 | return false; 164 | } 165 | 166 | static bool scan_long_string_char(TSLexer *lexer) { 167 | if (lexer->lookahead == '%') { 168 | return false; 169 | } 170 | consume(lexer); 171 | lexer->result_symbol = LONG_STRING_CHAR; 172 | return true; 173 | } 174 | 175 | static inline bool is_ascii_whitespace(uint32_t chr) { 176 | switch (chr) { 177 | default: return false; 178 | case '\n': case '\r': case ' ': case '\t': 179 | return true; 180 | } 181 | } 182 | 183 | bool tree_sitter_teal_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { 184 | State *state = payload; 185 | if (lexer->eof(lexer)) 186 | return false; 187 | 188 | if (state->in_str) { 189 | if (state->opening_quote > 0) { 190 | return (valid_symbols[SHORT_STRING_END] && scan_short_string_end(state, lexer)) 191 | || (valid_symbols[SHORT_STRING_CHAR] && scan_short_string_char(state, lexer)); 192 | } 193 | return scan_long_string_end(state, lexer) || scan_long_string_char(lexer); 194 | } 195 | 196 | while (is_ascii_whitespace(lexer->lookahead)) 197 | skip(lexer); 198 | 199 | if (valid_symbols[SHORT_STRING_START] && scan_short_string_start(state, lexer)) 200 | return true; 201 | 202 | if (valid_symbols[LONG_STRING_START] && scan_long_string_start(state, lexer)) 203 | return true; 204 | 205 | return valid_symbols[COMMENT] && scan_comment(lexer); 206 | } 207 | 208 | -------------------------------------------------------------------------------- /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 | typedef struct TSLanguageMetadata TSLanguageMetadata; 22 | typedef struct TSLanguageMetadata { 23 | uint8_t major_version; 24 | uint8_t minor_version; 25 | uint8_t patch_version; 26 | } TSLanguageMetadata; 27 | #endif 28 | 29 | typedef struct { 30 | TSFieldId field_id; 31 | uint8_t child_index; 32 | bool inherited; 33 | } TSFieldMapEntry; 34 | 35 | // Used to index the field and supertype maps. 36 | typedef struct { 37 | uint16_t index; 38 | uint16_t length; 39 | } TSMapSlice; 40 | 41 | typedef struct { 42 | bool visible; 43 | bool named; 44 | bool supertype; 45 | } TSSymbolMetadata; 46 | 47 | typedef struct TSLexer TSLexer; 48 | 49 | struct TSLexer { 50 | int32_t lookahead; 51 | TSSymbol result_symbol; 52 | void (*advance)(TSLexer *, bool); 53 | void (*mark_end)(TSLexer *); 54 | uint32_t (*get_column)(TSLexer *); 55 | bool (*is_at_included_range_start)(const TSLexer *); 56 | bool (*eof)(const TSLexer *); 57 | void (*log)(const TSLexer *, const char *, ...); 58 | }; 59 | 60 | typedef enum { 61 | TSParseActionTypeShift, 62 | TSParseActionTypeReduce, 63 | TSParseActionTypeAccept, 64 | TSParseActionTypeRecover, 65 | } TSParseActionType; 66 | 67 | typedef union { 68 | struct { 69 | uint8_t type; 70 | TSStateId state; 71 | bool extra; 72 | bool repetition; 73 | } shift; 74 | struct { 75 | uint8_t type; 76 | uint8_t child_count; 77 | TSSymbol symbol; 78 | int16_t dynamic_precedence; 79 | uint16_t production_id; 80 | } reduce; 81 | uint8_t type; 82 | } TSParseAction; 83 | 84 | typedef struct { 85 | uint16_t lex_state; 86 | uint16_t external_lex_state; 87 | } TSLexMode; 88 | 89 | typedef struct { 90 | uint16_t lex_state; 91 | uint16_t external_lex_state; 92 | uint16_t reserved_word_set_id; 93 | } TSLexerMode; 94 | 95 | typedef union { 96 | TSParseAction action; 97 | struct { 98 | uint8_t count; 99 | bool reusable; 100 | } entry; 101 | } TSParseActionEntry; 102 | 103 | typedef struct { 104 | int32_t start; 105 | int32_t end; 106 | } TSCharacterRange; 107 | 108 | struct TSLanguage { 109 | uint32_t abi_version; 110 | uint32_t symbol_count; 111 | uint32_t alias_count; 112 | uint32_t token_count; 113 | uint32_t external_token_count; 114 | uint32_t state_count; 115 | uint32_t large_state_count; 116 | uint32_t production_id_count; 117 | uint32_t field_count; 118 | uint16_t max_alias_sequence_length; 119 | const uint16_t *parse_table; 120 | const uint16_t *small_parse_table; 121 | const uint32_t *small_parse_table_map; 122 | const TSParseActionEntry *parse_actions; 123 | const char * const *symbol_names; 124 | const char * const *field_names; 125 | const TSMapSlice *field_map_slices; 126 | const TSFieldMapEntry *field_map_entries; 127 | const TSSymbolMetadata *symbol_metadata; 128 | const TSSymbol *public_symbol_map; 129 | const uint16_t *alias_map; 130 | const TSSymbol *alias_sequences; 131 | const TSLexerMode *lex_modes; 132 | bool (*lex_fn)(TSLexer *, TSStateId); 133 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 134 | TSSymbol keyword_capture_token; 135 | struct { 136 | const bool *states; 137 | const TSSymbol *symbol_map; 138 | void *(*create)(void); 139 | void (*destroy)(void *); 140 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 141 | unsigned (*serialize)(void *, char *); 142 | void (*deserialize)(void *, const char *, unsigned); 143 | } external_scanner; 144 | const TSStateId *primary_state_ids; 145 | const char *name; 146 | const TSSymbol *reserved_words; 147 | uint16_t max_reserved_word_set_size; 148 | uint32_t supertype_count; 149 | const TSSymbol *supertype_symbols; 150 | const TSMapSlice *supertype_map_slices; 151 | const TSSymbol *supertype_map_entries; 152 | TSLanguageMetadata metadata; 153 | }; 154 | 155 | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 156 | uint32_t index = 0; 157 | uint32_t size = len - index; 158 | while (size > 1) { 159 | uint32_t half_size = size / 2; 160 | uint32_t mid_index = index + half_size; 161 | const TSCharacterRange *range = &ranges[mid_index]; 162 | if (lookahead >= range->start && lookahead <= range->end) { 163 | return true; 164 | } else if (lookahead > range->end) { 165 | index = mid_index; 166 | } 167 | size -= half_size; 168 | } 169 | const TSCharacterRange *range = &ranges[index]; 170 | return (lookahead >= range->start && lookahead <= range->end); 171 | } 172 | 173 | /* 174 | * Lexer Macros 175 | */ 176 | 177 | #ifdef _MSC_VER 178 | #define UNUSED __pragma(warning(suppress : 4101)) 179 | #else 180 | #define UNUSED __attribute__((unused)) 181 | #endif 182 | 183 | #define START_LEXER() \ 184 | bool result = false; \ 185 | bool skip = false; \ 186 | UNUSED \ 187 | bool eof = false; \ 188 | int32_t lookahead; \ 189 | goto start; \ 190 | next_state: \ 191 | lexer->advance(lexer, skip); \ 192 | start: \ 193 | skip = false; \ 194 | lookahead = lexer->lookahead; 195 | 196 | #define ADVANCE(state_value) \ 197 | { \ 198 | state = state_value; \ 199 | goto next_state; \ 200 | } 201 | 202 | #define ADVANCE_MAP(...) \ 203 | { \ 204 | static const uint16_t map[] = { __VA_ARGS__ }; \ 205 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 206 | if (map[i] == lookahead) { \ 207 | state = map[i + 1]; \ 208 | goto next_state; \ 209 | } \ 210 | } \ 211 | } 212 | 213 | #define SKIP(state_value) \ 214 | { \ 215 | skip = true; \ 216 | state = state_value; \ 217 | goto next_state; \ 218 | } 219 | 220 | #define ACCEPT_TOKEN(symbol_value) \ 221 | result = true; \ 222 | lexer->result_symbol = symbol_value; \ 223 | lexer->mark_end(lexer); 224 | 225 | #define END_STATE() return result; 226 | 227 | /* 228 | * Parse Table Macros 229 | */ 230 | 231 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 232 | 233 | #define STATE(id) id 234 | 235 | #define ACTIONS(id) id 236 | 237 | #define SHIFT(state_value) \ 238 | {{ \ 239 | .shift = { \ 240 | .type = TSParseActionTypeShift, \ 241 | .state = (state_value) \ 242 | } \ 243 | }} 244 | 245 | #define SHIFT_REPEAT(state_value) \ 246 | {{ \ 247 | .shift = { \ 248 | .type = TSParseActionTypeShift, \ 249 | .state = (state_value), \ 250 | .repetition = true \ 251 | } \ 252 | }} 253 | 254 | #define SHIFT_EXTRA() \ 255 | {{ \ 256 | .shift = { \ 257 | .type = TSParseActionTypeShift, \ 258 | .extra = true \ 259 | } \ 260 | }} 261 | 262 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 263 | {{ \ 264 | .reduce = { \ 265 | .type = TSParseActionTypeReduce, \ 266 | .symbol = symbol_name, \ 267 | .child_count = children, \ 268 | .dynamic_precedence = precedence, \ 269 | .production_id = prod_id \ 270 | }, \ 271 | }} 272 | 273 | #define RECOVER() \ 274 | {{ \ 275 | .type = TSParseActionTypeRecover \ 276 | }} 277 | 278 | #define ACCEPT_INPUT() \ 279 | {{ \ 280 | .type = TSParseActionTypeAccept \ 281 | }} 282 | 283 | #ifdef __cplusplus 284 | } 285 | #endif 286 | 287 | #endif // TREE_SITTER_PARSER_H_ 288 | -------------------------------------------------------------------------------- /test/corpus/break.txt: -------------------------------------------------------------------------------- 1 | 2 | ============================== 3 | Break 4 | ============================== 5 | 6 | break 7 | 8 | --- 9 | 10 | (program (break)) 11 | -------------------------------------------------------------------------------- /test/corpus/casting.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple cast 3 | ================================================================================ 4 | 5 | return "thing" as number 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (return_statement 11 | (type_cast 12 | (string 13 | (string_content)) 14 | (simple_type 15 | (identifier))))) 16 | 17 | ================================================================================ 18 | Tuple cast 19 | ================================================================================ 20 | 21 | return thing() as (string, string) 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (return_statement 27 | (type_cast 28 | (function_call 29 | (identifier) 30 | (arguments)) 31 | (type_tuple 32 | (simple_type 33 | (identifier)) 34 | (simple_type 35 | (identifier)))))) 36 | -------------------------------------------------------------------------------- /test/corpus/comments.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Single line comment 3 | ================================================================================ 4 | 5 | -- This is a comment 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (comment)) 11 | 12 | ================================================================================ 13 | Multi line comment 14 | ================================================================================ 15 | 16 | --[[ 17 | This is a comment 18 | ]] 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | (program 23 | (comment)) 24 | 25 | ================================================================================ 26 | Multi line comment with multiple equal signs 27 | ================================================================================ 28 | 29 | --[==[ 30 | This is a comment 31 | ]==] 32 | 33 | -------------------------------------------------------------------------------- 34 | 35 | (program 36 | (comment)) 37 | 38 | ================================================================================ 39 | Nested comments 40 | ================================================================================ 41 | 42 | --[===[ 43 | This is a comment 44 | [=[ with some ]=] 45 | [==[ nesting ]==] 46 | ]===] 47 | 48 | -------------------------------------------------------------------------------- 49 | 50 | (program 51 | (comment)) 52 | 53 | ================================================================================ 54 | Inline comment 55 | ================================================================================ 56 | 57 | local x --[[ This is a comment ]] = 5 58 | 59 | -------------------------------------------------------------------------------- 60 | 61 | (program 62 | (var_declaration 63 | (var_declarators 64 | (var 65 | (identifier))) 66 | (comment) 67 | (expressions 68 | (number)))) 69 | 70 | ================================================================================ 71 | line comment that starts with --[ 72 | ================================================================================ 73 | 74 | --[ stuff 75 | local x = 5 76 | 77 | -------------------------------------------------------------------------------- 78 | 79 | (program 80 | (comment) 81 | (var_declaration 82 | (var_declarators 83 | (var 84 | (identifier))) 85 | (expressions 86 | (number)))) 87 | 88 | ================================================================================ 89 | line comment with whitespace -- [[ 90 | ================================================================================ 91 | 92 | -- [[ hi 93 | local x = 5 94 | 95 | -------------------------------------------------------------------------------- 96 | 97 | (program 98 | (comment) 99 | (var_declaration 100 | (var_declarators 101 | (var 102 | (identifier))) 103 | (expressions 104 | (number)))) 105 | 106 | ================================================================================ 107 | Shebang comment 108 | ================================================================================ 109 | #!/usr/bin/env tl run 110 | 111 | -------------------------------------------------------------------------------- 112 | 113 | (program 114 | (shebang_comment)) 115 | -------------------------------------------------------------------------------- /test/corpus/do_blocks.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Do block 3 | ================================================================================ 4 | 5 | do 6 | end 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (program 11 | (do_statement)) 12 | 13 | ================================================================================ 14 | Nested do blocks 15 | ================================================================================ 16 | 17 | do 18 | do 19 | do 20 | end 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (do_statement 28 | (do_statement 29 | (do_statement)))) 30 | 31 | ================================================================================ 32 | Numeric for loop 33 | ================================================================================ 34 | 35 | for i = 1, 10 do 36 | end 37 | 38 | -------------------------------------------------------------------------------- 39 | 40 | (program 41 | (numeric_for_statement 42 | (identifier) 43 | (number) 44 | (number) 45 | (for_body))) 46 | 47 | ================================================================================ 48 | Numeric for loop with step 49 | ================================================================================ 50 | 51 | for i = 1, 10, -2 do 52 | end 53 | 54 | -------------------------------------------------------------------------------- 55 | 56 | (program 57 | (numeric_for_statement 58 | variable: (identifier) 59 | initializer: (number) 60 | target: (number) 61 | step: (unary_op 62 | op: (op) 63 | right: (number)) 64 | body: (for_body))) 65 | 66 | ================================================================================ 67 | Generic for loop 68 | ================================================================================ 69 | 70 | for i, v in thingy do 71 | 72 | end 73 | 74 | -------------------------------------------------------------------------------- 75 | 76 | (program 77 | (generic_for_statement 78 | (identifier) 79 | (identifier) 80 | (identifier) 81 | (for_body))) 82 | 83 | ================================================================================ 84 | While loop 85 | ================================================================================ 86 | 87 | while 1 do 88 | end 89 | 90 | -------------------------------------------------------------------------------- 91 | 92 | (program 93 | (while_statement 94 | condition: (number) 95 | (while_body))) 96 | 97 | ================================================================================ 98 | Repeat loop 99 | ================================================================================ 100 | 101 | repeat 102 | until 1 103 | 104 | -------------------------------------------------------------------------------- 105 | 106 | (program 107 | (repeat_statement 108 | condition: (number))) 109 | 110 | ================================================================================ 111 | A whole bunch of loops 112 | ================================================================================ 113 | 114 | for i = 1, 20 do 115 | while i < 10 do 116 | repeat 117 | do 118 | end 119 | until i > 30 120 | end 121 | end 122 | 123 | -------------------------------------------------------------------------------- 124 | 125 | (program 126 | (numeric_for_statement 127 | variable: (identifier) 128 | initializer: (number) 129 | target: (number) 130 | body: (for_body 131 | (while_statement 132 | condition: (bin_op 133 | left: (identifier) 134 | op: (op) 135 | right: (number)) 136 | (while_body 137 | (repeat_statement 138 | (do_statement) 139 | condition: (bin_op 140 | left: (identifier) 141 | op: (op) 142 | right: (number)))))))) 143 | -------------------------------------------------------------------------------- /test/corpus/enum_block.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty enum 3 | ================================================================================ 4 | 5 | local type foo = enum 6 | end 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (program 11 | (type_declaration 12 | name: (identifier) 13 | value: (enum_body))) 14 | 15 | ================================================================================ 16 | Enum with stuff 17 | ================================================================================ 18 | 19 | local type foo = enum 20 | "hello" 21 | "world" 22 | end 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (type_declaration 28 | name: (identifier) 29 | value: (enum_body 30 | (string 31 | content: (string_content)) 32 | (string 33 | content: (string_content))))) 34 | 35 | ================================================================================ 36 | Empty enum (shorthand) 37 | ================================================================================ 38 | 39 | local enum foo 40 | end 41 | 42 | -------------------------------------------------------------------------------- 43 | 44 | (program 45 | (enum_declaration 46 | name: (identifier) 47 | enum_body: (enum_body))) 48 | 49 | ================================================================================ 50 | Enum with stuff (shorthand) 51 | ================================================================================ 52 | 53 | local enum foo 54 | "foo" 55 | "bar" 56 | "baz" 57 | end 58 | 59 | -------------------------------------------------------------------------------- 60 | 61 | (program 62 | (enum_declaration 63 | name: (identifier) 64 | enum_body: (enum_body 65 | (string 66 | content: (string_content)) 67 | (string 68 | content: (string_content)) 69 | (string 70 | content: (string_content))))) 71 | -------------------------------------------------------------------------------- /test/corpus/function_call.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Basic call 3 | ================================================================================ 4 | 5 | print("hello world") 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (function_call 11 | called_object: (identifier) 12 | arguments: (arguments 13 | (string 14 | content: (string_content))))) 15 | 16 | ================================================================================ 17 | Multiple arguments 18 | ================================================================================ 19 | 20 | print(a, b) 21 | 22 | -------------------------------------------------------------------------------- 23 | 24 | (program 25 | (function_call 26 | called_object: (identifier) 27 | arguments: (arguments 28 | (identifier) 29 | (identifier)))) 30 | 31 | ================================================================================ 32 | Basic single string arg 33 | ================================================================================ 34 | 35 | print "hello world" 36 | 37 | -------------------------------------------------------------------------------- 38 | 39 | (program 40 | (function_call 41 | called_object: (identifier) 42 | arguments: (arguments 43 | (string 44 | content: (string_content))))) 45 | 46 | ================================================================================ 47 | Basic single table arg 48 | ================================================================================ 49 | 50 | print {} 51 | 52 | -------------------------------------------------------------------------------- 53 | 54 | (program 55 | (function_call 56 | called_object: (identifier) 57 | arguments: (arguments 58 | (table_constructor)))) 59 | 60 | ================================================================================ 61 | Call table entry 62 | ================================================================================ 63 | 64 | foo.bar() 65 | 66 | -------------------------------------------------------------------------------- 67 | 68 | (program 69 | (function_call 70 | called_object: (index 71 | (identifier) 72 | key: (identifier)) 73 | arguments: (arguments))) 74 | 75 | ================================================================================ 76 | Call table index 77 | ================================================================================ 78 | 79 | foo[bar]() 80 | 81 | -------------------------------------------------------------------------------- 82 | 83 | (program 84 | (function_call 85 | called_object: (index 86 | (identifier) 87 | expr_key: (identifier)) 88 | arguments: (arguments))) 89 | 90 | ================================================================================ 91 | Call table entry of table entry 92 | ================================================================================ 93 | 94 | foo.bar.baz() 95 | 96 | -------------------------------------------------------------------------------- 97 | 98 | (program 99 | (function_call 100 | called_object: (index 101 | (index 102 | (identifier) 103 | key: (identifier)) 104 | key: (identifier)) 105 | arguments: (arguments))) 106 | 107 | ================================================================================ 108 | Higher order calls 109 | ================================================================================ 110 | 111 | func_that_returns_func()() 112 | 113 | -------------------------------------------------------------------------------- 114 | 115 | (program 116 | (function_call 117 | called_object: (function_call 118 | called_object: (identifier) 119 | arguments: (arguments)) 120 | arguments: (arguments))) 121 | 122 | ================================================================================ 123 | More higher order calls 124 | ================================================================================ 125 | 126 | func_that_returns_func()()()()()()() 127 | 128 | -------------------------------------------------------------------------------- 129 | 130 | (program 131 | (function_call 132 | called_object: (function_call 133 | called_object: (function_call 134 | called_object: (function_call 135 | called_object: (function_call 136 | called_object: (function_call 137 | called_object: (function_call 138 | called_object: (identifier) 139 | arguments: (arguments)) 140 | arguments: (arguments)) 141 | arguments: (arguments)) 142 | arguments: (arguments)) 143 | arguments: (arguments)) 144 | arguments: (arguments)) 145 | arguments: (arguments))) 146 | 147 | ================================================================================ 148 | Even more higher order calls 149 | ================================================================================ 150 | 151 | func_that_returns_func "hello" "world" "foo" "bar" 152 | 153 | -------------------------------------------------------------------------------- 154 | 155 | (program 156 | (function_call 157 | called_object: (function_call 158 | called_object: (function_call 159 | called_object: (function_call 160 | called_object: (identifier) 161 | arguments: (arguments 162 | (string 163 | content: (string_content)))) 164 | arguments: (arguments 165 | (string 166 | content: (string_content)))) 167 | arguments: (arguments 168 | (string 169 | content: (string_content)))) 170 | arguments: (arguments 171 | (string 172 | content: (string_content))))) 173 | 174 | ================================================================================ 175 | You get the idea 176 | ================================================================================ 177 | 178 | func_that_returns_func "hello" { this = "is" } "getting" "silly" 179 | 180 | -------------------------------------------------------------------------------- 181 | 182 | (program 183 | (function_call 184 | called_object: (function_call 185 | called_object: (function_call 186 | called_object: (function_call 187 | called_object: (identifier) 188 | arguments: (arguments 189 | (string 190 | content: (string_content)))) 191 | arguments: (arguments 192 | (table_constructor 193 | (table_entry 194 | key: (identifier) 195 | value: (string 196 | content: (string_content)))))) 197 | arguments: (arguments 198 | (string 199 | content: (string_content)))) 200 | arguments: (arguments 201 | (string 202 | content: (string_content))))) 203 | -------------------------------------------------------------------------------- /test/corpus/function_declaration.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Anonymous 3 | ================================================================================ 4 | 5 | local foo = function() 6 | end 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (program 11 | (var_declaration 12 | (var_declarators 13 | (var 14 | (identifier))) 15 | (expressions 16 | (anon_function 17 | (function_signature 18 | (arguments)) 19 | (function_body))))) 20 | 21 | ================================================================================ 22 | Named 23 | ================================================================================ 24 | 25 | local function foo() 26 | end 27 | 28 | -------------------------------------------------------------------------------- 29 | 30 | (program 31 | (function_statement 32 | name: (identifier) 33 | signature: (function_signature 34 | arguments: (arguments)) 35 | body: (function_body))) 36 | 37 | ================================================================================ 38 | A function that actually does something 39 | ================================================================================ 40 | 41 | local function bar() 42 | local x = 3 43 | local y = { 44 | z = function() 45 | local x = 1 46 | end, 47 | w = function() 48 | end, 49 | } 50 | end 51 | 52 | -------------------------------------------------------------------------------- 53 | 54 | (program 55 | (function_statement 56 | name: (identifier) 57 | signature: (function_signature 58 | arguments: (arguments)) 59 | body: (function_body 60 | (var_declaration 61 | declarators: (var_declarators 62 | (var 63 | name: (identifier))) 64 | initializers: (expressions 65 | (number))) 66 | (var_declaration 67 | declarators: (var_declarators 68 | (var 69 | name: (identifier))) 70 | initializers: (expressions 71 | (table_constructor 72 | (table_entry 73 | key: (identifier) 74 | value: (anon_function 75 | signature: (function_signature 76 | arguments: (arguments)) 77 | body: (function_body 78 | (var_declaration 79 | declarators: (var_declarators 80 | (var 81 | name: (identifier))) 82 | initializers: (expressions 83 | (number)))))) 84 | (table_entry 85 | key: (identifier) 86 | value: (anon_function 87 | signature: (function_signature 88 | arguments: (arguments)) 89 | body: (function_body))))))))) 90 | 91 | ================================================================================ 92 | A function that returns 93 | ================================================================================ 94 | 95 | local function bar() 96 | local x = "hello" 97 | return x 98 | end 99 | 100 | -------------------------------------------------------------------------------- 101 | 102 | (program 103 | (function_statement 104 | name: (identifier) 105 | signature: (function_signature 106 | arguments: (arguments)) 107 | body: (function_body 108 | (var_declaration 109 | declarators: (var_declarators 110 | (var 111 | name: (identifier))) 112 | initializers: (expressions 113 | (string 114 | content: (string_content)))) 115 | (return_statement 116 | (identifier))))) 117 | 118 | ================================================================================ 119 | A function with args 120 | ================================================================================ 121 | 122 | local function foo(bar, baz) 123 | return bar, baz 124 | end 125 | 126 | -------------------------------------------------------------------------------- 127 | 128 | (program 129 | (function_statement 130 | name: (identifier) 131 | signature: (function_signature 132 | arguments: (arguments 133 | (arg 134 | name: (identifier)) 135 | (arg 136 | name: (identifier)))) 137 | body: (function_body 138 | (return_statement 139 | (identifier) 140 | (identifier))))) 141 | 142 | ================================================================================ 143 | A function with typed args 144 | ================================================================================ 145 | 146 | local function foo(bar: string, baz: number) 147 | return bar, baz 148 | end 149 | 150 | -------------------------------------------------------------------------------- 151 | 152 | (program 153 | (function_statement 154 | name: (identifier) 155 | signature: (function_signature 156 | arguments: (arguments 157 | (arg 158 | name: (identifier) 159 | type: (simple_type 160 | name: (identifier))) 161 | (arg 162 | name: (identifier) 163 | type: (simple_type 164 | name: (identifier))))) 165 | body: (function_body 166 | (return_statement 167 | (identifier) 168 | (identifier))))) 169 | 170 | ================================================================================ 171 | A function with typed returns 172 | ================================================================================ 173 | 174 | local function foo(): string, number 175 | end 176 | 177 | -------------------------------------------------------------------------------- 178 | 179 | (program 180 | (function_statement 181 | name: (identifier) 182 | signature: (function_signature 183 | arguments: (arguments) 184 | return_type: (return_type 185 | (simple_type 186 | name: (identifier)) 187 | (simple_type 188 | name: (identifier)))) 189 | body: (function_body))) 190 | 191 | ================================================================================ 192 | A function in a table/record 193 | ================================================================================ 194 | 195 | function foo.bar() 196 | end 197 | 198 | -------------------------------------------------------------------------------- 199 | 200 | (program 201 | (function_statement 202 | name: (function_name 203 | base: (identifier) 204 | entry: (identifier)) 205 | signature: (function_signature 206 | arguments: (arguments)) 207 | body: (function_body))) 208 | 209 | ================================================================================ 210 | A method in a table/record 211 | ================================================================================ 212 | 213 | function foo:bar() 214 | end 215 | 216 | -------------------------------------------------------------------------------- 217 | 218 | (program 219 | (function_statement 220 | name: (function_name 221 | base: (identifier) 222 | method: (identifier)) 223 | signature: (function_signature 224 | arguments: (arguments)) 225 | body: (function_body))) 226 | 227 | ================================================================================ 228 | Argument with typearg 229 | ================================================================================ 230 | 231 | local function parse_list(ps: ParseState, i: number, list: {T}, close: {string:boolean}, sep: SeparatorMode, parse_item: ParseItem): number, {T} 232 | end 233 | 234 | -------------------------------------------------------------------------------- 235 | 236 | (program 237 | (function_statement 238 | name: (identifier) 239 | signature: (function_signature 240 | typeargs: (typeargs 241 | (typearg name: (identifier))) 242 | arguments: (arguments 243 | (arg 244 | name: (identifier) 245 | type: (simple_type 246 | name: (identifier))) 247 | (arg 248 | name: (identifier) 249 | type: (simple_type 250 | name: (identifier))) 251 | (arg 252 | name: (identifier) 253 | type: (table_type 254 | value_type: (simple_type 255 | name: (identifier)))) 256 | (arg 257 | name: (identifier) 258 | type: (table_type 259 | key_type: (simple_type 260 | name: (identifier)) 261 | value_type: (simple_type 262 | name: (identifier)))) 263 | (arg 264 | name: (identifier) 265 | type: (simple_type 266 | name: (identifier))) 267 | (arg 268 | name: (identifier) 269 | type: (simple_type 270 | name: (identifier) 271 | (typeargs 272 | (simple_type 273 | name: (identifier)))))) 274 | return_type: (return_type 275 | (simple_type 276 | name: (identifier)) 277 | (table_type 278 | value_type: (simple_type 279 | name: (identifier))))) 280 | body: (function_body))) 281 | 282 | ================================================================================ 283 | Variadic argument 284 | ================================================================================ 285 | 286 | local function thing(...: number) 287 | end 288 | 289 | -------------------------------------------------------------------------------- 290 | 291 | (program 292 | (function_statement 293 | name: (identifier) 294 | signature: (function_signature 295 | arguments: (arguments 296 | (varargs 297 | type: (simple_type 298 | name: (identifier))))) 299 | body: (function_body))) 300 | 301 | ================================================================================ 302 | Multiple args with variadic last argument 303 | ================================================================================ 304 | 305 | local function error_in_type(where: Type, msg: string, ...: Type): Error 306 | end 307 | 308 | -------------------------------------------------------------------------------- 309 | 310 | (program 311 | (function_statement 312 | name: (identifier) 313 | signature: (function_signature 314 | arguments: (arguments 315 | (arg 316 | name: (identifier) 317 | type: (simple_type 318 | name: (identifier))) 319 | (arg 320 | name: (identifier) 321 | type: (simple_type 322 | name: (identifier))) 323 | (varargs 324 | type: (simple_type 325 | name: (identifier)))) 326 | return_type: (return_type 327 | (simple_type 328 | name: (identifier)))) 329 | body: (function_body))) 330 | 331 | ================================================================================ 332 | Variadic return 333 | ================================================================================ 334 | 335 | local function thing(): string... 336 | end 337 | 338 | -------------------------------------------------------------------------------- 339 | 340 | (program 341 | (function_statement 342 | name: (identifier) 343 | signature: (function_signature 344 | arguments: (arguments) 345 | return_type: (return_type 346 | (variadic_type 347 | (simple_type 348 | name: (identifier))))) 349 | body: (function_body))) 350 | 351 | ================================================================================ 352 | Function type arguments 353 | ================================================================================ 354 | 355 | local function foo(bar: function(): (number), baz: number) 356 | return bar, baz 357 | end 358 | 359 | -------------------------------------------------------------------------------- 360 | 361 | (program 362 | (function_statement 363 | name: (identifier) 364 | signature: (function_signature 365 | arguments: (arguments 366 | (arg 367 | name: (identifier) 368 | type: (function_type 369 | arguments: (arguments) 370 | return_type: (return_type 371 | (simple_type 372 | name: (identifier))))) 373 | (arg 374 | name: (identifier) 375 | type: (simple_type 376 | name: (identifier))))) 377 | body: (function_body 378 | (return_statement 379 | (identifier) 380 | (identifier))))) 381 | 382 | ================================================================================ 383 | Function with optional arguments 384 | ================================================================================ 385 | 386 | local function foo(_bar: integer, _baz?: number) 387 | end 388 | 389 | -------------------------------------------------------------------------------- 390 | 391 | (program 392 | (function_statement 393 | name: (identifier) 394 | signature: (function_signature 395 | arguments: (arguments 396 | (arg 397 | name: (identifier) 398 | type: (simple_type name: (identifier))) 399 | (arg 400 | name: (identifier) 401 | optional_marker: (optional_marker) 402 | type: (simple_type name: (identifier))))) 403 | body: (function_body))) 404 | -------------------------------------------------------------------------------- /test/corpus/function_types.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | No args, no returns 3 | ================================================================================ 4 | 5 | local foo: function() 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | declarators: (var_declarators 12 | (var 13 | name: (identifier))) 14 | type_annotation: (type_annotation 15 | (function_type 16 | arguments: (arguments))))) 17 | 18 | ================================================================================ 19 | One arg, no returns 20 | ================================================================================ 21 | 22 | local foo: function(string) 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (var_declaration 28 | declarators: (var_declarators 29 | (var 30 | name: (identifier))) 31 | type_annotation: (type_annotation 32 | (function_type 33 | arguments: (arguments 34 | (arg 35 | type: (simple_type 36 | name: (identifier)))))))) 37 | 38 | ================================================================================ 39 | No args, one return 40 | ================================================================================ 41 | 42 | local foo: function(): string 43 | 44 | -------------------------------------------------------------------------------- 45 | 46 | (program 47 | (var_declaration 48 | declarators: (var_declarators 49 | (var 50 | name: (identifier))) 51 | type_annotation: (type_annotation 52 | (function_type 53 | arguments: (arguments) 54 | return_type: (return_type 55 | (simple_type 56 | name: (identifier))))))) 57 | 58 | ================================================================================ 59 | One arg, one return 60 | ================================================================================ 61 | 62 | local foo: function(number): string 63 | 64 | -------------------------------------------------------------------------------- 65 | 66 | (program 67 | (var_declaration 68 | declarators: (var_declarators 69 | (var 70 | name: (identifier))) 71 | type_annotation: (type_annotation 72 | (function_type 73 | arguments: (arguments 74 | (arg 75 | type: (simple_type 76 | name: (identifier)))) 77 | return_type: (return_type 78 | (simple_type 79 | name: (identifier))))))) 80 | 81 | ================================================================================ 82 | Multiple args, no return 83 | ================================================================================ 84 | 85 | local foo: function(number, {string}, string) 86 | 87 | -------------------------------------------------------------------------------- 88 | 89 | (program 90 | (var_declaration 91 | declarators: (var_declarators 92 | (var 93 | name: (identifier))) 94 | type_annotation: (type_annotation 95 | (function_type 96 | arguments: (arguments 97 | (arg 98 | type: (simple_type 99 | name: (identifier))) 100 | (arg 101 | type: (table_type 102 | value_type: (simple_type 103 | name: (identifier)))) 104 | (arg 105 | type: (simple_type 106 | name: (identifier)))))))) 107 | 108 | ================================================================================ 109 | No args, multiple returns 110 | ================================================================================ 111 | 112 | local foo: function(): string, {number}, number, thread 113 | 114 | -------------------------------------------------------------------------------- 115 | 116 | (program 117 | (var_declaration 118 | declarators: (var_declarators 119 | (var 120 | name: (identifier))) 121 | type_annotation: (type_annotation 122 | (function_type 123 | arguments: (arguments) 124 | return_type: (return_type 125 | (simple_type 126 | name: (identifier)) 127 | (table_type 128 | value_type: (simple_type 129 | name: (identifier))) 130 | (simple_type 131 | name: (identifier)) 132 | (simple_type 133 | name: (identifier))))))) 134 | 135 | ================================================================================ 136 | Multiple args, multiple returns 137 | ================================================================================ 138 | 139 | local foo: function(number, {string}, string): string, {number}, number, thread 140 | 141 | -------------------------------------------------------------------------------- 142 | 143 | (program 144 | (var_declaration 145 | declarators: (var_declarators 146 | (var 147 | name: (identifier))) 148 | type_annotation: (type_annotation 149 | (function_type 150 | arguments: (arguments 151 | (arg 152 | type: (simple_type 153 | name: (identifier))) 154 | (arg 155 | type: (table_type 156 | value_type: (simple_type 157 | name: (identifier)))) 158 | (arg 159 | type: (simple_type 160 | name: (identifier)))) 161 | return_type: (return_type 162 | (simple_type 163 | name: (identifier)) 164 | (table_type 165 | value_type: (simple_type 166 | name: (identifier))) 167 | (simple_type 168 | name: (identifier)) 169 | (simple_type 170 | name: (identifier))))))) 171 | 172 | ================================================================================ 173 | Named argument 174 | ================================================================================ 175 | 176 | local foo: function(bar: number) 177 | 178 | -------------------------------------------------------------------------------- 179 | 180 | (program 181 | (var_declaration 182 | declarators: (var_declarators 183 | (var 184 | name: (identifier))) 185 | type_annotation: (type_annotation 186 | (function_type 187 | arguments: (arguments 188 | (arg 189 | name: (identifier) 190 | type: (simple_type 191 | name: (identifier)))))))) 192 | 193 | ================================================================================ 194 | Named arguments 195 | ================================================================================ 196 | 197 | local foo: function(bar: number, baz: {string}) 198 | 199 | -------------------------------------------------------------------------------- 200 | 201 | (program 202 | (var_declaration 203 | declarators: (var_declarators 204 | (var 205 | name: (identifier))) 206 | type_annotation: (type_annotation 207 | (function_type 208 | arguments: (arguments 209 | (arg 210 | name: (identifier) 211 | type: (simple_type 212 | name: (identifier))) 213 | (arg 214 | name: (identifier) 215 | type: (table_type 216 | value_type: (simple_type 217 | name: (identifier))))))))) 218 | 219 | ================================================================================ 220 | Variadic args 221 | ================================================================================ 222 | 223 | local foo: function(...: string) 224 | 225 | -------------------------------------------------------------------------------- 226 | 227 | (program 228 | (var_declaration 229 | declarators: (var_declarators 230 | (var 231 | name: (identifier))) 232 | type_annotation: (type_annotation 233 | (function_type 234 | arguments: (arguments 235 | (varargs 236 | type: (simple_type 237 | name: (identifier)))))))) 238 | 239 | ================================================================================ 240 | Args + variadic last arg 241 | ================================================================================ 242 | 243 | local foo: function(number, string, ...: string) 244 | 245 | -------------------------------------------------------------------------------- 246 | 247 | (program 248 | (var_declaration 249 | declarators: (var_declarators 250 | (var 251 | name: (identifier))) 252 | type_annotation: (type_annotation 253 | (function_type 254 | arguments: (arguments 255 | (arg 256 | type: (simple_type 257 | name: (identifier))) 258 | (arg 259 | type: (simple_type 260 | name: (identifier))) 261 | (varargs 262 | type: (simple_type 263 | name: (identifier)))))))) 264 | 265 | ================================================================================ 266 | Variadic return 267 | ================================================================================ 268 | 269 | local foo: function(): string... 270 | 271 | -------------------------------------------------------------------------------- 272 | 273 | (program 274 | (var_declaration 275 | declarators: (var_declarators 276 | (var 277 | name: (identifier))) 278 | type_annotation: (type_annotation 279 | (function_type 280 | arguments: (arguments) 281 | return_type: (return_type 282 | (variadic_type 283 | (simple_type 284 | name: (identifier)))))))) 285 | -------------------------------------------------------------------------------- /test/corpus/generic_functions.txt: -------------------------------------------------------------------------------- 1 | 2 | ============================== 3 | Generic anonymous function 4 | ============================== 5 | 6 | return function() 7 | 8 | end 9 | 10 | --- 11 | 12 | (program 13 | (return_statement 14 | (anon_function 15 | signature: (function_signature 16 | typeargs: (typeargs 17 | (typearg 18 | name: (identifier))) 19 | arguments: (arguments)) 20 | body: (function_body)))) 21 | 22 | ============================== 23 | Generic named function 24 | ============================== 25 | 26 | local function foo() 27 | 28 | end 29 | 30 | --- 31 | 32 | (program (function_statement 33 | name: (identifier) 34 | signature: (function_signature 35 | typeargs: (typeargs 36 | (typearg 37 | name: (identifier))) 38 | arguments: (arguments)) 39 | body: (function_body))) 40 | 41 | ============================== 42 | Many typeargs 43 | ============================== 44 | 45 | local function foo() 46 | 47 | end 48 | 49 | --- 50 | 51 | (program 52 | (function_statement 53 | name: (identifier) 54 | signature: (function_signature 55 | typeargs: (typeargs 56 | (typearg name: (identifier)) 57 | (typearg name: (identifier)) 58 | (typearg name: (identifier)) 59 | (typearg name: (identifier)) 60 | (typearg name: (identifier)) 61 | (typearg name: (identifier))) 62 | arguments: (arguments)) 63 | body: (function_body))) 64 | 65 | ============================== 66 | Typearg with is clause 67 | ============================== 68 | 69 | local function foo() 70 | end 71 | 72 | ------------------------------ 73 | 74 | (program 75 | (function_statement 76 | name: (identifier) 77 | signature: (function_signature 78 | typeargs: (typeargs 79 | (typearg 80 | name: (identifier) 81 | constraint: (simple_type 82 | name: (identifier)))) 83 | arguments: (arguments)) 84 | body: (function_body))) 85 | -------------------------------------------------------------------------------- /test/corpus/goto.txt: -------------------------------------------------------------------------------- 1 | 2 | ============================== 3 | Label 4 | ============================== 5 | 6 | ::hello:: 7 | 8 | --- 9 | 10 | (program (label)) 11 | 12 | ============================== 13 | Goto 14 | ============================== 15 | 16 | goto nowhere 17 | 18 | --- 19 | 20 | (program (goto (identifier))) 21 | 22 | ============================== 23 | Goto + Label 24 | ============================== 25 | 26 | ::somewhere:: 27 | goto somewhere 28 | 29 | --- 30 | 31 | (program (label) (goto (identifier))) 32 | -------------------------------------------------------------------------------- /test/corpus/if_statements.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Basic if 3 | ================================================================================ 4 | 5 | if thing then 6 | 7 | end 8 | 9 | -------------------------------------------------------------------------------- 10 | 11 | (program 12 | (if_statement 13 | condition: (identifier))) 14 | 15 | ================================================================================ 16 | Basic if+else 17 | ================================================================================ 18 | 19 | if thing then 20 | 21 | else 22 | 23 | end 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | (program 28 | (if_statement 29 | condition: (identifier) 30 | (else_block))) 31 | 32 | ================================================================================ 33 | Basic if+elseif 34 | ================================================================================ 35 | 36 | if thing then 37 | 38 | elseif other_thing then 39 | 40 | end 41 | 42 | -------------------------------------------------------------------------------- 43 | 44 | (program 45 | (if_statement 46 | condition: (identifier) 47 | (elseif_block 48 | condition: (identifier)))) 49 | 50 | ================================================================================ 51 | Basic if+multiple elseif 52 | ================================================================================ 53 | 54 | if thing then 55 | elseif other_thing1 then 56 | elseif other_thing2 then 57 | elseif other_thing3 then 58 | end 59 | 60 | -------------------------------------------------------------------------------- 61 | 62 | (program 63 | (if_statement 64 | condition: (identifier) 65 | (elseif_block 66 | condition: (identifier)) 67 | (elseif_block 68 | condition: (identifier)) 69 | (elseif_block 70 | condition: (identifier)))) 71 | 72 | ================================================================================ 73 | Basic if+elseif+else 74 | ================================================================================ 75 | 76 | if thing then 77 | elseif other_thing then 78 | else 79 | end 80 | 81 | -------------------------------------------------------------------------------- 82 | 83 | (program 84 | (if_statement 85 | condition: (identifier) 86 | (elseif_block 87 | condition: (identifier)) 88 | (else_block))) 89 | 90 | ================================================================================ 91 | Basic if+elseif+else with statements 92 | ================================================================================ 93 | 94 | if thing then 95 | local x = 2 96 | elseif other_thing then 97 | local y = "hey" 98 | else 99 | local z = {} 100 | end 101 | 102 | -------------------------------------------------------------------------------- 103 | 104 | (program 105 | (if_statement 106 | condition: (identifier) 107 | (var_declaration 108 | declarators: (var_declarators 109 | (var 110 | name: (identifier))) 111 | initializers: (expressions 112 | (number))) 113 | (elseif_block 114 | condition: (identifier) 115 | (var_declaration 116 | declarators: (var_declarators 117 | (var 118 | name: (identifier))) 119 | initializers: (expressions 120 | (string 121 | content: (string_content))))) 122 | (else_block 123 | (var_declaration 124 | declarators: (var_declarators 125 | (var 126 | name: (identifier))) 127 | initializers: (expressions 128 | (table_constructor)))))) 129 | -------------------------------------------------------------------------------- /test/corpus/indexing.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Indexing with identifier 3 | ================================================================================ 4 | 5 | local a = b[c] 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | (var_declarators 12 | (var 13 | (identifier))) 14 | (expressions 15 | (index 16 | (identifier) 17 | (identifier))))) 18 | 19 | ================================================================================ 20 | Assigning to table entry 21 | ================================================================================ 22 | 23 | a[b] = c 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | (program 28 | (var_assignment 29 | (assignment_variables 30 | (var 31 | (index 32 | (identifier) 33 | (identifier)))) 34 | (expressions 35 | (identifier)))) 36 | 37 | ================================================================================ 38 | Indexing with string 39 | ================================================================================ 40 | 41 | local a = b["hi"] 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | (program 46 | (var_declaration 47 | (var_declarators 48 | (var 49 | (identifier))) 50 | (expressions 51 | (index 52 | (identifier) 53 | (string 54 | (string_content)))))) 55 | 56 | ================================================================================ 57 | Multiple indexing 58 | ================================================================================ 59 | 60 | local a = b["hi"][5] 61 | 62 | -------------------------------------------------------------------------------- 63 | 64 | (program 65 | (var_declaration 66 | (var_declarators 67 | (var 68 | (identifier))) 69 | (expressions 70 | (index 71 | (index 72 | (identifier) 73 | (string 74 | (string_content))) 75 | (number))))) 76 | 77 | ================================================================================ 78 | Dot indexing 79 | ================================================================================ 80 | 81 | local a = b.c 82 | 83 | -------------------------------------------------------------------------------- 84 | 85 | (program 86 | (var_declaration 87 | (var_declarators 88 | (var 89 | (identifier))) 90 | (expressions 91 | (index 92 | (identifier) 93 | (identifier))))) 94 | 95 | ================================================================================ 96 | Bracket and dot indexing 97 | ================================================================================ 98 | 99 | local a = b.c[d].e.f[g] 100 | 101 | -------------------------------------------------------------------------------- 102 | 103 | (program 104 | (var_declaration 105 | (var_declarators 106 | (var 107 | (identifier))) 108 | (expressions 109 | (index 110 | (index 111 | (index 112 | (index 113 | (index 114 | (identifier) 115 | (identifier)) 116 | (identifier)) 117 | (identifier)) 118 | (identifier)) 119 | (identifier))))) 120 | 121 | ================================================================================ 122 | Colon indexing 123 | ================================================================================ 124 | 125 | local a = b:c() 126 | 127 | -------------------------------------------------------------------------------- 128 | 129 | (program 130 | (var_declaration 131 | declarators: (var_declarators 132 | (var 133 | name: (identifier))) 134 | initializers: (expressions 135 | (function_call 136 | called_object: (method_index 137 | (identifier) 138 | key: (identifier)) 139 | arguments: (arguments))))) 140 | 141 | ================================================================================ 142 | The whole dang thing 143 | ================================================================================ 144 | 145 | local a = b[c].d.e[f]:g() 146 | 147 | -------------------------------------------------------------------------------- 148 | 149 | (program 150 | (var_declaration 151 | declarators: (var_declarators 152 | (var 153 | name: (identifier))) 154 | initializers: (expressions 155 | (function_call 156 | called_object: (method_index 157 | (index 158 | (index 159 | (index 160 | (index 161 | (identifier) 162 | expr_key: (identifier)) 163 | key: (identifier)) 164 | key: (identifier)) 165 | expr_key: (identifier)) 166 | key: (identifier)) 167 | arguments: (arguments))))) 168 | -------------------------------------------------------------------------------- /test/corpus/interface_block.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty interface 3 | ================================================================================ 4 | 5 | local type foo = interface 6 | end 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (program 11 | (type_declaration 12 | name: (identifier) 13 | value: (anon_interface 14 | interface_body: (interface_body)))) 15 | 16 | ================================================================================ 17 | Empty interface (shorthand) 18 | ================================================================================ 19 | 20 | local interface foo 21 | end 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (interface_declaration 27 | name: (identifier) 28 | interface_body: (interface_body))) 29 | 30 | ================================================================================ 31 | Interface with stuff 32 | ================================================================================ 33 | 34 | local type foo = interface 35 | bar: {number} 36 | baz: string 37 | end 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (program 42 | (type_declaration 43 | name: (identifier) 44 | value: (anon_interface 45 | interface_body: (interface_body 46 | (field 47 | key: (identifier) 48 | type: (table_type 49 | value_type: (simple_type 50 | name: (identifier)))) 51 | (field 52 | key: (identifier) 53 | type: (simple_type 54 | name: (identifier))))))) 55 | 56 | ================================================================================ 57 | Arrayinterface with stuff 58 | ================================================================================ 59 | 60 | local type foo = interface 61 | {thread} 62 | bar: {number} 63 | baz: string 64 | end 65 | 66 | -------------------------------------------------------------------------------- 67 | 68 | (program 69 | (type_declaration 70 | name: (identifier) 71 | value: (anon_interface 72 | interface_body: (interface_body 73 | (record_array_type 74 | (simple_type 75 | name: (identifier))) 76 | (field 77 | key: (identifier) 78 | type: (table_type 79 | value_type: (simple_type 80 | name: (identifier)))) 81 | (field 82 | key: (identifier) 83 | type: (simple_type 84 | name: (identifier))))))) 85 | 86 | ================================================================================ 87 | Nested interfaces 88 | ================================================================================ 89 | 90 | local type foo = interface 91 | type bar = interface 92 | x: number 93 | end 94 | baz: bar 95 | end 96 | 97 | -------------------------------------------------------------------------------- 98 | 99 | (program 100 | (type_declaration 101 | name: (identifier) 102 | value: (anon_interface 103 | interface_body: (interface_body 104 | (typedef 105 | name: (identifier) 106 | value: (anon_interface 107 | interface_body: (interface_body 108 | (field 109 | key: (identifier) 110 | type: (simple_type 111 | name: (identifier)))))) 112 | (field 113 | key: (identifier) 114 | type: (simple_type 115 | name: (identifier))))))) 116 | 117 | ================================================================================ 118 | Generic interface 119 | ================================================================================ 120 | 121 | local type foo = interface 122 | foo: T 123 | end 124 | 125 | -------------------------------------------------------------------------------- 126 | 127 | (program 128 | (type_declaration 129 | name: (identifier) 130 | value: (anon_interface 131 | (typeargs 132 | (typearg name: (identifier))) 133 | interface_body: (interface_body 134 | (field 135 | key: (identifier) 136 | type: (simple_type 137 | name: (identifier))))))) 138 | 139 | ================================================================================ 140 | Interface with a 'type' entry 141 | ================================================================================ 142 | 143 | local type foo = interface 144 | type: number 145 | end 146 | 147 | -------------------------------------------------------------------------------- 148 | 149 | (program 150 | (type_declaration 151 | name: (identifier) 152 | value: (anon_interface 153 | interface_body: (interface_body 154 | (field 155 | key: (identifier) 156 | type: (simple_type 157 | name: (identifier))))))) 158 | 159 | ================================================================================ 160 | Interface with a 'type' entry and types 161 | ================================================================================ 162 | 163 | local type foo = interface 164 | type: number 165 | type bar = interface 166 | end 167 | type baz = enum 168 | "foo" "bar" 169 | end 170 | end 171 | 172 | -------------------------------------------------------------------------------- 173 | 174 | (program 175 | (type_declaration 176 | name: (identifier) 177 | value: (anon_interface 178 | interface_body: (interface_body 179 | (field 180 | key: (identifier) 181 | type: (simple_type 182 | name: (identifier))) 183 | (typedef 184 | name: (identifier) 185 | value: (anon_interface 186 | interface_body: (interface_body))) 187 | (typedef 188 | name: (identifier) 189 | value: (enum_body 190 | (string 191 | content: (string_content)) 192 | (string 193 | content: (string_content)))))))) 194 | 195 | ================================================================================ 196 | Nested interface shorthand syntax 197 | ================================================================================ 198 | 199 | local interface Foo 200 | interface Bar 201 | end 202 | end 203 | 204 | -------------------------------------------------------------------------------- 205 | 206 | (program 207 | (interface_declaration 208 | name: (identifier) 209 | interface_body: (interface_body 210 | (interface_declaration 211 | name: (identifier) 212 | interface_body: (interface_body))))) 213 | 214 | ================================================================================ 215 | Nested enum shorthand syntax 216 | ================================================================================ 217 | 218 | local interface Foo 219 | enum Bar 220 | "foo" "bar" 221 | end 222 | end 223 | 224 | -------------------------------------------------------------------------------- 225 | 226 | (program 227 | (interface_declaration 228 | name: (identifier) 229 | interface_body: (interface_body 230 | (enum_declaration 231 | name: (identifier) 232 | enum_body: (enum_body 233 | (string 234 | content: (string_content)) 235 | (string 236 | content: (string_content))))))) 237 | 238 | ================================================================================ 239 | Interface with a 'interface' entry 240 | ================================================================================ 241 | 242 | local interface Foo 243 | interface: number 244 | end 245 | 246 | -------------------------------------------------------------------------------- 247 | 248 | (program 249 | (interface_declaration 250 | name: (identifier) 251 | interface_body: (interface_body 252 | (field 253 | key: (identifier) 254 | type: (simple_type 255 | name: (identifier)))))) 256 | 257 | ================================================================================ 258 | Interface with a 'enum' entry 259 | ================================================================================ 260 | 261 | local interface Foo 262 | enum: number 263 | end 264 | 265 | -------------------------------------------------------------------------------- 266 | 267 | (program 268 | (interface_declaration 269 | name: (identifier) 270 | interface_body: (interface_body 271 | (field 272 | key: (identifier) 273 | type: (simple_type 274 | name: (identifier)))))) 275 | 276 | ================================================================================ 277 | Interface with ['entry'] 278 | ================================================================================ 279 | 280 | local interface Foo 281 | ["things"]: number 282 | end 283 | 284 | -------------------------------------------------------------------------------- 285 | 286 | (program 287 | (interface_declaration 288 | name: (identifier) 289 | interface_body: (interface_body 290 | (field 291 | key: (string 292 | content: (string_content)) 293 | type: (simple_type 294 | name: (identifier)))))) 295 | 296 | ================================================================================ 297 | Nested generic interface shorthand 298 | ================================================================================ 299 | 300 | local interface Foo 301 | interface Bar 302 | end 303 | end 304 | 305 | -------------------------------------------------------------------------------- 306 | 307 | (program 308 | (interface_declaration 309 | name: (identifier) 310 | interface_body: (interface_body 311 | (interface_declaration 312 | name: (identifier) 313 | typeargs: (typeargs 314 | (typearg name: (identifier))) 315 | interface_body: (interface_body))))) 316 | 317 | ================================================================================ 318 | Userdata interface 319 | ================================================================================ 320 | 321 | local interface Foo 322 | userdata 323 | end 324 | 325 | -------------------------------------------------------------------------------- 326 | 327 | (program 328 | (interface_declaration 329 | name: (identifier) 330 | interface_body: (interface_body 331 | (userdata)))) 332 | 333 | ================================================================================ 334 | Interface with metamethod 335 | ================================================================================ 336 | 337 | local interface Foo 338 | metamethod __call: number 339 | end 340 | 341 | -------------------------------------------------------------------------------- 342 | 343 | (program 344 | (interface_declaration 345 | name: (identifier) 346 | interface_body: (interface_body 347 | metamethod: (metamethod 348 | name: (identifier) 349 | type: (simple_type 350 | name: (identifier)))))) 351 | 352 | ================================================================================ 353 | Interface with is clause 354 | ================================================================================ 355 | 356 | local interface Foo is Bar 357 | end 358 | 359 | -------------------------------------------------------------------------------- 360 | 361 | (program 362 | (interface_declaration 363 | name: (identifier) 364 | interface_body: (interface_body 365 | is_types: (simple_type 366 | name: (identifier))))) 367 | 368 | ================================================================================ 369 | Interface with is and where clause 370 | ================================================================================ 371 | 372 | local interface Foo is Bar where self.blah 373 | end 374 | 375 | -------------------------------------------------------------------------------- 376 | 377 | (program 378 | (interface_declaration 379 | name: (identifier) 380 | interface_body: (interface_body 381 | is_types: (simple_type 382 | name: (identifier)) 383 | where: (index 384 | (identifier) 385 | key: (identifier))))) 386 | 387 | -------------------------------------------------------------------------------- /test/corpus/macroexp.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | No arguments 3 | ================================================================================ 4 | 5 | local macroexp foo() 6 | return 1 7 | end 8 | 9 | -------------------------------------------------------------------------------- 10 | 11 | (program 12 | (macroexp_statement 13 | name: (identifier) 14 | signature: (macroexp_signature 15 | arguments: (arguments)) 16 | body: (macroexp_body 17 | (return_statement 18 | (number))))) 19 | 20 | ================================================================================ 21 | One argument 22 | ================================================================================ 23 | 24 | local macroexp bar(hello: integer) 25 | return hello + 1 26 | end 27 | 28 | -------------------------------------------------------------------------------- 29 | 30 | (program 31 | (macroexp_statement 32 | name: (identifier) 33 | signature: (macroexp_signature 34 | arguments: (arguments 35 | (arg 36 | name: (identifier) 37 | type: (simple_type 38 | name: (identifier))))) 39 | body: (macroexp_body 40 | (return_statement 41 | (bin_op 42 | left: (identifier) 43 | op: (op) 44 | right: (number)))))) 45 | 46 | ================================================================================ 47 | In a record 48 | ================================================================================ 49 | 50 | local record Foo 51 | macroexp bar(a: integer, b: integer): integer 52 | return a - b 53 | end 54 | end 55 | 56 | -------------------------------------------------------------------------------- 57 | 58 | (program 59 | (record_declaration 60 | name: (identifier) 61 | record_body: (record_body 62 | (macroexp_declaration 63 | name: (identifier) 64 | signature: (macroexp_signature 65 | arguments: (arguments 66 | (arg 67 | name: (identifier) 68 | type: (simple_type name: (identifier))) 69 | (arg 70 | name: (identifier) 71 | type: (simple_type name: (identifier)))) 72 | return_type: (return_type (simple_type name: (identifier)))) 73 | body: (macroexp_body 74 | (return_statement 75 | (bin_op left: (identifier) op: (op) right: (identifier)))))))) 76 | -------------------------------------------------------------------------------- /test/corpus/numbers.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Floats 3 | ================================================================================ 4 | 5 | local x = 4.63 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | (var_declarators 12 | (var 13 | (identifier))) 14 | (expressions 15 | (number)))) 16 | 17 | ================================================================================ 18 | Hex number 19 | ================================================================================ 20 | 21 | local x = 0xf22 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (var_declaration 27 | (var_declarators 28 | (var 29 | (identifier))) 30 | (expressions 31 | (number)))) 32 | 33 | ================================================================================ 34 | Hex float 35 | ================================================================================ 36 | 37 | local x = 0xf22.fffeec1 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (program 42 | (var_declaration 43 | (var_declarators 44 | (var 45 | (identifier))) 46 | (expressions 47 | (number)))) 48 | 49 | ================================================================================ 50 | Exponent 51 | ================================================================================ 52 | 53 | local x = 3e2 54 | 55 | -------------------------------------------------------------------------------- 56 | 57 | (program 58 | (var_declaration 59 | (var_declarators 60 | (var 61 | (identifier))) 62 | (expressions 63 | (number)))) 64 | 65 | ================================================================================ 66 | Hex Exponent 67 | ================================================================================ 68 | 69 | local x = 0xfp10 70 | 71 | -------------------------------------------------------------------------------- 72 | 73 | (program 74 | (var_declaration 75 | (var_declarators 76 | (var 77 | (identifier))) 78 | (expressions 79 | (number)))) 80 | -------------------------------------------------------------------------------- /test/corpus/operators.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Basic arithmetic 3 | ================================================================================ 4 | 5 | return 3 + 3 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (return_statement 11 | (bin_op 12 | left: (number) 13 | op: (op) 14 | right: (number)))) 15 | 16 | ================================================================================ 17 | Basic precedence 18 | ================================================================================ 19 | 20 | return 3 + 3 * 2 21 | 22 | -------------------------------------------------------------------------------- 23 | 24 | (program 25 | (return_statement 26 | (bin_op 27 | left: (number) 28 | op: (op) 29 | right: (bin_op 30 | left: (number) 31 | op: (op) 32 | right: (number))))) 33 | 34 | ================================================================================ 35 | A bunch of precedence 36 | ================================================================================ 37 | 38 | return 4 as string .. 5 as string / 2 + {} 39 | 40 | -------------------------------------------------------------------------------- 41 | 42 | (program 43 | (return_statement 44 | (bin_op 45 | left: (type_cast 46 | (number) 47 | (simple_type 48 | name: (identifier))) 49 | op: (op) 50 | right: (bin_op 51 | left: (bin_op 52 | left: (type_cast 53 | (number) 54 | (simple_type 55 | name: (identifier))) 56 | op: (op) 57 | right: (number)) 58 | op: (op) 59 | right: (table_constructor))))) 60 | -------------------------------------------------------------------------------- /test/corpus/parenthesized.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Parenthesized Expression 3 | ================================================================================ 4 | 5 | print((1)) 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (function_call 11 | called_object: (identifier) 12 | arguments: (arguments 13 | (parenthesized_expression 14 | (number))))) 15 | 16 | ================================================================================ 17 | Very Parenthesized Expression 18 | ================================================================================ 19 | 20 | print(((((1))))) 21 | 22 | -------------------------------------------------------------------------------- 23 | 24 | (program 25 | (function_call 26 | called_object: (identifier) 27 | arguments: (arguments 28 | (parenthesized_expression 29 | (parenthesized_expression 30 | (parenthesized_expression 31 | (parenthesized_expression 32 | (number)))))))) 33 | -------------------------------------------------------------------------------- /test/corpus/record_block.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty record 3 | ================================================================================ 4 | 5 | local type foo = record 6 | end 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (program 11 | (type_declaration 12 | name: (identifier) 13 | value: (anon_record 14 | record_body: (record_body)))) 15 | 16 | ================================================================================ 17 | Empty record (shorthand) 18 | ================================================================================ 19 | 20 | local record foo 21 | end 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (record_declaration 27 | name: (identifier) 28 | record_body: (record_body))) 29 | 30 | ================================================================================ 31 | Record with stuff 32 | ================================================================================ 33 | 34 | local type foo = record 35 | bar: {number} 36 | baz: string 37 | end 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (program 42 | (type_declaration 43 | name: (identifier) 44 | value: (anon_record 45 | record_body: (record_body 46 | (field 47 | key: (identifier) 48 | type: (table_type 49 | value_type: (simple_type 50 | name: (identifier)))) 51 | (field 52 | key: (identifier) 53 | type: (simple_type 54 | name: (identifier))))))) 55 | 56 | ================================================================================ 57 | Arrayrecord with stuff 58 | ================================================================================ 59 | 60 | local type foo = record 61 | {thread} 62 | bar: {number} 63 | baz: string 64 | end 65 | 66 | -------------------------------------------------------------------------------- 67 | 68 | (program 69 | (type_declaration 70 | name: (identifier) 71 | value: (anon_record 72 | record_body: (record_body 73 | (record_array_type 74 | (simple_type 75 | name: (identifier))) 76 | (field 77 | key: (identifier) 78 | type: (table_type 79 | value_type: (simple_type 80 | name: (identifier)))) 81 | (field 82 | key: (identifier) 83 | type: (simple_type 84 | name: (identifier))))))) 85 | 86 | ================================================================================ 87 | Nested records 88 | ================================================================================ 89 | 90 | local type foo = record 91 | type bar = record 92 | x: number 93 | end 94 | baz: bar 95 | end 96 | 97 | -------------------------------------------------------------------------------- 98 | 99 | (program 100 | (type_declaration 101 | name: (identifier) 102 | value: (anon_record 103 | record_body: (record_body 104 | (typedef 105 | name: (identifier) 106 | value: (anon_record 107 | record_body: (record_body 108 | (field 109 | key: (identifier) 110 | type: (simple_type 111 | name: (identifier)))))) 112 | (field 113 | key: (identifier) 114 | type: (simple_type 115 | name: (identifier))))))) 116 | 117 | ================================================================================ 118 | Generic record 119 | ================================================================================ 120 | 121 | local type foo = record 122 | foo: T 123 | end 124 | 125 | -------------------------------------------------------------------------------- 126 | 127 | (program 128 | (type_declaration 129 | name: (identifier) 130 | value: (anon_record 131 | (typeargs 132 | (typearg 133 | name: (identifier))) 134 | record_body: (record_body 135 | (field 136 | key: (identifier) 137 | type: (simple_type 138 | name: (identifier))))))) 139 | 140 | ================================================================================ 141 | Record with a 'type' entry 142 | ================================================================================ 143 | 144 | local type foo = record 145 | type: number 146 | end 147 | 148 | -------------------------------------------------------------------------------- 149 | 150 | (program 151 | (type_declaration 152 | name: (identifier) 153 | value: (anon_record 154 | record_body: (record_body 155 | (field 156 | key: (identifier) 157 | type: (simple_type 158 | name: (identifier))))))) 159 | 160 | ================================================================================ 161 | Record with a 'type' entry and types 162 | ================================================================================ 163 | 164 | local type foo = record 165 | type: number 166 | type bar = record 167 | end 168 | type baz = enum 169 | "foo" "bar" 170 | end 171 | end 172 | 173 | -------------------------------------------------------------------------------- 174 | 175 | (program 176 | (type_declaration 177 | name: (identifier) 178 | value: (anon_record 179 | record_body: (record_body 180 | (field 181 | key: (identifier) 182 | type: (simple_type 183 | name: (identifier))) 184 | (typedef 185 | name: (identifier) 186 | value: (anon_record 187 | record_body: (record_body))) 188 | (typedef 189 | name: (identifier) 190 | value: (enum_body 191 | (string 192 | content: (string_content)) 193 | (string 194 | content: (string_content)))))))) 195 | 196 | ================================================================================ 197 | Nested record shorthand syntax 198 | ================================================================================ 199 | 200 | local record Foo 201 | record Bar 202 | end 203 | end 204 | 205 | -------------------------------------------------------------------------------- 206 | 207 | (program 208 | (record_declaration 209 | name: (identifier) 210 | record_body: (record_body 211 | (record_declaration 212 | name: (identifier) 213 | record_body: (record_body))))) 214 | 215 | ================================================================================ 216 | Nested enum shorthand syntax 217 | ================================================================================ 218 | 219 | local record Foo 220 | enum Bar 221 | "foo" "bar" 222 | end 223 | end 224 | 225 | -------------------------------------------------------------------------------- 226 | 227 | (program 228 | (record_declaration 229 | name: (identifier) 230 | record_body: (record_body 231 | (enum_declaration 232 | name: (identifier) 233 | enum_body: (enum_body 234 | (string 235 | content: (string_content)) 236 | (string 237 | content: (string_content))))))) 238 | 239 | ================================================================================ 240 | Record with a 'record' entry 241 | ================================================================================ 242 | 243 | local record Foo 244 | record: number 245 | end 246 | 247 | -------------------------------------------------------------------------------- 248 | 249 | (program 250 | (record_declaration 251 | name: (identifier) 252 | record_body: (record_body 253 | (field 254 | key: (identifier) 255 | type: (simple_type 256 | name: (identifier)))))) 257 | 258 | ================================================================================ 259 | Record with a 'enum' entry 260 | ================================================================================ 261 | 262 | local record Foo 263 | enum: number 264 | end 265 | 266 | -------------------------------------------------------------------------------- 267 | 268 | (program 269 | (record_declaration 270 | name: (identifier) 271 | record_body: (record_body 272 | (field 273 | key: (identifier) 274 | type: (simple_type 275 | name: (identifier)))))) 276 | 277 | ================================================================================ 278 | Record with ['entry'] 279 | ================================================================================ 280 | 281 | local record Foo 282 | ["things"]: number 283 | end 284 | 285 | -------------------------------------------------------------------------------- 286 | 287 | (program 288 | (record_declaration 289 | name: (identifier) 290 | record_body: (record_body 291 | (field 292 | key: (string 293 | content: (string_content)) 294 | type: (simple_type 295 | name: (identifier)))))) 296 | 297 | ================================================================================ 298 | Nested generic record shorthand 299 | ================================================================================ 300 | 301 | local record Foo 302 | record Bar 303 | end 304 | end 305 | 306 | -------------------------------------------------------------------------------- 307 | 308 | (program 309 | (record_declaration 310 | name: (identifier) 311 | record_body: (record_body 312 | (record_declaration 313 | name: (identifier) 314 | typeargs: (typeargs 315 | (typearg name: (identifier))) 316 | record_body: (record_body))))) 317 | 318 | ================================================================================ 319 | Userdata record 320 | ================================================================================ 321 | 322 | local record Foo 323 | userdata 324 | end 325 | 326 | -------------------------------------------------------------------------------- 327 | 328 | (program 329 | (record_declaration 330 | name: (identifier) 331 | record_body: (record_body 332 | (userdata)))) 333 | 334 | ================================================================================ 335 | Record with metamethod 336 | ================================================================================ 337 | 338 | local record Foo 339 | metamethod __call: number 340 | end 341 | 342 | -------------------------------------------------------------------------------- 343 | 344 | (program 345 | (record_declaration 346 | name: (identifier) 347 | record_body: (record_body 348 | metamethod: (metamethod 349 | name: (identifier) 350 | type: (simple_type 351 | name: (identifier)))))) 352 | 353 | ================================================================================ 354 | Record with is clause 355 | ================================================================================ 356 | 357 | local record Foo is Bar 358 | end 359 | 360 | -------------------------------------------------------------------------------- 361 | 362 | (program 363 | (record_declaration 364 | name: (identifier) 365 | record_body: (record_body 366 | is_types: (simple_type 367 | name: (identifier))))) 368 | 369 | ================================================================================ 370 | Record with is and where clause 371 | ================================================================================ 372 | 373 | local record Foo is Bar where self.blah 374 | end 375 | 376 | -------------------------------------------------------------------------------- 377 | 378 | (program 379 | (record_declaration 380 | name: (identifier) 381 | record_body: (record_body 382 | is_types: (simple_type 383 | name: (identifier)) 384 | where: (index 385 | (identifier) 386 | key: (identifier))))) 387 | -------------------------------------------------------------------------------- /test/corpus/return.txt: -------------------------------------------------------------------------------- 1 | ============================== 2 | Empty 3 | ============================== 4 | 5 | return 6 | 7 | --- 8 | 9 | (program (return_statement)) 10 | 11 | ============================== 12 | One expression 13 | ============================== 14 | 15 | return 4 16 | 17 | --- 18 | 19 | (program (return_statement (number))) 20 | 21 | ============================== 22 | Expression list 23 | ============================== 24 | 25 | return 4, 5, 4 26 | 27 | --- 28 | 29 | (program (return_statement (number) (number) (number))) 30 | 31 | ============================== 32 | Expression list with parens 33 | ============================== 34 | 35 | return 4, (5), 4 36 | 37 | --- 38 | 39 | (program (return_statement (number) (parenthesized_expression (number)) (number))) 40 | 41 | ============================== 42 | Return that looks like a function call 43 | ============================== 44 | 45 | return(4, 5, 4) 46 | 47 | --- 48 | 49 | (program (return_statement (number) (number) (number))) 50 | -------------------------------------------------------------------------------- /test/corpus/semi-colons.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Statement with a semi-colon 3 | ================================================================================ 4 | 5 | local x = 5; 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | declarators: (var_declarators 12 | (var 13 | name: (identifier))) 14 | initializers: (expressions 15 | (number)))) 16 | -------------------------------------------------------------------------------- /test/corpus/simple_types.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Local declaration 3 | ================================================================================ 4 | 5 | local x: number 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | declarators: (var_declarators 12 | (var 13 | name: (identifier))) 14 | type_annotation: (type_annotation 15 | (simple_type 16 | name: (identifier))))) 17 | 18 | ================================================================================ 19 | Local declaration with initialization 20 | ================================================================================ 21 | 22 | local x: number = 5 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (var_declaration 28 | declarators: (var_declarators 29 | (var 30 | name: (identifier))) 31 | type_annotation: (type_annotation 32 | (simple_type 33 | name: (identifier))) 34 | initializers: (expressions 35 | (number)))) 36 | 37 | ================================================================================ 38 | Local declaration of multiple variables 39 | ================================================================================ 40 | 41 | local x, y: number, string 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | (program 46 | (var_declaration 47 | declarators: (var_declarators 48 | (var 49 | name: (identifier)) 50 | (var 51 | name: (identifier))) 52 | type_annotation: (type_annotation 53 | (simple_type 54 | name: (identifier)) 55 | (simple_type 56 | name: (identifier))))) 57 | 58 | ================================================================================ 59 | Local declaration of multiple variables with initialization 60 | ================================================================================ 61 | 62 | local x, y: number, string = 23, "hi" 63 | 64 | -------------------------------------------------------------------------------- 65 | 66 | (program 67 | (var_declaration 68 | declarators: (var_declarators 69 | (var 70 | name: (identifier)) 71 | (var 72 | name: (identifier))) 73 | type_annotation: (type_annotation 74 | (simple_type 75 | name: (identifier)) 76 | (simple_type 77 | name: (identifier))) 78 | initializers: (expressions 79 | (number) 80 | (string 81 | content: (string_content))))) 82 | 83 | ================================================================================ 84 | Union 85 | ================================================================================ 86 | 87 | local x: string | number 88 | 89 | -------------------------------------------------------------------------------- 90 | 91 | (program 92 | (var_declaration 93 | declarators: (var_declarators 94 | (var 95 | name: (identifier))) 96 | type_annotation: (type_annotation 97 | (type_union 98 | (simple_type 99 | name: (identifier)) 100 | (simple_type 101 | name: (identifier)))))) 102 | 103 | ================================================================================ 104 | Union of simple type and non-array type 105 | ================================================================================ 106 | 107 | local x: thread | {string:number} = {} 108 | 109 | -------------------------------------------------------------------------------- 110 | 111 | (program 112 | (var_declaration 113 | declarators: (var_declarators 114 | (var 115 | name: (identifier))) 116 | type_annotation: (type_annotation 117 | (type_union 118 | (simple_type 119 | name: (identifier)) 120 | (table_type 121 | key_type: (simple_type 122 | name: (identifier)) 123 | value_type: (simple_type 124 | name: (identifier))))) 125 | initializers: (expressions 126 | (table_constructor)))) 127 | 128 | ================================================================================ 129 | Type indexing 130 | ================================================================================ 131 | 132 | local x: foo.bar 133 | 134 | -------------------------------------------------------------------------------- 135 | 136 | (program 137 | (var_declaration 138 | declarators: (var_declarators 139 | (var 140 | name: (identifier))) 141 | type_annotation: (type_annotation 142 | (type_index 143 | (identifier) 144 | (identifier))))) 145 | 146 | ================================================================================ 147 | Multiple type indexing 148 | ================================================================================ 149 | 150 | local x: foo.bar.baz 151 | 152 | -------------------------------------------------------------------------------- 153 | 154 | (program 155 | (var_declaration 156 | declarators: (var_declarators 157 | (var 158 | name: (identifier))) 159 | type_annotation: (type_annotation 160 | (type_index 161 | (type_index 162 | (identifier) 163 | (identifier)) 164 | (identifier))))) 165 | -------------------------------------------------------------------------------- /test/corpus/strings.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple "string" 3 | ================================================================================ 4 | 5 | local x = "hello" 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | (var_declarators 12 | (var 13 | (identifier))) 14 | (expressions 15 | (string 16 | (string_content))))) 17 | 18 | ================================================================================ 19 | Simple 'string' 20 | ================================================================================ 21 | 22 | local x = 'hello' 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (var_declaration 28 | (var_declarators 29 | (var 30 | (identifier))) 31 | (expressions 32 | (string 33 | (string_content))))) 34 | 35 | ================================================================================ 36 | Simple "string" with \" 37 | ================================================================================ 38 | 39 | local x = "he\"llo" 40 | 41 | -------------------------------------------------------------------------------- 42 | 43 | (program 44 | (var_declaration 45 | (var_declarators 46 | (var 47 | (identifier))) 48 | (expressions 49 | (string 50 | (string_content 51 | (escape_sequence)))))) 52 | 53 | ================================================================================ 54 | Simple 'string' with \' 55 | ================================================================================ 56 | 57 | local x = 'he\'llo' 58 | 59 | -------------------------------------------------------------------------------- 60 | 61 | (program 62 | (var_declaration 63 | (var_declarators 64 | (var 65 | (identifier))) 66 | (expressions 67 | (string 68 | (string_content 69 | (escape_sequence)))))) 70 | 71 | ================================================================================ 72 | Simple "string" with format specifier 73 | ================================================================================ 74 | 75 | local x = "a %A" 76 | 77 | -------------------------------------------------------------------------------- 78 | 79 | (program 80 | (var_declaration 81 | (var_declarators 82 | (var 83 | (identifier))) 84 | (expressions 85 | (string 86 | (string_content 87 | (format_specifier)))))) 88 | 89 | ================================================================================ 90 | Simple "string" with % but not a format specifier 91 | ================================================================================ 92 | 93 | local x = "%" 94 | 95 | -------------------------------------------------------------------------------- 96 | 97 | (program 98 | (var_declaration 99 | (var_declarators 100 | (var 101 | (identifier))) 102 | (expressions 103 | (string 104 | (string_content))))) 105 | 106 | ================================================================================ 107 | Long [[string]] 108 | ================================================================================ 109 | 110 | local x = [[hello]] 111 | 112 | -------------------------------------------------------------------------------- 113 | 114 | (program 115 | (var_declaration 116 | (var_declarators 117 | (var 118 | (identifier))) 119 | (expressions 120 | (string 121 | (string_content))))) 122 | 123 | ================================================================================ 124 | Long [ [string] ] 125 | ================================================================================ 126 | 127 | local x = [==[hello]==] 128 | 129 | -------------------------------------------------------------------------------- 130 | 131 | (program 132 | (var_declaration 133 | (var_declarators 134 | (var 135 | (identifier))) 136 | (expressions 137 | (string 138 | (string_content))))) 139 | 140 | ================================================================================ 141 | Longer [ [string] ] 142 | ================================================================================ 143 | 144 | local x = [====[hello]====] 145 | 146 | -------------------------------------------------------------------------------- 147 | 148 | (program 149 | (var_declaration 150 | (var_declarators 151 | (var 152 | (identifier))) 153 | (expressions 154 | (string 155 | (string_content))))) 156 | 157 | ================================================================================ 158 | Long string with eq + almost terminating sequence 159 | ================================================================================ 160 | 161 | local x = [==[ ]== ]==] 162 | 163 | -------------------------------------------------------------------------------- 164 | 165 | (program 166 | (var_declaration 167 | (var_declarators 168 | (var 169 | (identifier))) 170 | (expressions 171 | (string 172 | (string_content))))) 173 | 174 | ================================================================================ 175 | "String" with -- in it 176 | ================================================================================ 177 | 178 | local x = "-- stuff" 179 | 180 | -------------------------------------------------------------------------------- 181 | 182 | (program 183 | (var_declaration 184 | (var_declarators 185 | (var 186 | (identifier))) 187 | (expressions 188 | (string 189 | (string_content))))) 190 | 191 | ================================================================================ 192 | 'String' with -- in it 193 | ================================================================================ 194 | 195 | local x = '-- stuff' 196 | 197 | -------------------------------------------------------------------------------- 198 | 199 | (program 200 | (var_declaration 201 | (var_declarators 202 | (var 203 | (identifier))) 204 | (expressions 205 | (string 206 | (string_content))))) 207 | 208 | ================================================================================ 209 | String in return statement 210 | ================================================================================ 211 | 212 | return "hi" 213 | 214 | -------------------------------------------------------------------------------- 215 | 216 | (program 217 | (return_statement 218 | (string 219 | (string_content)))) 220 | 221 | ================================================================================ 222 | Unicode escape seq 223 | ================================================================================ 224 | 225 | local x = "a \u{123} b" 226 | 227 | -------------------------------------------------------------------------------- 228 | 229 | (program 230 | (var_declaration 231 | (var_declarators 232 | (var 233 | (identifier))) 234 | (expressions 235 | (string 236 | (string_content 237 | (escape_sequence)))))) 238 | 239 | ================================================================================ 240 | % at end of long string 241 | ================================================================================ 242 | 243 | local x = [[ abcd %]] 244 | 245 | -------------------------------------------------------------------------------- 246 | 247 | (program 248 | (var_declaration 249 | (var_declarators 250 | (var 251 | (identifier))) 252 | (expressions 253 | (string 254 | (string_content))))) 255 | 256 | ================================================================================ 257 | Long string with format specifier 258 | ================================================================================ 259 | 260 | local x = [[ abcd %s ]] 261 | 262 | -------------------------------------------------------------------------------- 263 | 264 | (program 265 | (var_declaration 266 | (var_declarators 267 | (var 268 | (identifier))) 269 | (expressions 270 | (string 271 | (string_content 272 | (format_specifier)))))) 273 | 274 | ================================================================================ 275 | Empty long string 276 | ================================================================================ 277 | 278 | local x = [[]] 279 | 280 | -------------------------------------------------------------------------------- 281 | 282 | (program 283 | (var_declaration 284 | (var_declarators 285 | (var 286 | (identifier))) 287 | (expressions 288 | (string)))) 289 | -------------------------------------------------------------------------------- /test/corpus/table_constructor.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty 3 | ================================================================================ 4 | 5 | local t = {} 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | (var_declarators 12 | (var 13 | (identifier))) 14 | (expressions 15 | (table_constructor)))) 16 | 17 | ================================================================================ 18 | Array 19 | ================================================================================ 20 | 21 | local arr = {1, 2, 3} 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (var_declaration 27 | declarators: (var_declarators 28 | (var 29 | name: (identifier))) 30 | initializers: (expressions 31 | (table_constructor 32 | (table_entry 33 | value: (number)) 34 | (table_entry 35 | value: (number)) 36 | (table_entry 37 | value: (number)))))) 38 | 39 | ================================================================================ 40 | Identifier-Map 41 | ================================================================================ 42 | 43 | local map = { 44 | x = 5, 45 | y = 6, 46 | } 47 | 48 | -------------------------------------------------------------------------------- 49 | 50 | (program 51 | (var_declaration 52 | declarators: (var_declarators 53 | (var 54 | name: (identifier))) 55 | initializers: (expressions 56 | (table_constructor 57 | (table_entry 58 | key: (identifier) 59 | value: (number)) 60 | (table_entry 61 | key: (identifier) 62 | value: (number)))))) 63 | 64 | ================================================================================ 65 | Value-Map 66 | ================================================================================ 67 | 68 | local map = { 69 | ["x"] = 5, 70 | [y] = 6, 71 | } 72 | 73 | -------------------------------------------------------------------------------- 74 | 75 | (program 76 | (var_declaration 77 | declarators: (var_declarators 78 | (var 79 | name: (identifier))) 80 | initializers: (expressions 81 | (table_constructor 82 | (table_entry 83 | expr_key: (string 84 | content: (string_content)) 85 | value: (number)) 86 | (table_entry 87 | expr_key: (identifier) 88 | value: (number)))))) 89 | 90 | ================================================================================ 91 | Nested 92 | ================================================================================ 93 | 94 | local tab = { 95 | foo = { 96 | bar = "a", 97 | baz = "b", 98 | }, 99 | [{}] = {}; 100 | } 101 | 102 | -------------------------------------------------------------------------------- 103 | 104 | (program 105 | (var_declaration 106 | declarators: (var_declarators 107 | (var 108 | name: (identifier))) 109 | initializers: (expressions 110 | (table_constructor 111 | (table_entry 112 | key: (identifier) 113 | value: (table_constructor 114 | (table_entry 115 | key: (identifier) 116 | value: (string 117 | content: (string_content))) 118 | (table_entry 119 | key: (identifier) 120 | value: (string 121 | content: (string_content))))) 122 | (table_entry 123 | expr_key: (table_constructor) 124 | value: (table_constructor)))))) 125 | 126 | ================================================================================ 127 | With type annotations 128 | ================================================================================ 129 | 130 | local tl = { 131 | process: function(string, Env, Result, {string}): (Result, string) = nil, 132 | } 133 | 134 | -------------------------------------------------------------------------------- 135 | 136 | (program 137 | (var_declaration 138 | declarators: (var_declarators 139 | (var 140 | name: (identifier))) 141 | initializers: (expressions 142 | (table_constructor 143 | (table_entry 144 | key: (identifier) 145 | type: (function_type 146 | arguments: (arguments 147 | (arg 148 | type: (simple_type 149 | name: (identifier))) 150 | (arg 151 | type: (simple_type 152 | name: (identifier))) 153 | (arg 154 | type: (simple_type 155 | name: (identifier))) 156 | (arg 157 | type: (table_type 158 | value_type: (simple_type 159 | name: (identifier))))) 160 | return_type: (return_type 161 | (simple_type 162 | name: (identifier)) 163 | (simple_type 164 | name: (identifier)))) 165 | value: (nil)))))) 166 | 167 | ================================================================================ 168 | Method call as expression inside table 169 | ================================================================================ 170 | 171 | local a = { b:c() } 172 | 173 | -------------------------------------------------------------------------------- 174 | 175 | (program 176 | (var_declaration 177 | declarators: (var_declarators 178 | (var 179 | name: (identifier))) 180 | initializers: (expressions 181 | (table_constructor 182 | (table_entry 183 | value: (function_call 184 | called_object: (method_index 185 | (identifier) 186 | key: (identifier)) 187 | arguments: (arguments))))))) 188 | -------------------------------------------------------------------------------- /test/corpus/table_types.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Array type 3 | ================================================================================ 4 | 5 | local x: {string} 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | declarators: (var_declarators 12 | (var 13 | name: (identifier))) 14 | type_annotation: (type_annotation 15 | (table_type 16 | value_type: (simple_type 17 | name: (identifier)))))) 18 | 19 | ================================================================================ 20 | Array type with initialization 21 | ================================================================================ 22 | 23 | local x: {string} = {} 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | (program 28 | (var_declaration 29 | declarators: (var_declarators 30 | (var 31 | name: (identifier))) 32 | type_annotation: (type_annotation 33 | (table_type 34 | value_type: (simple_type 35 | name: (identifier)))) 36 | initializers: (expressions 37 | (table_constructor)))) 38 | 39 | ================================================================================ 40 | Map type 41 | ================================================================================ 42 | 43 | local x: {string:number} 44 | 45 | -------------------------------------------------------------------------------- 46 | 47 | (program 48 | (var_declaration 49 | declarators: (var_declarators 50 | (var 51 | name: (identifier))) 52 | type_annotation: (type_annotation 53 | (table_type 54 | key_type: (simple_type 55 | name: (identifier)) 56 | value_type: (simple_type 57 | name: (identifier)))))) 58 | 59 | ================================================================================ 60 | Map type with initialization 61 | ================================================================================ 62 | 63 | local x: {string:number} = {} 64 | 65 | -------------------------------------------------------------------------------- 66 | 67 | (program 68 | (var_declaration 69 | declarators: (var_declarators 70 | (var 71 | name: (identifier))) 72 | type_annotation: (type_annotation 73 | (table_type 74 | key_type: (simple_type 75 | name: (identifier)) 76 | value_type: (simple_type 77 | name: (identifier)))) 78 | initializers: (expressions 79 | (table_constructor)))) 80 | 81 | ================================================================================ 82 | Tuple type 83 | ================================================================================ 84 | 85 | local x: {number, string} 86 | 87 | -------------------------------------------------------------------------------- 88 | 89 | (program 90 | (var_declaration 91 | declarators: (var_declarators 92 | (var 93 | name: (identifier))) 94 | type_annotation: (type_annotation 95 | (table_type 96 | tuple_type: (simple_type 97 | name: (identifier)) 98 | tuple_type: (simple_type 99 | name: (identifier)))))) 100 | 101 | ================================================================================ 102 | Tuple type with initialization 103 | ================================================================================ 104 | 105 | local x: {number, string} = {} 106 | 107 | -------------------------------------------------------------------------------- 108 | 109 | (program 110 | (var_declaration 111 | declarators: (var_declarators 112 | (var 113 | name: (identifier))) 114 | type_annotation: (type_annotation 115 | (table_type 116 | tuple_type: (simple_type 117 | name: (identifier)) 118 | tuple_type: (simple_type 119 | name: (identifier)))) 120 | initializers: (expressions 121 | (table_constructor)))) 122 | 123 | ================================================================================ 124 | Tuple type with initialization 125 | ================================================================================ 126 | 127 | local types_seen: {(number|string):boolean} = {} 128 | 129 | -------------------------------------------------------------------------------- 130 | 131 | (program 132 | (var_declaration 133 | declarators: (var_declarators 134 | (var 135 | name: (identifier))) 136 | type_annotation: (type_annotation 137 | (table_type 138 | key_type: (type_union 139 | (simple_type 140 | name: (identifier)) 141 | (simple_type 142 | name: (identifier))) 143 | value_type: (simple_type 144 | name: (identifier)))) 145 | initializers: (expressions 146 | (table_constructor)))) 147 | -------------------------------------------------------------------------------- /test/corpus/variable_assignment.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Local Variable Declaration 3 | ================================================================================ 4 | 5 | local x = 5 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | declarators: (var_declarators 12 | (var 13 | name: (identifier))) 14 | initializers: (expressions 15 | (number)))) 16 | 17 | ================================================================================ 18 | Global Variable Declaration 19 | ================================================================================ 20 | 21 | global x = 5 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (program 26 | (var_declaration 27 | declarators: (var_declarators 28 | (var 29 | name: (identifier))) 30 | initializers: (expressions 31 | (number)))) 32 | 33 | ================================================================================ 34 | Local Variable List Declaration 35 | ================================================================================ 36 | 37 | local x, y, z = 1, 2, 3 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (program 42 | (var_declaration 43 | declarators: (var_declarators 44 | (var 45 | name: (identifier)) 46 | (var 47 | name: (identifier)) 48 | (var 49 | name: (identifier))) 50 | initializers: (expressions 51 | (number) 52 | (number) 53 | (number)))) 54 | 55 | ================================================================================ 56 | Global Variable List Declaration 57 | ================================================================================ 58 | 59 | global x, y, z = 1, 2, "hey" 60 | 61 | -------------------------------------------------------------------------------- 62 | 63 | (program 64 | (var_declaration 65 | declarators: (var_declarators 66 | (var 67 | name: (identifier)) 68 | (var 69 | name: (identifier)) 70 | (var 71 | name: (identifier))) 72 | initializers: (expressions 73 | (number) 74 | (number) 75 | (string 76 | content: (string_content))))) 77 | 78 | ================================================================================ 79 | Variable reassignment 80 | ================================================================================ 81 | 82 | local x = "hey" 83 | x = "hi" 84 | 85 | -------------------------------------------------------------------------------- 86 | 87 | (program 88 | (var_declaration 89 | declarators: (var_declarators 90 | (var 91 | name: (identifier))) 92 | initializers: (expressions 93 | (string 94 | content: (string_content)))) 95 | (var_assignment 96 | variables: (assignment_variables 97 | (var 98 | (identifier))) 99 | expressions: (expressions 100 | (string 101 | content: (string_content))))) 102 | 103 | ================================================================================ 104 | Table entry reassignment 105 | ================================================================================ 106 | 107 | foo.bar = "hi" 108 | 109 | -------------------------------------------------------------------------------- 110 | 111 | (program 112 | (var_assignment 113 | (assignment_variables 114 | (var 115 | (index 116 | (identifier) 117 | (identifier)))) 118 | (expressions 119 | (string 120 | (string_content))))) 121 | -------------------------------------------------------------------------------- /test/corpus/variable_declaration.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Local Variable Declaration 3 | ================================================================================ 4 | 5 | local x = 5 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (program 10 | (var_declaration 11 | (var_declarators 12 | (var 13 | (identifier) 14 | (attribute))) 15 | (expressions 16 | (number)))) 17 | 18 | ================================================================================ 19 | Global Variable Declaration 20 | ================================================================================ 21 | 22 | local x = 5 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | (program 27 | (var_declaration 28 | (var_declarators 29 | (var 30 | (identifier) 31 | (attribute))) 32 | (expressions 33 | (number)))) 34 | 35 | ================================================================================ 36 | Local Variable List Declaration 37 | ================================================================================ 38 | 39 | local x , y , z = 1, 2, 3 40 | 41 | -------------------------------------------------------------------------------- 42 | 43 | (program 44 | (var_declaration 45 | (var_declarators 46 | (var 47 | (identifier) 48 | (attribute)) 49 | (var 50 | (identifier) 51 | (attribute)) 52 | (var 53 | (identifier) 54 | (attribute))) 55 | (expressions 56 | (number) 57 | (number) 58 | (number)))) 59 | 60 | ================================================================================ 61 | Global Variable List Declaration 62 | ================================================================================ 63 | 64 | global x , y , z = 1, 2, 3 65 | 66 | -------------------------------------------------------------------------------- 67 | 68 | (program 69 | (var_declaration 70 | (var_declarators 71 | (var 72 | (identifier) 73 | (attribute)) 74 | (var 75 | (identifier) 76 | (attribute)) 77 | (var 78 | (identifier) 79 | (attribute))) 80 | (expressions 81 | (number) 82 | (number) 83 | (number)))) 84 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "teal", 5 | "camelcase": "Teal", 6 | "scope": "source.teal", 7 | "path": ".", 8 | "file-types": [ 9 | "tl" 10 | ] 11 | } 12 | ], 13 | "metadata": { 14 | "version": "0.1.0", 15 | "license": "MIT", 16 | "description": "Tree sitter parser for Teal, a typed dialect of Lua.", 17 | "authors": [ 18 | { 19 | "name": "euclidianAce" 20 | } 21 | ], 22 | "links": { 23 | "repository": "https://github.com/tree-sitter/tree-sitter-teal" 24 | } 25 | }, 26 | "bindings": { 27 | "c": true, 28 | "go": true, 29 | "node": true, 30 | "python": true, 31 | "rust": true, 32 | "swift": true, 33 | "zig": true 34 | } 35 | } 36 | --------------------------------------------------------------------------------