Update F# parser to use crate

pull/730/merge
Wilfred Hughes 2025-02-22 21:53:21 +07:00
parent 5420cd19fa
commit 89e2a459d6
76 changed files with 20 additions and 386446 deletions

@ -2,7 +2,7 @@
### Parsing
Updated to the latest tree-sitter parser for Pascal and Swift.
Updated to the latest tree-sitter parser for F#, Pascal and Swift.
## 0.63 (released 11th February 2025)

11
Cargo.lock generated

@ -280,6 +280,7 @@ dependencies = [
"tree-sitter-cpp",
"tree-sitter-css",
"tree-sitter-elixir",
"tree-sitter-fsharp",
"tree-sitter-go",
"tree-sitter-haskell",
"tree-sitter-html",
@ -1063,6 +1064,16 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-fsharp"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2db500a0948bf37c43febe2c3d67bfb9ad690b06aaa20780a5106da6f620b41"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-go"
version = "0.23.4"

@ -103,6 +103,7 @@ tree-sitter-elixir = "0.3.4"
tree-sitter-nix = "0.0.2"
tree-sitter-pascal = "0.10.0"
tree-sitter-swift = "0.7.0"
tree-sitter-fsharp = "0.1.0"
[dev-dependencies]
# assert_cmd 2.0.10 requires predicates 3.

@ -117,11 +117,6 @@ fn main() {
src_dir: "vendored_parsers/tree-sitter-erlang-src",
extra_files: vec![],
},
TreeSitterParser {
name: "tree-sitter-f-sharp",
src_dir: "vendored_parsers/tree-sitter-f-sharp-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-gleam",
src_dir: "vendored_parsers/tree-sitter-gleam-src",

@ -77,7 +77,7 @@ sample_files/erlang_1.erl sample_files/erlang_2.erl
dccdb8f65d2f099ab1a8cb66011376a2 -
sample_files/f_sharp_1.fs sample_files/f_sharp_2.fs
a9251656c7808ec0e3411fbbd189f5aa -
25253b18ef64469c67cf9a7131c8c125 -
sample_files/hack_1.php sample_files/hack_2.php
c2bb0aa7d7b07d6ced79f6a5363e878b -

@ -70,7 +70,6 @@ extern "C" {
fn tree_sitter_elm() -> ts::Language;
fn tree_sitter_elvish() -> ts::Language;
fn tree_sitter_erlang() -> ts::Language;
fn tree_sitter_fsharp() -> ts::Language;
fn tree_sitter_gleam() -> ts::Language;
fn tree_sitter_hare() -> ts::Language;
fn tree_sitter_hack() -> ts::Language;
@ -374,16 +373,16 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig {
}
}
FSharp => {
let language = unsafe { tree_sitter_fsharp() };
let language_fn = tree_sitter_fsharp::LANGUAGE_FSHARP;
let language = tree_sitter::Language::new(language_fn);
TreeSitterConfig {
language: language.clone(),
atom_nodes: ["string", "triple_quoted_string"].into_iter().collect(),
delimiter_tokens: vec![("(", ")"), ("[", "]"), ("{", "}")],
highlight_query: ts::Query::new(
&language,
include_str!("../../vendored_parsers/highlights/f-sharp.scm"),
)
.unwrap(),
highlight_query: ts::Query::new(&language, tree_sitter_fsharp::HIGHLIGHTS_QUERY)
.unwrap(),
sub_languages: vec![],
}
}

@ -1 +0,0 @@
../tree-sitter-f-sharp/queries/highlights.scm

@ -1 +0,0 @@
tree-sitter-f-sharp/src

@ -1,43 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{json,toml,yml,gyp}]
indent_style = space
indent_size = 2
[*.fs]
indent_style = space
indent_size = 2
[*.js]
indent_style = space
indent_size = 2
[*.rs]
indent_style = space
indent_size = 4
[*.{c,cc,h}]
indent_style = space
indent_size = 2
[*.{py,pyi}]
indent_style = space
indent_size = 4
[*.swift]
indent_style = space
indent_size = 4
[*.go]
indent_style = tab
indent_size = 8
[Makefile]
indent_style = tab
indent_size = 8

@ -1,20 +0,0 @@
module.exports = {
'env': {
'commonjs': true,
'es2021': true,
},
'extends': 'google',
'overrides': [
],
'parserOptions': {
'ecmaVersion': 'latest',
'sourceType': 'module',
},
'rules': {
'indent': ['error', 2, {'SwitchCase': 1}],
'max-len': [
'error',
{'code': 120, 'ignoreComments': true, 'ignoreUrls': true, 'ignoreStrings': true},
],
},
};

@ -1,11 +0,0 @@
* text eol=lf
src/*.json linguist-generated
src/parser.c linguist-generated
src/tree_sitter/* linguist-generated
bindings/** linguist-vendored
binding.gyp linguist-vendored
setup.py linguist-vendored
Makefile linguist-vendored
Package.swift linguist-vendored

@ -1,10 +0,0 @@
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "cargo" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

@ -1,50 +0,0 @@
name: CI
on:
push:
branches: ["main"]
paths:
- grammar.js
- src/**
- test/**
- bindings/**
- binding.gyp
pull_request:
concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true
jobs:
test:
name: Test parser
runs-on: ${{matrix.os}}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-14]
steps:
- uses: actions/checkout@v4
- uses: tree-sitter/setup-action/cli@v1
- uses: tree-sitter/parser-test-action@v2
with:
generate: ${{runner.os == 'Linux'}}
fuzz:
name: Fuzz parser
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check for scanner changes
id: scanner-changes
run: |-
if git diff --quiet HEAD^ -- src/scanner.c; then
printf 'changed=false\n' >> "$GITHUB_OUTPUT"
else
printf 'changed=true\n' >> "$GITHUB_OUTPUT"
fi
- name: Fuzz parser
uses: tree-sitter/fuzz-action@v4
if: steps.scanner-changes.outputs.changed == 'true'

@ -1,53 +0,0 @@
name: Build/release
on:
workflow_dispatch:
permissions:
contents: write
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v3
with:
ref: "develop"
- uses: actions/setup-node@v2
with:
node-version: 16
- run: npm install
- run: npm test
release:
runs-on: ubuntu-latest
steps:
- name: Checkout develop branch
uses: actions/checkout@v3
with:
ref: "develop"
- name: Fetch main branch
run: |
git fetch origin main
git branch -t main origin/main
- name: "remove src/parser.c from .gitignore"
run: sed -i '/src\/parser.c/d' .gitignore
- uses: actions/setup-node@v2
with:
node-version: 16
- name: "compile main branch"
run: |
npm install
npm run build
- name: Merge into main branch and publish
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git add .
tree=$(git write-tree)
commit=$(git commit-tree -p main -p develop -m "release" $tree)
git update-ref refs/heads/main $commit
git push origin main

@ -1,36 +0,0 @@
# Rust artifacts
/Cargo.lock
/target/
# Node artifacts
/build/
/node_modules/
# Swift artifacts
/.build/
# Python artifacts
/dist/
*.egg-info
*.whl
# Zig artifacts
/zig-cache/
/zig-out/
# C artifacts
*.a
*.so
*.so.*
*.dylib
*.dll
*.pc
# Example dirs
/examples/*/
# Grammar volatiles
dsl.d.ts
*.wasm
*.obj
*.o

@ -1,17 +0,0 @@
bindings/c
bindings/go
bindings/python
bindings/rust
bindings/swift
Cargo.toml
Makefile
examples
pyproject.toml
setup.py
test
.editorconfig
.github
.gitignore
.gitattributes
.gitmodules
.npmignore

@ -1,26 +0,0 @@
[package]
name = "tree-sitter-fsharp"
description = "fsharp grammar for the tree-sitter parsing library"
version = "0.0.1"
keywords = ["incremental", "parsing", "fsharp"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/nsidorenco/tree-sitter-fsharp"
edition = "2021"
license = "MIT"
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = ">=0.21.0"
[build-dependencies]
cc = "1.0.89"

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Nikolaj Sidorenco
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,110 +0,0 @@
VERSION := 0.0.1
LANGUAGE_NAME := tree-sitter-fsharp
# repository
SRC_DIR := src
PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin 2>/dev/null)
ifeq ($(PARSER_URL),)
PARSER_URL := $(subst .git,,$(PARSER_REPO_URL))
ifeq ($(shell echo $(PARSER_URL) | grep '^[a-z][-+.0-9a-z]*://'),)
PARSER_URL := $(subst :,/,$(PARSER_URL))
PARSER_URL := $(subst git@,https://,$(PARSER_URL))
endif
endif
TS ?= tree-sitter
# ABI versioning
SONAME_MAJOR := $(word 1,$(subst ., ,$(VERSION)))
SONAME_MINOR := $(word 2,$(subst ., ,$(VERSION)))
# install directory layout
PREFIX ?= /usr/local
INCLUDEDIR ?= $(PREFIX)/include
LIBDIR ?= $(PREFIX)/lib
PCLIBDIR ?= $(LIBDIR)/pkgconfig
# object files
OBJS := $(patsubst %.c,%.o,$(wildcard $(SRC_DIR)/*.c))
# flags
ARFLAGS := rcs
override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC
# OS-specific bits
ifeq ($(OS),Windows_NT)
$(error "Windows is not supported")
else ifeq ($(shell uname),Darwin)
SOEXT = dylib
SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib
LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
ifneq ($(ADDITIONAL_LIBS),)
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS),
endif
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks
else
SOEXT = so
SOEXTVER_MAJOR = so.$(SONAME_MAJOR)
SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR)
LINKSHARED := $(LINKSHARED)-shared -Wl,
ifneq ($(ADDITIONAL_LIBS),)
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS)
endif
LINKSHARED := $(LINKSHARED)-soname,lib$(LANGUAGE_NAME).so.$(SONAME_MAJOR)
endif
ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
endif
all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc
lib$(LANGUAGE_NAME).a: $(OBJS)
$(AR) $(ARFLAGS) $@ $^
lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS)
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
ifneq ($(STRIP),)
$(STRIP) $@
endif
$(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in
sed -e 's|@URL@|$(PARSER_URL)|' \
-e 's|@VERSION@|$(VERSION)|' \
-e 's|@LIBDIR@|$(LIBDIR)|' \
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
-e 's|@REQUIRES@|$(REQUIRES)|' \
-e 's|@ADDITIONAL_LIBS@|$(ADDITIONAL_LIBS)|' \
-e 's|=$(PREFIX)|=$${prefix}|' \
-e 's|@PREFIX@|$(PREFIX)|' $< > $@
$(SRC_DIR)/parser.c: grammar.js
$(TS) generate --no-bindings
install: all
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT)
uninstall:
$(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \
'$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
'$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
clean:
$(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT)
test:
$(TS) test
.PHONY: all install uninstall clean test

@ -1,48 +0,0 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterFsharp",
platforms: [.macOS(.v10_13), .iOS(.v11)],
products: [
.library(name: "TreeSitterFsharp", targets: ["TreeSitterFsharp"]),
],
dependencies: [],
targets: [
.target(name: "TreeSitterFsharp",
path: ".",
exclude: [
"Cargo.toml",
"Makefile",
"binding.gyp",
"bindings/c",
"bindings/go",
"bindings/node",
"bindings/python",
"bindings/rust",
"prebuilds",
"grammar.js",
"package.json",
"package-lock.json",
"pyproject.toml",
"setup.py",
"test",
"examples",
".editorconfig",
".github",
".gitignore",
".gitattributes",
".gitmodules",
],
sources: [
"src/parser.c",
// NOTE: if your language has an external scanner, add it here.
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")])
],
cLanguageStandard: .c11
)

@ -1,77 +0,0 @@
# tree-sitter-fsharp
tree-sitter grammar for F# (still WIP)
Based on [the 4.1 F# language specification](https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf) (Mostly, Appendix A)
and the [F# compiler parser](https://github.com/dotnet/fsharp/blob/main/src/Compiler/pars.fsy)
## Getting started
First, run `npm install` to install the `tree-sitter cli`.
Next, the grammar can be build using `npm run build`, or used to parse a file with `npm run parse $file`
### Project structure
The parser consists of two parts:
- `src/scanner.c` is responsible for parsing newlines and comments and keeps track of indentation to open and close scopes.
- `grammar.js` the main tree-sitter grammar. The indent tokens from the external scanner is access though the `indent` and `dedent` tokens.
The grammar starts with the `file` node at the begging of the rules.
### Adding to neovim
#### From the local copy:
```lua
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.fsharp = {
install_info = {
url = "path/to/tree-sitter-fsharp",
files = {"src/scanner.c", "src/parser.c" }
},
filetype = "fsharp",
}
```
#### From GitHub repository:
```lua
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.fsharp = {
install_info = {
url = "https://github.com/Nsidorenco/tree-sitter-fsharp",
branch = "main",
files = {"src/scanner.c", "src/parser.c" },
},
filetype = "fsharp",
}
```
Then run `:TSInstall fsharp` inside neovim.
## Status
The grammar currently has support for most language features, but might have rough edges.
Some parts, like the type annotations are still very bare-bones.
The grammar supports indentation-based scoping but does not fully support offside indentation and opening new indentation levels on record/list construction.
The precedence rules for the different grammar nodes (and particularly expressions) are not set properly yet, which means that the parser size is much larger than needed.
### Missing
- [ ] Computational expressions
- [ ] Type annotations
- [x] Annotations
- [ ] Offside tokens inside indentation scope
- [ ] Testing
- [ ] Set properly precedence rules
## Testing
### Testing corpus
To run all tests stores in `corpus/` run
```sh
$ npm test
```
### Test parsing a specific file
```
$ npm run debug $file
```
## How to contribute
Clone the repo and start playing around with it.
If you find a code example which fails to parse, please reduce it to a minimal example, such that it can be added to the corpus as a test case.
PRs fleshing out the grammar or fixing bugs are very welcome!

@ -1,21 +0,0 @@
{
"targets": [
{
"target_name": "tree_sitter_fsharp_binding",
"dependencies": [
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
],
"include_dirs": [
"src",
],
"sources": [
"bindings/node/binding.cc",
"src/parser.c",
"src/scanner.c",
],
"cflags_c": [
"-std=c11",
],
}
]
}

@ -1,16 +0,0 @@
#ifndef TREE_SITTER_FSHARP_H_
#define TREE_SITTER_FSHARP_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_fsharp(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_FSHARP_H_

@ -1,11 +0,0 @@
prefix=@PREFIX@
libdir=@LIBDIR@
includedir=@INCLUDEDIR@
Name: tree-sitter-fsharp
Description: Fsharp grammar for tree-sitter
URL: @URL@
Version: @VERSION@
Requires: @REQUIRES@
Libs: -L${libdir} @ADDITIONAL_LIBS@ -ltree-sitter-fsharp
Cflags: -I${includedir}

@ -1,13 +0,0 @@
package tree_sitter_fsharp
// #cgo CFLAGS: -std=c11 -fPIC
// #include "../../src/parser.c"
// // NOTE: if your language has an external scanner, add it here.
import "C"
import "unsafe"
// Get the tree-sitter Language for this grammar.
func Language() unsafe.Pointer {
return unsafe.Pointer(C.tree_sitter_fsharp())
}

@ -1,15 +0,0 @@
package tree_sitter_fsharp_test
import (
"testing"
tree_sitter "github.com/smacker/go-tree-sitter"
"github.com/tree-sitter/tree-sitter-fsharp"
)
func TestCanLoadGrammar(t *testing.T) {
language := tree_sitter.NewLanguage(tree_sitter_fsharp.Language())
if language == nil {
t.Errorf("Error loading Fsharp grammar")
}
}

@ -1,5 +0,0 @@
module github.com/tree-sitter/tree-sitter-fsharp
go 1.22
require github.com/smacker/go-tree-sitter v0.0.0-20230720070738-0d0a9f78d8f8

@ -1,20 +0,0 @@
#include <napi.h>
typedef struct TSLanguage TSLanguage;
extern "C" TSLanguage *tree_sitter_fsharp();
// "tree-sitter", "language" hashed with BLAKE2
const napi_type_tag LANGUAGE_TYPE_TAG = {
0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
};
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports["name"] = Napi::String::New(env, "fsharp");
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_fsharp());
language.TypeTag(&LANGUAGE_TYPE_TAG);
exports["language"] = language;
return exports;
}
NODE_API_MODULE(tree_sitter_fsharp_binding, Init)

@ -1,28 +0,0 @@
type BaseNode = {
type: string;
named: boolean;
};
type ChildNode = {
multiple: boolean;
required: boolean;
types: BaseNode[];
};
type NodeInfo =
| (BaseNode & {
subtypes: BaseNode[];
})
| (BaseNode & {
fields: { [name: string]: ChildNode };
children: ChildNode[];
});
type Language = {
name: string;
language: unknown;
nodeTypeInfo: NodeInfo[];
};
declare const language: Language;
export = language;

@ -1,7 +0,0 @@
const root = require("path").join(__dirname, "..", "..");
module.exports = require("node-gyp-build")(root);
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

@ -1,5 +0,0 @@
"Fsharp grammar for tree-sitter"
from ._binding import language
__all__ = ["language"]

@ -1,27 +0,0 @@
#include <Python.h>
typedef struct TSLanguage TSLanguage;
TSLanguage *tree_sitter_fsharp(void);
static PyObject* _binding_language(PyObject *self, PyObject *args) {
return PyLong_FromVoidPtr(tree_sitter_fsharp());
}
static PyMethodDef methods[] = {
{"language", _binding_language, METH_NOARGS,
"Get the tree-sitter language for this grammar."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "_binding",
.m_doc = NULL,
.m_size = -1,
.m_methods = methods
};
PyMODINIT_FUNC PyInit__binding(void) {
return PyModule_Create(&module);
}

@ -1,19 +0,0 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.std("c11").include(src_dir);
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
// NOTE: if your language uses an external scanner, uncomment this block:
/*
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
c_config.compile("tree-sitter-fsharp");
}

@ -1,54 +0,0 @@
//! This crate provides Fsharp language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = r#"
//! "#;
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(&tree_sitter_fsharp::language()).expect("Error loading Fsharp grammar");
//! let tree = parser.parse(code, None).unwrap();
//! assert!(!tree.root_node().has_error());
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_fsharp() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_fsharp() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
// Uncomment these to include any queries that this grammar contains
// pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(&super::language())
.expect("Error loading Fsharp grammar");
}
}

@ -1,16 +0,0 @@
#ifndef TREE_SITTER_FSHARP_H_
#define TREE_SITTER_FSHARP_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_fsharp(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_FSHARP_H_

@ -1,14 +0,0 @@
namespace test
module Json =
[<Literal>]
let MyPayload =
"""
{
"prop1": []
"prop2": {
"prop3": true,
"prop4": 1,
},
}
"""

@ -1,4 +0,0 @@
type A = {
B: int[]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,57 +0,0 @@
{
"name": "tree-sitter-fsharp",
"version": "0.0.1",
"description": "",
"repository": "https://github.com/tree-sitter/tree-sitter-fsharp",
"license": "MIT",
"author": "Nikolaj Sidorenco",
"main": "bindings/node",
"types": "bindings/node",
"files": [
"grammar.js",
"binding.gyp",
"bindings/node/*",
"queries/*",
"src/**"
],
"devDependencies": {
"eslint": "^9.2.0",
"eslint-config-google": "^0.14.0",
"prebuildify": "^6.0.1",
"tree-sitter-cli": "^0.22.6"
},
"peerDependencies": {
"tree-sitter": "^0.21.0"
},
"peerDependenciesMeta": {
"tree_sitter": {
"optional": true
}
},
"scripts": {
"build": "tree-sitter generate --no-bindings",
"lint": "eslint grammar.js",
"parse": "tree-sitter parse",
"debug": "tree-sitter parse -d",
"test": "tree-sitter test",
"install": "node-gyp-build",
"prebuildify": "prebuildify --napi --strip"
},
"tree-sitter": [
{
"scope": "source.fsharp",
"file-types": [
"fs",
"fsx"
],
"injection-regex": "fs",
"highlights": "queries/highlights.scm",
"injections": "queries/injections.scm",
"tags": "queries/tags.scm"
}
],
"dependencies": {
"node-addon-api": "^8.0.0",
"node-gyp-build": "^4.8.1"
}
}

@ -1,29 +0,0 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "tree-sitter-fsharp"
description = "Fsharp grammar for tree-sitter"
version = "0.0.1"
keywords = ["incremental", "parsing", "tree-sitter", "fsharp"]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Topic :: Software Development :: Compilers",
"Topic :: Text Processing :: Linguistic",
"Typing :: Typed"
]
requires-python = ">=3.8"
license.text = "MIT"
readme = "README.md"
[project.urls]
Homepage = "https://github.com/tree-sitter/tree-sitter-fsharp"
[project.optional-dependencies]
core = ["tree-sitter~=0.21"]
[tool.cibuildwheel]
build = "cp38-*"
build-frontend = "build"

@ -1,263 +0,0 @@
;; ----------------------------------------------------------------------------
;; Literals and comments
[
(line_comment)
(block_comment)
] @comment @spell
(xml_doc) @comment.documentation @spell
((identifier) @variable
(#set! "priority" 90))
((identifier_pattern (long_identifier (identifier) @character.special))
(#match? @character.special "^\_.*")
(#set! "priority" 90))
(const) @constant
;; ----------------------------------------------------------------------------
;; Punctuation
(wildcard_pattern) @character.special
(type_definition (_ (type_name (identifier) @type.definition)))
(type) @type
(member_signature
.
(identifier) @function.member
(curried_spec
(arguments_spec
"*"* @operator
(argument_spec
(argument_name_spec
"?"* @character.special
name: (_) @variable.parameter)
(_) @type))))
[
(union_type_case)
(rules
(rule
(identifier_pattern
(long_identifier)
.
(long_identifier) @variable)))
] @type
(fsi_directive_decl . (string) @module)
(import_decl . (_) @module)
(named_module
name: (_) @module)
(namespace
name: (_) @module)
(module_defn
.
(_) @module)
(field_initializer
field: (_) @property)
(record_fields
(record_field
.
(identifier) @property))
(dot_expression
base: (_) @variable
field: (_) @variable.member)
(value_declaration_left . (_) @variable)
(function_declaration_left
. (_) @function
[
(argument_patterns)
(argument_patterns (long_identifier (identifier)))
] @variable.parameter)
(member_defn
(method_or_prop_defn
(property_or_ident
instance: (identifier) @variable.parameter.builtin
method: (identifier) @variable.member)
args: _ @variable.parameter))
(application_expression) @function.call
(compiler_directive_decl
.
(_) @keyword.directive.define) @keyword.directive
[
(string)
(triple_quoted_string)
] @spell @string
[
(int)
(int16)
(int32)
(int64)
] @number
[
(float)
(decimal)
] @number.float
(bool) @boolean
(attribute) @attribute
[
"("
")"
"{"
"}"
"["
"]"
"[|"
"|]"
"{|"
"|}"
"[<"
">]"
] @punctuation.bracket
(format_string_eval
[
"{"
"}"
] @punctuation.special)
[
","
";"
] @punctuation.delimiter
[
"|"
"="
">"
"<"
"-"
"~"
"->"
(infix_op)
(prefix_op)
] @operator
[
"if"
"then"
"else"
"elif"
"when"
"match"
"match!"
"and"
"or"
"&&"
"||"
"then"
] @keyword.conditional
[
"and"
"or"
"not"
"upcast"
"downcast"
] @keyword.operator
[
"return"
"return!"
"yield"
"yield!"
] @keyword.return
[
"for"
"while"
"downto"
"to"
] @keyword.repeat
[
"open"
"#r"
"#load"
] @keyword.import
[
"abstract"
"delegate"
"static"
"inline"
"mutable"
"override"
"rec"
"global"
(access_modifier)
] @keyword.modifier
[
"let"
"let!"
"use"
"use!"
"member"
] @keyword.function
[
"enum"
"type"
"inherit"
"interface"
] @keyword.type
[
"try"
"with"
"finally"
] @keyword.exception
[
"as"
"assert"
"begin"
"end"
"done"
"default"
"in"
"do"
"do!"
"event"
"field"
"fun"
"function"
"get"
"set"
"lazy"
"new"
"null"
"of"
"param"
"property"
"struct"
"val"
"module"
"namespace"
] @keyword
(long_identifier
(identifier)* @module
.
(identifier))

@ -1,49 +0,0 @@
[
(value_declaration)
(module_defn)
(paren_expression)
(brace_expression)
(anon_record_expression)
(list_expression)
(array_expression)
(while_expression)
(if_expression)
(elif_expression)
(rule)
] @indent.begin
((rules) @indent.begin
(#set! indent.start_at_same_line))
((application_expression) @indent.align
(#set! indent.open_delimiter "(")
(#set! indent.close_delimiter ")"))
(paren_expression
")" @indent.branch)
(brace_expression
"}" @indent.branch)
(anon_record_expression
"|}" @indent.branch)
(list_expression
"]" @indent.branch)
(array_expression
"|]" @indent.branch)
(ERROR
.
[
"module"
"do"
]) @indent.begin
[
(string)
(line_comment)
(block_comment)
(xml_doc)
] @indent.auto

@ -1,8 +0,0 @@
([
(line_comment)
(block_comment_content)
] @injection.content
(#set! injection.language "comment"))
((xml_doc (xml_doc_content) @injection.content)
(#set! injection.language "xml"))

@ -1,33 +0,0 @@
(identifier) @local.reference
[
(namespace)
(named_module)
(function_or_value_defn)
] @local.scope
(value_declaration_left
.
[
(_ (identifier) @local.definition.var)
(_ (_ (identifier) @local.definition.var))
(_ (_ (_ (identifier) @local.definition.var)))
(_ (_ (_ (_ (identifier) @local.definition.var))))
(_ (_ (_ (_ (_ (identifier) @local.definition.var)))))
(_ (_ (_ (_ (_ (_ (identifier) @local.definition.var))))))
])
(function_declaration_left
.
((_) @local.definition.function
(#set! "definition.function.scope" "parent"))
((argument_patterns
[
(_ (identifier) @local.definition.parameter)
(_ (_ (identifier) @local.definition.parameter))
(_ (_ (_ (identifier) @local.definition.parameter)))
(_ (_ (_ (_ (identifier) @local.definition.parameter))))
(_ (_ (_ (_ (_ (identifier) @local.definition.parameter)))))
(_ (_ (_ (_ (_ (_ (identifier) @local.definition.parameter))))))
])
))

@ -1,57 +0,0 @@
from os.path import isdir, join
from platform import system
from setuptools import Extension, find_packages, setup
from setuptools.command.build import build
from wheel.bdist_wheel import bdist_wheel
class Build(build):
def run(self):
if isdir("queries"):
dest = join(self.build_lib, "tree_sitter_fsharp", "queries")
self.copy_tree("queries", dest)
super().run()
class BdistWheel(bdist_wheel):
def get_tag(self):
python, abi, platform = super().get_tag()
if python.startswith("cp"):
python, abi = "cp38", "abi3"
return python, abi, platform
setup(
packages=find_packages("bindings/python"),
package_dir={"": "bindings/python"},
package_data={
"tree_sitter_fsharp": ["*.pyi", "py.typed"],
"tree_sitter_fsharp.queries": ["*.scm"],
},
ext_package="tree_sitter_fsharp",
ext_modules=[
Extension(
name="_binding",
sources=[
"bindings/python/tree_sitter_fsharp/binding.c",
"src/parser.c",
# NOTE: if your language uses an external scanner, add it here.
],
extra_compile_args=(
["-std=c11"] if system() != 'Windows' else []
),
define_macros=[
("Py_LIMITED_API", "0x03080000"),
("PY_SSIZE_T_CLEAN", None)
],
include_dirs=["src"],
py_limited_api=True,
)
],
cmdclass={
"build": Build,
"bdist_wheel": BdistWheel
},
zip_safe=False
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,346 +0,0 @@
#include "tree_sitter/alloc.h"
#include "tree_sitter/array.h"
#include "tree_sitter/parser.h"
enum TokenType {
NEWLINE,
INDENT,
DEDENT,
THEN,
ELSE,
ELIF,
TRIPLE_QUOTE_CONTENT,
BLOCK_COMMENT_CONTENT,
LINE_COMMENT,
ERROR_SENTINEL
};
typedef struct {
Array(uint16_t) indents;
} Scanner;
static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
static inline bool scan_block_comment(TSLexer *lexer) {
lexer->mark_end(lexer);
if (lexer->lookahead != '(')
return false;
advance(lexer);
if (lexer->lookahead != '*')
return false;
advance(lexer);
while (true) {
switch (lexer->lookahead) {
case '(':
scan_block_comment(lexer);
break;
case '*':
advance(lexer);
if (lexer->lookahead == ')') {
advance(lexer);
return true;
}
break;
case '\0':
return true;
default:
advance(lexer);
}
}
}
static inline bool is_infix_op_start(TSLexer *lexer) {
switch (lexer->lookahead) {
case '+':
case '-':
case '%':
case '&':
case '=':
case '?':
case '<':
case '>':
case '^':
return true;
case '/':
skip(lexer);
return lexer->lookahead != '/';
case '.':
skip(lexer);
return lexer->lookahead != '.';
case '!':
skip(lexer);
return lexer->lookahead == '=';
case ':':
skip(lexer);
return lexer->lookahead == '=' || lexer->lookahead == ':';
case 'o':
skip(lexer);
return lexer->lookahead == 'r';
case '@':
case '$':
skip(lexer);
return lexer->lookahead != '"';
default:
return false;
}
}
static inline bool is_bracket_end(TSLexer *lexer) {
switch (lexer->lookahead) {
case ')':
case ']':
case '}':
return true;
default:
return false;
}
}
bool tree_sitter_fsharp_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
Scanner *scanner = (Scanner *)payload;
bool error_recovery_mode = valid_symbols[ERROR_SENTINEL];
if (valid_symbols[TRIPLE_QUOTE_CONTENT] && !error_recovery_mode) {
lexer->mark_end(lexer);
while (true) {
if (lexer->lookahead == '\0') {
break;
}
if (lexer->lookahead != '"') {
advance(lexer);
} else {
lexer->mark_end(lexer);
skip(lexer);
if (lexer->lookahead == '"') {
skip(lexer);
if (lexer->lookahead == '"') {
skip(lexer);
break;
}
}
lexer->mark_end(lexer);
}
}
lexer->result_symbol = TRIPLE_QUOTE_CONTENT;
return true;
}
lexer->mark_end(lexer);
bool found_end_of_line = false;
bool found_start_of_infix_op = false;
bool found_bracket_end = false;
uint32_t indent_length = lexer->get_column(lexer);
for (;;) {
if (lexer->lookahead == '\n') {
found_end_of_line = true;
indent_length = 0;
skip(lexer);
} else if (lexer->lookahead == ' ') {
indent_length++;
skip(lexer);
} else if (lexer->lookahead == '\r' || lexer->lookahead == '\f') {
indent_length = 0;
skip(lexer);
} else if (lexer->lookahead == '\t') {
indent_length += 8;
skip(lexer);
} else if (lexer->eof(lexer)) {
found_end_of_line = true;
break;
} else {
break;
}
}
// printf("lexer->lookahead = %c\n", lexer->lookahead);
// printf("valid_symbols[INDENT] = %d\n", valid_symbols[INDENT]);
// printf("valid_symbols[DEDENT] = %d\n", valid_symbols[DEDENT]);
if (valid_symbols[NEWLINE] && lexer->lookahead == ';') {
advance(lexer);
lexer->mark_end(lexer);
lexer->result_symbol = NEWLINE;
return true;
}
if (valid_symbols[THEN] && lexer->lookahead == 't') {
advance(lexer);
if (lexer->lookahead == 'h') {
advance(lexer);
if (lexer->lookahead == 'e') {
advance(lexer);
if (lexer->lookahead == 'n') {
advance(lexer);
lexer->mark_end(lexer);
lexer->result_symbol = THEN;
return true;
}
}
}
return false;
} else if (lexer->lookahead == 'e' &&
(valid_symbols[ELSE] || valid_symbols[ELIF])) {
advance(lexer);
if (lexer->lookahead == 'l') {
advance(lexer);
if (lexer->lookahead == 's' && valid_symbols[ELSE]) {
advance(lexer);
if (lexer->lookahead == 'e') {
advance(lexer);
lexer->mark_end(lexer);
lexer->result_symbol = ELSE;
array_pop(&scanner->indents);
return true;
}
} else if (lexer->lookahead == 'i' && valid_symbols[ELIF]) {
advance(lexer);
if (lexer->lookahead == 'f') {
advance(lexer);
lexer->mark_end(lexer);
lexer->result_symbol = ELIF;
array_pop(&scanner->indents);
return true;
}
}
}
return false;
} else if (is_infix_op_start(lexer)) {
found_start_of_infix_op = true;
} else if (lexer->lookahead == '|') {
skip(lexer);
switch (lexer->lookahead) {
case ']':
case '}':
found_bracket_end = true;
break;
case ' ':
break;
default:
found_start_of_infix_op = true;
break;
}
} else if (is_bracket_end(lexer)) {
found_bracket_end = true;
}
if (error_recovery_mode && scanner->indents.size > 0) {
array_pop(&scanner->indents);
lexer->result_symbol = DEDENT;
return true;
}
if (valid_symbols[INDENT] && !found_start_of_infix_op && !found_bracket_end &&
!error_recovery_mode) {
array_push(&scanner->indents, indent_length);
lexer->result_symbol = INDENT;
return true;
}
if (scanner->indents.size > 0) {
uint16_t current_indent_length = *array_back(&scanner->indents);
if (found_bracket_end && valid_symbols[DEDENT]) {
array_pop(&scanner->indents);
lexer->result_symbol = DEDENT;
return true;
}
if (found_end_of_line) {
if (indent_length == current_indent_length && indent_length > 0 &&
!found_start_of_infix_op && !found_bracket_end) {
if (valid_symbols[NEWLINE] && !error_recovery_mode) {
lexer->result_symbol = NEWLINE;
return true;
}
}
if (indent_length < current_indent_length && !found_bracket_end) {
array_pop(&scanner->indents);
lexer->result_symbol = DEDENT;
return true;
}
}
}
if (valid_symbols[BLOCK_COMMENT_CONTENT] && !error_recovery_mode) {
lexer->mark_end(lexer);
while (true) {
if (lexer->lookahead == '\0') {
break;
}
if (lexer->lookahead != '(' && lexer->lookahead != '*') {
advance(lexer);
} else if (lexer->lookahead == '*') {
lexer->mark_end(lexer);
advance(lexer);
if (lexer->lookahead == ')') {
break;
}
} else if (scan_block_comment(lexer)) {
lexer->mark_end(lexer);
advance(lexer);
if (lexer->lookahead == '*') {
break;
}
}
}
lexer->result_symbol = BLOCK_COMMENT_CONTENT;
return true;
}
return false;
}
unsigned tree_sitter_fsharp_external_scanner_serialize(void *payload,
char *buffer) {
Scanner *scanner = (Scanner *)payload;
size_t size = 0;
uint32_t iter = 1;
for (; iter < scanner->indents.size &&
size < TREE_SITTER_SERIALIZATION_BUFFER_SIZE;
++iter) {
buffer[size++] = (char)*array_get(&scanner->indents, iter);
}
return size;
}
void tree_sitter_fsharp_external_scanner_deserialize(void *payload,
const char *buffer,
unsigned length) {
Scanner *scanner = (Scanner *)payload;
array_delete(&scanner->indents);
array_push(&scanner->indents, 0);
if (length > 0) {
size_t size = 0;
for (; size < length; size++) {
array_push(&scanner->indents, (unsigned char)buffer[size]);
}
}
}
void *tree_sitter_fsharp_external_scanner_create() {
Scanner *scanner = ts_calloc(1, sizeof(Scanner));
array_init(&scanner->indents);
tree_sitter_fsharp_external_scanner_deserialize(scanner, NULL, 0);
return scanner;
}
void tree_sitter_fsharp_external_scanner_destroy(void *payload) {
Scanner *scanner = (Scanner *)payload;
array_delete(&scanner->indents);
ts_free(scanner);
}

@ -1,54 +0,0 @@
#ifndef TREE_SITTER_ALLOC_H_
#define TREE_SITTER_ALLOC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// Allow clients to override allocation functions
#ifdef TREE_SITTER_REUSE_ALLOCATOR
extern void *(*ts_current_malloc)(size_t);
extern void *(*ts_current_calloc)(size_t, size_t);
extern void *(*ts_current_realloc)(void *, size_t);
extern void (*ts_current_free)(void *);
#ifndef ts_malloc
#define ts_malloc ts_current_malloc
#endif
#ifndef ts_calloc
#define ts_calloc ts_current_calloc
#endif
#ifndef ts_realloc
#define ts_realloc ts_current_realloc
#endif
#ifndef ts_free
#define ts_free ts_current_free
#endif
#else
#ifndef ts_malloc
#define ts_malloc malloc
#endif
#ifndef ts_calloc
#define ts_calloc calloc
#endif
#ifndef ts_realloc
#define ts_realloc realloc
#endif
#ifndef ts_free
#define ts_free free
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_ALLOC_H_

@ -1,290 +0,0 @@
#ifndef TREE_SITTER_ARRAY_H_
#define TREE_SITTER_ARRAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "./alloc.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
#pragma warning(disable : 4101)
#elif defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
#define Array(T) \
struct { \
T *contents; \
uint32_t size; \
uint32_t capacity; \
}
/// Initialize an array.
#define array_init(self) \
((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
/// Create an empty array.
#define array_new() \
{ NULL, 0, 0 }
/// Get a pointer to the element at a given `index` in the array.
#define array_get(self, _index) \
(assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
/// Get a pointer to the first element in the array.
#define array_front(self) array_get(self, 0)
/// Get a pointer to the last element in the array.
#define array_back(self) array_get(self, (self)->size - 1)
/// Clear the array, setting its size to zero. Note that this does not free any
/// memory allocated for the array's contents.
#define array_clear(self) ((self)->size = 0)
/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
/// less than the array's current capacity, this function has no effect.
#define array_reserve(self, new_capacity) \
_array__reserve((Array *)(self), array_elem_size(self), new_capacity)
/// Free any memory allocated for this array. Note that this does not free any
/// memory allocated for the array's contents.
#define array_delete(self) _array__delete((Array *)(self))
/// Push a new `element` onto the end of the array.
#define array_push(self, element) \
(_array__grow((Array *)(self), 1, array_elem_size(self)), \
(self)->contents[(self)->size++] = (element))
/// Increase the array's size by `count` elements.
/// New elements are zero-initialized.
#define array_grow_by(self, count) \
do { \
if ((count) == 0) break; \
_array__grow((Array *)(self), count, array_elem_size(self)); \
memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
(self)->size += (count); \
} while (0)
/// Append all elements from one array to the end of another.
#define array_push_all(self, other) \
array_extend((self), (other)->size, (other)->contents)
/// Append `count` elements to the end of the array, reading their values from the
/// `contents` pointer.
#define array_extend(self, count, contents) \
_array__splice( \
(Array *)(self), array_elem_size(self), (self)->size, \
0, count, contents \
)
/// Remove `old_count` elements from the array starting at the given `index`. At
/// the same index, insert `new_count` new elements, reading their values from the
/// `new_contents` pointer.
#define array_splice(self, _index, old_count, new_count, new_contents) \
_array__splice( \
(Array *)(self), array_elem_size(self), _index, \
old_count, new_count, new_contents \
)
/// Insert one `element` into the array at the given `index`.
#define array_insert(self, _index, element) \
_array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element))
/// Remove one element from the array at the given `index`.
#define array_erase(self, _index) \
_array__erase((Array *)(self), array_elem_size(self), _index)
/// Pop the last element off the array, returning the element by value.
#define array_pop(self) ((self)->contents[--(self)->size])
/// Assign the contents of one array to another, reallocating if necessary.
#define array_assign(self, other) \
_array__assign((Array *)(self), (const Array *)(other), array_elem_size(self))
/// Swap one array with another
#define array_swap(self, other) \
_array__swap((Array *)(self), (Array *)(other))
/// Get the size of the array contents
#define array_elem_size(self) (sizeof *(self)->contents)
/// Search a sorted array for a given `needle` value, using the given `compare`
/// callback to determine the order.
///
/// If an existing element is found to be equal to `needle`, then the `index`
/// out-parameter is set to the existing value's index, and the `exists`
/// out-parameter is set to true. Otherwise, `index` is set to an index where
/// `needle` should be inserted in order to preserve the sorting, and `exists`
/// is set to false.
#define array_search_sorted_with(self, compare, needle, _index, _exists) \
_array__search_sorted(self, 0, compare, , needle, _index, _exists)
/// Search a sorted array for a given `needle` value, using integer comparisons
/// of a given struct field (specified with a leading dot) to determine the order.
///
/// See also `array_search_sorted_with`.
#define array_search_sorted_by(self, field, needle, _index, _exists) \
_array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)
/// Insert a given `value` into a sorted array, using the given `compare`
/// callback to determine the order.
#define array_insert_sorted_with(self, compare, value) \
do { \
unsigned _index, _exists; \
array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
if (!_exists) array_insert(self, _index, value); \
} while (0)
/// Insert a given `value` into a sorted array, using integer comparisons of
/// a given struct field (specified with a leading dot) to determine the order.
///
/// See also `array_search_sorted_by`.
#define array_insert_sorted_by(self, field, value) \
do { \
unsigned _index, _exists; \
array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
if (!_exists) array_insert(self, _index, value); \
} while (0)
// Private
typedef Array(void) Array;
/// This is not what you're looking for, see `array_delete`.
static inline void _array__delete(Array *self) {
if (self->contents) {
ts_free(self->contents);
self->contents = NULL;
self->size = 0;
self->capacity = 0;
}
}
/// This is not what you're looking for, see `array_erase`.
static inline void _array__erase(Array *self, size_t element_size,
uint32_t index) {
assert(index < self->size);
char *contents = (char *)self->contents;
memmove(contents + index * element_size, contents + (index + 1) * element_size,
(self->size - index - 1) * element_size);
self->size--;
}
/// This is not what you're looking for, see `array_reserve`.
static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) {
if (new_capacity > self->capacity) {
if (self->contents) {
self->contents = ts_realloc(self->contents, new_capacity * element_size);
} else {
self->contents = ts_malloc(new_capacity * element_size);
}
self->capacity = new_capacity;
}
}
/// This is not what you're looking for, see `array_assign`.
static inline void _array__assign(Array *self, const Array *other, size_t element_size) {
_array__reserve(self, element_size, other->size);
self->size = other->size;
memcpy(self->contents, other->contents, self->size * element_size);
}
/// This is not what you're looking for, see `array_swap`.
static inline void _array__swap(Array *self, Array *other) {
Array swap = *other;
*other = *self;
*self = swap;
}
/// This is not what you're looking for, see `array_push` or `array_grow_by`.
static inline void _array__grow(Array *self, uint32_t count, size_t element_size) {
uint32_t new_size = self->size + count;
if (new_size > self->capacity) {
uint32_t new_capacity = self->capacity * 2;
if (new_capacity < 8) new_capacity = 8;
if (new_capacity < new_size) new_capacity = new_size;
_array__reserve(self, element_size, new_capacity);
}
}
/// This is not what you're looking for, see `array_splice`.
static inline void _array__splice(Array *self, size_t element_size,
uint32_t index, uint32_t old_count,
uint32_t new_count, const void *elements) {
uint32_t new_size = self->size + new_count - old_count;
uint32_t old_end = index + old_count;
uint32_t new_end = index + new_count;
assert(old_end <= self->size);
_array__reserve(self, element_size, new_size);
char *contents = (char *)self->contents;
if (self->size > old_end) {
memmove(
contents + new_end * element_size,
contents + old_end * element_size,
(self->size - old_end) * element_size
);
}
if (new_count > 0) {
if (elements) {
memcpy(
(contents + index * element_size),
elements,
new_count * element_size
);
} else {
memset(
(contents + index * element_size),
0,
new_count * element_size
);
}
}
self->size += new_count - old_count;
}
/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.
#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
do { \
*(_index) = start; \
*(_exists) = false; \
uint32_t size = (self)->size - *(_index); \
if (size == 0) break; \
int comparison; \
while (size > 1) { \
uint32_t half_size = size / 2; \
uint32_t mid_index = *(_index) + half_size; \
comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
if (comparison <= 0) *(_index) = mid_index; \
size -= half_size; \
} \
comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
if (comparison == 0) *(_exists) = true; \
else if (comparison < 0) *(_index) += 1; \
} while (0)
/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
/// parameter by reference in order to work with the generic sorting function above.
#define _compare_int(a, b) ((int)*(a) - (int)(b))
#ifdef _MSC_VER
#pragma warning(default : 4101)
#elif defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_ARRAY_H_

@ -1,230 +0,0 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSStateId;
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#ifdef _MSC_VER
#define UNUSED __pragma(warning(suppress : 4101))
#else
#define UNUSED __attribute__((unused))
#endif
#define START_LEXER() \
bool result = false; \
bool skip = false; \
UNUSED \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = (state_value) \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = (state_value), \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

@ -1,292 +0,0 @@
================================================================================
top-level module attribute
================================================================================
[<AutoOpen>]
module test =
let x = 4
--------------------------------------------------------------------------------
(file
(module_defn
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
top-level module attributes repeated
================================================================================
[<A;B;C>]
module test =
let x = 4
--------------------------------------------------------------------------------
(file
(module_defn
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))
(attribute
(object_construction
(type
(long_identifier
(identifier)))))
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
top-level module attributes separate
================================================================================
[<A>]
[<B;C>]
module test =
let x = 4
--------------------------------------------------------------------------------
(file
(module_defn
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier))))))
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
top-level class attribute
================================================================================
[<Route("test")>]
type A() =
do ()
--------------------------------------------------------------------------------
(file
(type_definition
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))
(paren_expression
(const
(string)))))))
(anon_type_defn
(type_name
(identifier))
(primary_constr_args)
(const
(unit)))))
================================================================================
attribute on let binding
================================================================================
[<AutoOpen>]
module Constants =
[<Literal>]
let A = "A"
[<Literal>]
let B = "B"
module Impl =
let v = A + B
--------------------------------------------------------------------------------
(file
(module_defn
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(identifier)
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string))))
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string)))))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(long_identifier_or_op
(long_identifier
(identifier))))))))
================================================================================
attribute on let binding in namespace
================================================================================
namespace Com.Test
[<AutoOpen>]
module Constants =
[<Literal>]
let A = "A"
[<Literal>]
let B = "B"
module Impl =
let x = A + B
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier)
(identifier))
(module_defn
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(identifier)
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string))))
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string)))))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(long_identifier_or_op
(long_identifier
(identifier)))))))))

@ -1,249 +0,0 @@
================================================================================
line comment
================================================================================
// comment
let x = 1
--------------------------------------------------------------------------------
(file
(line_comment)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const (int)))))
================================================================================
block comment
================================================================================
(* comment *)
let x = 1
--------------------------------------------------------------------------------
(file
(block_comment
(block_comment_content))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const (int)))))
================================================================================
multi-line block comment
================================================================================
(*
* comment
*)
let x = 1
--------------------------------------------------------------------------------
(file
(block_comment
(block_comment_content))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const (int)))))
================================================================================
docstring
================================================================================
/// <c>code</c>
let x = 1
--------------------------------------------------------------------------------
(file
(xml_doc
(xml_doc_content))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const (int)))))
================================================================================
comment in simple string
================================================================================
let x = "//comment in string"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string)))))
================================================================================
comment in triple-quoted string
================================================================================
let x = """
//comment in string
"""
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(triple_quoted_string)))))
================================================================================
comment in verbatim string
================================================================================
let x = @"//comment in string"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(verbatim_string)))))
================================================================================
xml docstring
================================================================================
/// <summary>
/// super important function
/// </summary>
let f x = x + 1
--------------------------------------------------------------------------------
(file
(xml_doc
(xml_doc_content))
(xml_doc
(xml_doc_content))
(xml_doc
(xml_doc_content))
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const
(int))))))
================================================================================
json payload in multi-line string
================================================================================
namespace test
module Json =
[<Literal>]
let MyPayload =
"""
{
"prop1": []
"prop2": {
"prop3": true,
"prop4": 1,
},
}
"""
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(module_defn
(identifier)
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(triple_quoted_string)))))))
================================================================================
json payload in multi-line format string
================================================================================
namespace test
module Json =
let myPayloadBuilder x =
$"""
{
"prop1": []
"prop2": {
"prop3": {x},
"prop4": 1,
},
}
"""
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(const
(triple_quoted_string
(format_triple_quoted_string))))))))

@ -1,11 +0,0 @@
================================================================================
basic compiler directive
================================================================================
#nowarn "42"
--------------------------------------------------------------------------------
(file
(compiler_directive_decl
(string)))

@ -1,489 +0,0 @@
================================================================================
simple string
================================================================================
let x = "test"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string)))))
================================================================================
verbatim string
================================================================================
let x = @"\"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(verbatim_string)))))
================================================================================
int
================================================================================
let x = 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int)))))
================================================================================
int64
================================================================================
let x = 1L
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int64
(int))))))
================================================================================
int32
================================================================================
let x = 1l
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int32
(int))))))
================================================================================
int16
================================================================================
let x = 1s
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int16
(int))))))
================================================================================
sbyte
================================================================================
let x = 1y
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(sbyte
(int))))))
================================================================================
byte
================================================================================
let x = 1uy
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(byte
(int))))))
================================================================================
uint16
================================================================================
let x = 1us
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(uint16
(int))))))
================================================================================
uint32
================================================================================
let x = 1u
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(uint32
(int))))))
================================================================================
uint32 alternative
================================================================================
let x = 1ul
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(uint32
(int))))))
================================================================================
uint64
================================================================================
let x = 1UL
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(uint64
(int))))))
================================================================================
uint64 alternative
================================================================================
let x = 1uL
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(uint64
(int))))))
================================================================================
nativeint
================================================================================
do
1n
0b1n
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(const
(nativeint
(int)))
(const
(nativeint
(xint)))))))
================================================================================
unativeint
================================================================================
do
1un
0b1un
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(const
(unativeint
(int)))
(const
(unativeint
(xint)))))))
================================================================================
ieee32
================================================================================
let x = 1.f
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(ieee32
(float))))))
================================================================================
ieee32 alternative
================================================================================
let x = 0b1lf
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(ieee32
(xint))))))
================================================================================
ieee64
================================================================================
let x = 0b0LF
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(ieee64
(xint))))))
================================================================================
bignum
================================================================================
do
1Q
1R
1Z
1I
1N
1G
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(const
(bignum
(int)))
(sequential_expression
(const
(bignum
(int)))
(sequential_expression
(const
(bignum
(int)))
(sequential_expression
(const
(bignum
(int)))
(sequential_expression
(const
(bignum
(int)))
(const
(bignum
(int)))))))))))
================================================================================
decimal
================================================================================
do
1.0M
1.M
1M
1.0m
1.m
1m
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(const
(decimal
(float)))
(sequential_expression
(const
(decimal
(float)))
(sequential_expression
(const
(decimal
(int)))
(sequential_expression
(const
(decimal
(float)))
(sequential_expression
(const
(decimal
(float)))
(const
(decimal
(int)))))))))))
================================================================================
string with escaped quote
================================================================================
let str = "name: \"name\""
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string)))))
================================================================================
format string
================================================================================
let x =
$"int: {2 + 2}"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(string
(format_string
(format_string_eval
(infix_expression
(const
(int))
(infix_op)
(const
(int))))))))))
================================================================================
triple quoted format string
================================================================================
let x =
$"""int: {2 + 2}"""
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(triple_quoted_string
(format_triple_quoted_string))))))

File diff suppressed because it is too large Load Diff

@ -1,37 +0,0 @@
===
refer dll
===
#r "path/to/MyAssembly.dll"
---
(file
(fsi_directive_decl
(string)))
===
refer nuget package
===
#r "path/to/MyAssembly.dll"
---
(file
(fsi_directive_decl
(string)))
===
load script
===
#load "Script1.fsx"
---
(file
(fsi_directive_decl
(string)))

@ -1,259 +0,0 @@
================================================================================
basic constant function
================================================================================
let functionName x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
body: (const
(int)))))
================================================================================
basic constant function inline
================================================================================
let inline functionName x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
body: (const
(int)))))
================================================================================
basic private constant function
================================================================================
let private functionName x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(access_modifier)
(identifier)
(argument_patterns
(long_identifier
(identifier))))
body: (const
(int)))))
================================================================================
private rec function
================================================================================
let rec private functionName x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(access_modifier)
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(const
(int)))))
================================================================================
mutual rec function
================================================================================
let rec private f1 x = f2 x
and f2 y = y + 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(access_modifier)
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier))))
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const
(int))))))
================================================================================
basic private constant function inline
================================================================================
let inline private functionName x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(access_modifier)
(identifier)
(argument_patterns
(long_identifier
(identifier))))
body: (const
(int)))))
================================================================================
basic function with srt constraint (old-style, with ^)
================================================================================
let inline double<^a when ^a:(member Double: unit -> ^a)> (x: ^a) = x.Double()
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(type_arguments
(type_argument_defn
(type_argument
(identifier)))
(type_argument_constraints
(constraint
(static_type_argument
(identifier))
(trait_member_constraint
(identifier)
(type
(type
(long_identifier
(identifier)))
(type
(type_argument
(identifier))))))))
(argument_patterns
(typed_pattern
(identifier_pattern
(long_identifier
(identifier)))
(type
(type_argument
(identifier))))))
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)
(identifier)))))))
================================================================================
basic function with srt constraint (new-style, with ')
================================================================================
let inline double<'a when 'a:(member Double: unit -> 'a)> (x: 'a) = x.Double()
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(type_arguments
(type_argument_defn
(type_argument
(identifier)))
(type_argument_constraints
(constraint
(static_type_argument
(identifier))
(trait_member_constraint
(identifier)
(type
(type
(long_identifier
(identifier)))
(type
(type_argument
(identifier))))))))
(argument_patterns
(typed_pattern
(identifier_pattern
(long_identifier
(identifier)))
(type
(type_argument
(identifier))))))
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)
(identifier)))))))
================================================================================
function decl should be preferred over value decl
================================================================================
namespace Test
module Program =
[<EntryPoint>]
let main args =
()
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(module_defn
(identifier)
(value_declaration
(attributes
(attribute_set
(attribute
(object_construction
(type
(long_identifier
(identifier)))))))
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(const
(unit)))))))

@ -1,87 +0,0 @@
================================================================================
basic ident
================================================================================
do sample
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(long_identifier_or_op
(long_identifier
(identifier))))))
================================================================================
ident with numbers
================================================================================
do wh0ar3y0u
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(long_identifier_or_op
(long_identifier
(identifier))))))
================================================================================
tick ident
================================================================================
do ``I can have anything in here ASDFAS?DFS``
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(long_identifier_or_op
(long_identifier
(identifier))))))
================================================================================
ident with leading _
================================================================================
do _yo
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(long_identifier_or_op
(long_identifier
(identifier))))))
================================================================================
long ident
================================================================================
module test = foo.bar.baz
--------------------------------------------------------------------------------
(file
(module_abbrev
(identifier)
(long_identifier
(identifier)
(identifier)
(identifier))))
================================================================================
long ident with tick
================================================================================
module _ = foo.bar.``baz``
--------------------------------------------------------------------------------
(file
(module_abbrev
(identifier)
(long_identifier
(identifier)
(identifier)
(identifier))))

@ -1,23 +0,0 @@
===
basic import
===
open test
---
(file
(import_decl
(long_identifier (identifier))))
===
basic import long identifier
===
open Mod.Test
---
(file
(import_decl
(long_identifier (identifier) (identifier))))

@ -1,253 +0,0 @@
================================================================================
basic module with indent
================================================================================
module test =
let x = 4
--------------------------------------------------------------------------------
(file
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic module with large indent
================================================================================
module test =
let x = 4
--------------------------------------------------------------------------------
(file
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic module with multiple elements
================================================================================
module test =
let x = 4
let y = 5
--------------------------------------------------------------------------------
(file
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
top-level module with multiple elements
================================================================================
module Test
let x = 4
let y = 5
--------------------------------------------------------------------------------
(file
(named_module
name: (long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
body: (const
(int))))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
body: (const
(int))))))
================================================================================
namespace open
================================================================================
namespace Test.A
open B
open X.Y
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier)
(identifier))
(import_decl
(long_identifier (identifier)))
(import_decl
(long_identifier
(identifier)
(identifier)))))
================================================================================
multiple modules in namespace
================================================================================
namespace Test
module A =
let x = ()
module B =
let x = ()
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit)))))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit)))))))
================================================================================
multiple modules in top-level module
================================================================================
module Test
module A =
let x = ()
module B =
let x = ()
--------------------------------------------------------------------------------
(file
(named_module
(long_identifier
(identifier))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit)))))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit)))))))
================================================================================
multiple modules in anonymous module
================================================================================
module A =
let x = ()
module B =
let x = ()
--------------------------------------------------------------------------------
(file
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit)))))
(module_defn
(identifier)
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(unit))))))
================================================================================
top-level expression in module
================================================================================
module A =
()
--------------------------------------------------------------------------------
(file
(module_defn
(identifier)
(const
(unit))))

@ -1,13 +0,0 @@
===
basic module abbreviation
===
module local = Mod.local
---
(file
(module_abbrev
(identifier)
(long_identifier (identifier) (identifier))))

@ -1,72 +0,0 @@
================================================================================
basic comparison
================================================================================
do
1 < 2
1 <= 2
2 > 1
2 <> 1
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(infix_expression
(const (int))
(infix_op)
(const (int)))
(sequential_expression
(infix_expression
(const (int))
(infix_op)
(const (int)))
(sequential_expression
(infix_expression
(const (int))
(infix_op)
(const (int)))
(infix_expression
(const (int))
(infix_op)
(const (int)))))))))
================================================================================
prefix operator
================================================================================
do
!!"str"
~"str"
!*"str"
~~"str"
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(sequential_expression
(prefixed_expression
(prefix_op)
(const
(string)))
(sequential_expression
(prefixed_expression
(prefix_op)
(const
(string)))
(sequential_expression
(prefixed_expression
(prefix_op)
(const
(string)))
(prefixed_expression
(prefix_op)
(prefixed_expression
(prefix_op)
(const
(string))))))))))

@ -1,79 +0,0 @@
================================================================================
constant pattern
================================================================================
let x = 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern (long_identifier (identifier))))
(const (int)))))
================================================================================
tuple pattern
================================================================================
let (x,y) = (1,2)
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(paren_pattern
(repeat_pattern
(identifier_pattern (long_identifier (identifier)))
(identifier_pattern (long_identifier (identifier))))))
(paren_expression
(tuple_expression
(const (int))
(const (int)))))))
================================================================================
typed pattern
================================================================================
let name (x : int) = 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(typed_pattern
(identifier_pattern (long_identifier (identifier)))
(type (long_identifier (identifier))))))
(const (int)))))
================================================================================
typed tuple pattern
================================================================================
let name (x: int, y: string) = 1, "test"
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(repeat_pattern
(typed_pattern
(identifier_pattern (long_identifier (identifier)))
(type (long_identifier (identifier))))
(typed_pattern
(identifier_pattern (long_identifier (identifier)))
(type (long_identifier (identifier)))))))
(tuple_expression
(const (int))
(const (string))))))

@ -1,229 +0,0 @@
================================================================================
function definition on same line should end scope
================================================================================
let f x = x + 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const (int))))))
================================================================================
function definition on new line should open scope
================================================================================
let f x =
x + 1
1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(sequential_expression
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const (int)))
(const (int))))))
================================================================================
function definition aligned to first line should scope correctly
================================================================================
let f x = x + 1
1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(sequential_expression
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const (int)))
(const (int))))))
================================================================================
call expression with underindentation
================================================================================
do
Serializer(
1,
2,
3
)
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(tuple_expression
(tuple_expression
(const (int))
(const (int)))
(const (int)))))))
================================================================================
declaration expression should contain all sequential expressions
================================================================================
let f x =
let y = x + 1
printfn y
printfn y
printfn y
printfn y
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(function_declaration_left
(identifier)
(argument_patterns
(long_identifier
(identifier))))
(declaration_expression
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(infix_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(infix_op)
(const
(int))))
(sequential_expression
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier))))
(sequential_expression
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier))))
(sequential_expression
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier))))
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier)))))))))))
================================================================================
for-loop in else branch
================================================================================
do
if b then
()
else
for x in xs do
()
()
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(if_expression
(long_identifier_or_op
(long_identifier
(identifier)))
(const
(unit))
(sequential_expression
(for_expression
(identifier_pattern
(long_identifier
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier)))
(const
(unit)))
(const
(unit)))))))
================================================================================
prefix associativity
================================================================================
do
return ctx.Ok message :> IAction
--------------------------------------------------------------------------------
(file
(value_declaration
(do
(prefixed_expression
(typecast_expression
(application_expression
(long_identifier_or_op
(long_identifier
(identifier)
(identifier)))
(long_identifier_or_op
(long_identifier
(identifier))))
(type
(long_identifier
(identifier))))))))

@ -1,176 +0,0 @@
================================================================================
basic anonymous module
================================================================================
let x = 4
--------------------------------------------------------------------------------
(file
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int)))))
================================================================================
basic named module
================================================================================
module Test
let x = 4
--------------------------------------------------------------------------------
(file
(named_module
(long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
named module with whitespace
================================================================================
module Test
let x = 4
--------------------------------------------------------------------------------
(file
(named_module
(long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
named module lowercase
================================================================================
module test
let x = 4
--------------------------------------------------------------------------------
(file
(named_module
(long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic namespace
================================================================================
namespace test
let x = 4
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic global namespace
================================================================================
namespace global
let x = 4
--------------------------------------------------------------------------------
(file
(namespace
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic recursive namespace
================================================================================
namespace rec test
let x = 4
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))
================================================================================
basic long namespace
================================================================================
namespace test.val
let x = 4
--------------------------------------------------------------------------------
(file
(namespace
(long_identifier
(identifier)
(identifier))
(value_declaration
(function_or_value_defn
(value_declaration_left
(identifier_pattern
(long_identifier
(identifier))))
(const
(int))))))

File diff suppressed because it is too large Load Diff

@ -1,8 +0,0 @@
let f x = x + 1
// <- keyword.function
// ^ function
// ^ variable.parameter
// ^ operator
// ^ variable
// ^ operator
// ^ number

@ -1,9 +0,0 @@
#r "nuget: FSharp.Compiler.Service, 43.7.300"
//<- keyword.import
// ^ string
#r "/home/bin/MyApp.dll"
//<- keyword.import
// ^ string
#load "Strings.fsx"
//<- keyword.import
// ^ string

@ -1,7 +0,0 @@
let str = $"2 + 2 = {2 + 2}"
//<- keyword.function
// ^ variable
// ^ string
// ^ number
// ^ number
// ^ string

@ -1,8 +0,0 @@
type A() =
//<- keyword.type
// ^ type.definition
member this.F(x) = ()
//^ keyword.function
// ^ variable.parameter.builtin
// ^ variable.member
// ^ variable