diff --git a/Cargo.lock b/Cargo.lock index c648e2379c..5b6fffaa49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -576,6 +576,7 @@ dependencies = [ "anyhow", "async-task 4.0.3 (git+https://github.com/zedit-io/async-task?rev=341b57d6de98cdfd7b418567b8de2022ca993a6e)", "bindgen", + "cc", "cocoa", "core-foundation", "core-text", diff --git a/gpui/Cargo.toml b/gpui/Cargo.toml index 1e77e4b139..e1451fe22d 100644 --- a/gpui/Cargo.toml +++ b/gpui/Cargo.toml @@ -15,6 +15,7 @@ tree-sitter = "0.17" [build-dependencies] bindgen = "0.57" +cc = "1.0.67" [target.'cfg(target_os = "macos")'.dependencies] anyhow = "1" diff --git a/gpui/build.rs b/gpui/build.rs index 82a5c82617..935571f40c 100644 --- a/gpui/build.rs +++ b/gpui/build.rs @@ -2,6 +2,7 @@ use std::{env, path::PathBuf}; fn main() { generate_dispatch_bindings(); + compile_context_predicate_parser(); } fn generate_dispatch_bindings() { @@ -21,3 +22,14 @@ fn generate_dispatch_bindings() { .write_to_file(out_path.join("dispatch_sys.rs")) .expect("couldn't write bindings"); } + +fn compile_context_predicate_parser() { + let dir = PathBuf::from("./grammars/context-predicate/src"); + let parser_c = dir.join("parser.c"); + + println!("cargo:rerun-if-changed={}", &parser_c.to_str().unwrap()); + cc::Build::new() + .include(&dir) + .file(parser_c) + .compile("tree_sitter_context_predicate"); +} diff --git a/gpui/grammars/context-predicate/.gitignore b/gpui/grammars/context-predicate/.gitignore new file mode 100644 index 0000000000..563ba71918 --- /dev/null +++ b/gpui/grammars/context-predicate/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/build \ No newline at end of file diff --git a/gpui/grammars/context-predicate/binding.gyp b/gpui/grammars/context-predicate/binding.gyp new file mode 100644 index 0000000000..456116d62b --- /dev/null +++ b/gpui/grammars/context-predicate/binding.gyp @@ -0,0 +1,18 @@ +{ + "targets": [ + { + "target_name": "tree_sitter_context_predicate_binding", + "include_dirs": [ + " $._expression, + + _expression: $ => choice( + $.identifier, + $.not, + $.and, + $.or, + $.equal, + $.not_equal, + $.parenthesized, + ), + + identifier: $ => /[A-Za-z0-9_-]+/, + + not: $ => prec(3, seq("!", field("expression", $._expression))), + + and: $ => prec.left(2, seq(field("left", $._expression), "&&", field("right", $._expression))), + + or: $ => prec.left(1, seq(field("left", $._expression), "||", field("right", $._expression))), + + equal: $ => seq(field("left", $.identifier), "==", field("right", $.identifier)), + + not_equal: $ => seq(field("left", $.identifier), "!=", field("right", $.identifier)), + + parenthesized: $ => seq("(", field("expression", $._expression), ")"), + } +}); diff --git a/gpui/grammars/context-predicate/index.js b/gpui/grammars/context-predicate/index.js new file mode 100644 index 0000000000..1be86370cd --- /dev/null +++ b/gpui/grammars/context-predicate/index.js @@ -0,0 +1,13 @@ +try { + module.exports = require("./build/Release/tree_sitter_context_predicate_binding"); +} catch (error) { + try { + module.exports = require("./build/Debug/tree_sitter_context_predicate_binding"); + } catch (_) { + throw error + } +} + +try { + module.exports.nodeTypeInfo = require("./src/node-types.json"); +} catch (_) { } diff --git a/gpui/grammars/context-predicate/package-lock.json b/gpui/grammars/context-predicate/package-lock.json new file mode 100644 index 0000000000..d068dc0228 --- /dev/null +++ b/gpui/grammars/context-predicate/package-lock.json @@ -0,0 +1,44 @@ +{ + "name": "tree-sitter-context-predicate", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "tree-sitter-context-predicate", + "dependencies": { + "nan": "^2.14.0" + }, + "devDependencies": { + "tree-sitter-cli": "^0.18.3" + } + }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "node_modules/tree-sitter-cli": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.18.3.tgz", + "integrity": "sha512-ntN8Siljy7dlazb4cSYtZCfibaNppIy6RIr/XGt44GW1hAy/yuTLtKVi4kqYlImB4/7H0AjktcSlQRmI8zLNng==", + "dev": true, + "hasInstallScript": true, + "bin": { + "tree-sitter": "cli.js" + } + } + }, + "dependencies": { + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "tree-sitter-cli": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.18.3.tgz", + "integrity": "sha512-ntN8Siljy7dlazb4cSYtZCfibaNppIy6RIr/XGt44GW1hAy/yuTLtKVi4kqYlImB4/7H0AjktcSlQRmI8zLNng==", + "dev": true + } + } +} diff --git a/gpui/grammars/context-predicate/package.json b/gpui/grammars/context-predicate/package.json new file mode 100644 index 0000000000..a14e9d0145 --- /dev/null +++ b/gpui/grammars/context-predicate/package.json @@ -0,0 +1,10 @@ +{ + "name": "tree-sitter-context-predicate", + "main": "index.js", + "devDependencies": { + "tree-sitter-cli": "^0.18.3" + }, + "dependencies": { + "nan": "^2.14.0" + } +} diff --git a/gpui/grammars/context-predicate/src/binding.cc b/gpui/grammars/context-predicate/src/binding.cc new file mode 100644 index 0000000000..9a3df4b028 --- /dev/null +++ b/gpui/grammars/context-predicate/src/binding.cc @@ -0,0 +1,28 @@ +#include "tree_sitter/parser.h" +#include +#include "nan.h" + +using namespace v8; + +extern "C" TSLanguage * tree_sitter_context_predicate(); + +namespace { + +NAN_METHOD(New) {} + +void Init(Local exports, Local module) { + Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Language").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + Local constructor = Nan::GetFunction(tpl).ToLocalChecked(); + Local instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked(); + Nan::SetInternalFieldPointer(instance, 0, tree_sitter_context_predicate()); + + Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("context_predicate").ToLocalChecked()); + Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance); +} + +NODE_MODULE(tree_sitter_context_predicate_binding, Init) + +} // namespace diff --git a/gpui/grammars/context-predicate/src/grammar.json b/gpui/grammars/context-predicate/src/grammar.json new file mode 100644 index 0000000000..9ccb50fe79 --- /dev/null +++ b/gpui/grammars/context-predicate/src/grammar.json @@ -0,0 +1,208 @@ +{ + "name": "context_predicate", + "rules": { + "source": { + "type": "SYMBOL", + "name": "_expression" + }, + "_expression": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "identifier" + }, + { + "type": "SYMBOL", + "name": "not" + }, + { + "type": "SYMBOL", + "name": "and" + }, + { + "type": "SYMBOL", + "name": "or" + }, + { + "type": "SYMBOL", + "name": "equal" + }, + { + "type": "SYMBOL", + "name": "not_equal" + }, + { + "type": "SYMBOL", + "name": "parenthesized" + } + ] + }, + "identifier": { + "type": "PATTERN", + "value": "[A-Za-z0-9_-]+" + }, + "not": { + "type": "PREC", + "value": 3, + "content": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "!" + }, + { + "type": "FIELD", + "name": "expression", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + } + ] + } + }, + "and": { + "type": "PREC_LEFT", + "value": 2, + "content": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "left", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + }, + { + "type": "STRING", + "value": "&&" + }, + { + "type": "FIELD", + "name": "right", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + } + ] + } + }, + "or": { + "type": "PREC_LEFT", + "value": 1, + "content": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "left", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + }, + { + "type": "STRING", + "value": "||" + }, + { + "type": "FIELD", + "name": "right", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + } + ] + } + }, + "equal": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "left", + "content": { + "type": "SYMBOL", + "name": "identifier" + } + }, + { + "type": "STRING", + "value": "==" + }, + { + "type": "FIELD", + "name": "right", + "content": { + "type": "SYMBOL", + "name": "identifier" + } + } + ] + }, + "not_equal": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "left", + "content": { + "type": "SYMBOL", + "name": "identifier" + } + }, + { + "type": "STRING", + "value": "!=" + }, + { + "type": "FIELD", + "name": "right", + "content": { + "type": "SYMBOL", + "name": "identifier" + } + } + ] + }, + "parenthesized": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "(" + }, + { + "type": "FIELD", + "name": "expression", + "content": { + "type": "SYMBOL", + "name": "_expression" + } + }, + { + "type": "STRING", + "value": ")" + } + ] + } + }, + "extras": [ + { + "type": "PATTERN", + "value": "\\s" + } + ], + "conflicts": [], + "precedences": [], + "externals": [], + "inline": [], + "supertypes": [] +} + diff --git a/gpui/grammars/context-predicate/src/node-types.json b/gpui/grammars/context-predicate/src/node-types.json new file mode 100644 index 0000000000..2e8868b1f1 --- /dev/null +++ b/gpui/grammars/context-predicate/src/node-types.json @@ -0,0 +1,353 @@ +[ + { + "type": "and", + "named": true, + "fields": { + "left": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + }, + "right": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + } + } + }, + { + "type": "equal", + "named": true, + "fields": { + "left": { + "multiple": false, + "required": true, + "types": [ + { + "type": "identifier", + "named": true + } + ] + }, + "right": { + "multiple": false, + "required": true, + "types": [ + { + "type": "identifier", + "named": true + } + ] + } + } + }, + { + "type": "not", + "named": true, + "fields": { + "expression": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + } + } + }, + { + "type": "not_equal", + "named": true, + "fields": { + "left": { + "multiple": false, + "required": true, + "types": [ + { + "type": "identifier", + "named": true + } + ] + }, + "right": { + "multiple": false, + "required": true, + "types": [ + { + "type": "identifier", + "named": true + } + ] + } + } + }, + { + "type": "or", + "named": true, + "fields": { + "left": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + }, + "right": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + } + } + }, + { + "type": "parenthesized", + "named": true, + "fields": { + "expression": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + } + } + }, + { + "type": "source", + "named": true, + "fields": {}, + "children": { + "multiple": false, + "required": true, + "types": [ + { + "type": "and", + "named": true + }, + { + "type": "equal", + "named": true + }, + { + "type": "identifier", + "named": true + }, + { + "type": "not", + "named": true + }, + { + "type": "not_equal", + "named": true + }, + { + "type": "or", + "named": true + }, + { + "type": "parenthesized", + "named": true + } + ] + } + }, + { + "type": "!", + "named": false + }, + { + "type": "!=", + "named": false + }, + { + "type": "&&", + "named": false + }, + { + "type": "(", + "named": false + }, + { + "type": ")", + "named": false + }, + { + "type": "==", + "named": false + }, + { + "type": "identifier", + "named": true + }, + { + "type": "||", + "named": false + } +] \ No newline at end of file diff --git a/gpui/grammars/context-predicate/src/parser.c b/gpui/grammars/context-predicate/src/parser.c new file mode 100644 index 0000000000..4bab2ea4dd --- /dev/null +++ b/gpui/grammars/context-predicate/src/parser.c @@ -0,0 +1,527 @@ +#include + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#define LANGUAGE_VERSION 12 +#define STATE_COUNT 18 +#define LARGE_STATE_COUNT 6 +#define SYMBOL_COUNT 17 +#define ALIAS_COUNT 0 +#define TOKEN_COUNT 9 +#define EXTERNAL_TOKEN_COUNT 0 +#define FIELD_COUNT 3 +#define MAX_ALIAS_SEQUENCE_LENGTH 3 + +enum { + sym_identifier = 1, + anon_sym_BANG = 2, + anon_sym_AMP_AMP = 3, + anon_sym_PIPE_PIPE = 4, + anon_sym_EQ_EQ = 5, + anon_sym_BANG_EQ = 6, + anon_sym_LPAREN = 7, + anon_sym_RPAREN = 8, + sym_source = 9, + sym__expression = 10, + sym_not = 11, + sym_and = 12, + sym_or = 13, + sym_equal = 14, + sym_not_equal = 15, + sym_parenthesized = 16, +}; + +static const char *ts_symbol_names[] = { + [ts_builtin_sym_end] = "end", + [sym_identifier] = "identifier", + [anon_sym_BANG] = "!", + [anon_sym_AMP_AMP] = "&&", + [anon_sym_PIPE_PIPE] = "||", + [anon_sym_EQ_EQ] = "==", + [anon_sym_BANG_EQ] = "!=", + [anon_sym_LPAREN] = "(", + [anon_sym_RPAREN] = ")", + [sym_source] = "source", + [sym__expression] = "_expression", + [sym_not] = "not", + [sym_and] = "and", + [sym_or] = "or", + [sym_equal] = "equal", + [sym_not_equal] = "not_equal", + [sym_parenthesized] = "parenthesized", +}; + +static TSSymbol ts_symbol_map[] = { + [ts_builtin_sym_end] = ts_builtin_sym_end, + [sym_identifier] = sym_identifier, + [anon_sym_BANG] = anon_sym_BANG, + [anon_sym_AMP_AMP] = anon_sym_AMP_AMP, + [anon_sym_PIPE_PIPE] = anon_sym_PIPE_PIPE, + [anon_sym_EQ_EQ] = anon_sym_EQ_EQ, + [anon_sym_BANG_EQ] = anon_sym_BANG_EQ, + [anon_sym_LPAREN] = anon_sym_LPAREN, + [anon_sym_RPAREN] = anon_sym_RPAREN, + [sym_source] = sym_source, + [sym__expression] = sym__expression, + [sym_not] = sym_not, + [sym_and] = sym_and, + [sym_or] = sym_or, + [sym_equal] = sym_equal, + [sym_not_equal] = sym_not_equal, + [sym_parenthesized] = sym_parenthesized, +}; + +static const TSSymbolMetadata ts_symbol_metadata[] = { + [ts_builtin_sym_end] = { + .visible = false, + .named = true, + }, + [sym_identifier] = { + .visible = true, + .named = true, + }, + [anon_sym_BANG] = { + .visible = true, + .named = false, + }, + [anon_sym_AMP_AMP] = { + .visible = true, + .named = false, + }, + [anon_sym_PIPE_PIPE] = { + .visible = true, + .named = false, + }, + [anon_sym_EQ_EQ] = { + .visible = true, + .named = false, + }, + [anon_sym_BANG_EQ] = { + .visible = true, + .named = false, + }, + [anon_sym_LPAREN] = { + .visible = true, + .named = false, + }, + [anon_sym_RPAREN] = { + .visible = true, + .named = false, + }, + [sym_source] = { + .visible = true, + .named = true, + }, + [sym__expression] = { + .visible = false, + .named = true, + }, + [sym_not] = { + .visible = true, + .named = true, + }, + [sym_and] = { + .visible = true, + .named = true, + }, + [sym_or] = { + .visible = true, + .named = true, + }, + [sym_equal] = { + .visible = true, + .named = true, + }, + [sym_not_equal] = { + .visible = true, + .named = true, + }, + [sym_parenthesized] = { + .visible = true, + .named = true, + }, +}; + +enum { + field_expression = 1, + field_left = 2, + field_right = 3, +}; + +static const char *ts_field_names[] = { + [0] = NULL, + [field_expression] = "expression", + [field_left] = "left", + [field_right] = "right", +}; + +static const TSFieldMapSlice ts_field_map_slices[3] = { + [1] = {.index = 0, .length = 1}, + [2] = {.index = 1, .length = 2}, +}; + +static const TSFieldMapEntry ts_field_map_entries[] = { + [0] = + {field_expression, 1}, + [1] = + {field_left, 0}, + {field_right, 2}, +}; + +static TSSymbol ts_alias_sequences[3][MAX_ALIAS_SEQUENCE_LENGTH] = { + [0] = {0}, +}; + +static uint16_t ts_non_terminal_alias_map[] = { + 0, +}; + +static bool ts_lex(TSLexer *lexer, TSStateId state) { + START_LEXER(); + eof = lexer->eof(lexer); + switch (state) { + case 0: + if (eof) ADVANCE(7); + if (lookahead == '!') ADVANCE(10); + if (lookahead == '&') ADVANCE(2); + if (lookahead == '(') ADVANCE(15); + if (lookahead == ')') ADVANCE(16); + if (lookahead == '=') ADVANCE(4); + if (lookahead == '|') ADVANCE(5); + if (lookahead == '\t' || + lookahead == '\n' || + lookahead == '\r' || + lookahead == ' ') SKIP(0) + if (lookahead == '-' || + ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); + END_STATE(); + case 1: + if (lookahead == '!') ADVANCE(9); + if (lookahead == '(') ADVANCE(15); + if (lookahead == '\t' || + lookahead == '\n' || + lookahead == '\r' || + lookahead == ' ') SKIP(1) + if (lookahead == '-' || + ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); + END_STATE(); + case 2: + if (lookahead == '&') ADVANCE(11); + END_STATE(); + case 3: + if (lookahead == '=') ADVANCE(14); + END_STATE(); + case 4: + if (lookahead == '=') ADVANCE(13); + END_STATE(); + case 5: + if (lookahead == '|') ADVANCE(12); + END_STATE(); + case 6: + if (eof) ADVANCE(7); + if (lookahead == '!') ADVANCE(3); + if (lookahead == '&') ADVANCE(2); + if (lookahead == ')') ADVANCE(16); + if (lookahead == '=') ADVANCE(4); + if (lookahead == '|') ADVANCE(5); + if (lookahead == '\t' || + lookahead == '\n' || + lookahead == '\r' || + lookahead == ' ') SKIP(6) + END_STATE(); + case 7: + ACCEPT_TOKEN(ts_builtin_sym_end); + END_STATE(); + case 8: + ACCEPT_TOKEN(sym_identifier); + if (lookahead == '-' || + ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); + END_STATE(); + case 9: + ACCEPT_TOKEN(anon_sym_BANG); + END_STATE(); + case 10: + ACCEPT_TOKEN(anon_sym_BANG); + if (lookahead == '=') ADVANCE(14); + END_STATE(); + case 11: + ACCEPT_TOKEN(anon_sym_AMP_AMP); + END_STATE(); + case 12: + ACCEPT_TOKEN(anon_sym_PIPE_PIPE); + END_STATE(); + case 13: + ACCEPT_TOKEN(anon_sym_EQ_EQ); + END_STATE(); + case 14: + ACCEPT_TOKEN(anon_sym_BANG_EQ); + END_STATE(); + case 15: + ACCEPT_TOKEN(anon_sym_LPAREN); + END_STATE(); + case 16: + ACCEPT_TOKEN(anon_sym_RPAREN); + END_STATE(); + default: + return false; + } +} + +static TSLexMode ts_lex_modes[STATE_COUNT] = { + [0] = {.lex_state = 0}, + [1] = {.lex_state = 1}, + [2] = {.lex_state = 1}, + [3] = {.lex_state = 1}, + [4] = {.lex_state = 1}, + [5] = {.lex_state = 1}, + [6] = {.lex_state = 6}, + [7] = {.lex_state = 0}, + [8] = {.lex_state = 0}, + [9] = {.lex_state = 0}, + [10] = {.lex_state = 0}, + [11] = {.lex_state = 0}, + [12] = {.lex_state = 0}, + [13] = {.lex_state = 0}, + [14] = {.lex_state = 0}, + [15] = {.lex_state = 0}, + [16] = {.lex_state = 0}, + [17] = {.lex_state = 0}, +}; + +static uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { + [0] = { + [ts_builtin_sym_end] = ACTIONS(1), + [sym_identifier] = ACTIONS(1), + [anon_sym_BANG] = ACTIONS(1), + [anon_sym_AMP_AMP] = ACTIONS(1), + [anon_sym_PIPE_PIPE] = ACTIONS(1), + [anon_sym_EQ_EQ] = ACTIONS(1), + [anon_sym_BANG_EQ] = ACTIONS(1), + [anon_sym_LPAREN] = ACTIONS(1), + [anon_sym_RPAREN] = ACTIONS(1), + }, + [1] = { + [sym_source] = STATE(15), + [sym__expression] = STATE(13), + [sym_not] = STATE(13), + [sym_and] = STATE(13), + [sym_or] = STATE(13), + [sym_equal] = STATE(13), + [sym_not_equal] = STATE(13), + [sym_parenthesized] = STATE(13), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [2] = { + [sym__expression] = STATE(7), + [sym_not] = STATE(7), + [sym_and] = STATE(7), + [sym_or] = STATE(7), + [sym_equal] = STATE(7), + [sym_not_equal] = STATE(7), + [sym_parenthesized] = STATE(7), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [3] = { + [sym__expression] = STATE(14), + [sym_not] = STATE(14), + [sym_and] = STATE(14), + [sym_or] = STATE(14), + [sym_equal] = STATE(14), + [sym_not_equal] = STATE(14), + [sym_parenthesized] = STATE(14), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [4] = { + [sym__expression] = STATE(11), + [sym_not] = STATE(11), + [sym_and] = STATE(11), + [sym_or] = STATE(11), + [sym_equal] = STATE(11), + [sym_not_equal] = STATE(11), + [sym_parenthesized] = STATE(11), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [5] = { + [sym__expression] = STATE(12), + [sym_not] = STATE(12), + [sym_and] = STATE(12), + [sym_or] = STATE(12), + [sym_equal] = STATE(12), + [sym_not_equal] = STATE(12), + [sym_parenthesized] = STATE(12), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, +}; + +static uint16_t ts_small_parse_table[] = { + [0] = 3, + ACTIONS(11), 1, + anon_sym_EQ_EQ, + ACTIONS(13), 1, + anon_sym_BANG_EQ, + ACTIONS(9), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [13] = 1, + ACTIONS(15), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [20] = 1, + ACTIONS(17), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [27] = 1, + ACTIONS(19), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [34] = 1, + ACTIONS(21), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [41] = 1, + ACTIONS(23), 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [48] = 2, + ACTIONS(27), 1, + anon_sym_AMP_AMP, + ACTIONS(25), 3, + ts_builtin_sym_end, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [57] = 3, + ACTIONS(27), 1, + anon_sym_AMP_AMP, + ACTIONS(29), 1, + ts_builtin_sym_end, + ACTIONS(31), 1, + anon_sym_PIPE_PIPE, + [67] = 3, + ACTIONS(27), 1, + anon_sym_AMP_AMP, + ACTIONS(31), 1, + anon_sym_PIPE_PIPE, + ACTIONS(33), 1, + anon_sym_RPAREN, + [77] = 1, + ACTIONS(35), 1, + ts_builtin_sym_end, + [81] = 1, + ACTIONS(37), 1, + sym_identifier, + [85] = 1, + ACTIONS(39), 1, + sym_identifier, +}; + +static uint32_t ts_small_parse_table_map[] = { + [SMALL_STATE(6)] = 0, + [SMALL_STATE(7)] = 13, + [SMALL_STATE(8)] = 20, + [SMALL_STATE(9)] = 27, + [SMALL_STATE(10)] = 34, + [SMALL_STATE(11)] = 41, + [SMALL_STATE(12)] = 48, + [SMALL_STATE(13)] = 57, + [SMALL_STATE(14)] = 67, + [SMALL_STATE(15)] = 77, + [SMALL_STATE(16)] = 81, + [SMALL_STATE(17)] = 85, +}; + +static TSParseActionEntry ts_parse_actions[] = { + [0] = {.entry = {.count = 0, .reusable = false}}, + [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), + [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(6), + [5] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), + [7] = {.entry = {.count = 1, .reusable = true}}, SHIFT(3), + [9] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym__expression, 1), + [11] = {.entry = {.count = 1, .reusable = true}}, SHIFT(16), + [13] = {.entry = {.count = 1, .reusable = true}}, SHIFT(17), + [15] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_not, 2, .production_id = 1), + [17] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_equal, 3, .production_id = 2), + [19] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_not_equal, 3, .production_id = 2), + [21] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_parenthesized, 3, .production_id = 1), + [23] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_and, 3, .production_id = 2), + [25] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_or, 3, .production_id = 2), + [27] = {.entry = {.count = 1, .reusable = true}}, SHIFT(4), + [29] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_source, 1), + [31] = {.entry = {.count = 1, .reusable = true}}, SHIFT(5), + [33] = {.entry = {.count = 1, .reusable = true}}, SHIFT(10), + [35] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), + [37] = {.entry = {.count = 1, .reusable = true}}, SHIFT(8), + [39] = {.entry = {.count = 1, .reusable = true}}, SHIFT(9), +}; + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _WIN32 +#define extern __declspec(dllexport) +#endif + +extern const TSLanguage *tree_sitter_context_predicate(void) { + static TSLanguage language = { + .version = LANGUAGE_VERSION, + .symbol_count = SYMBOL_COUNT, + .alias_count = ALIAS_COUNT, + .token_count = TOKEN_COUNT, + .external_token_count = EXTERNAL_TOKEN_COUNT, + .symbol_names = ts_symbol_names, + .symbol_metadata = ts_symbol_metadata, + .parse_table = (const uint16_t *)ts_parse_table, + .parse_actions = ts_parse_actions, + .lex_modes = ts_lex_modes, + .alias_sequences = (const TSSymbol *)ts_alias_sequences, + .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, + .lex_fn = ts_lex, + .field_count = FIELD_COUNT, + .field_map_slices = (const TSFieldMapSlice *)ts_field_map_slices, + .field_map_entries = (const TSFieldMapEntry *)ts_field_map_entries, + .field_names = ts_field_names, + .large_state_count = LARGE_STATE_COUNT, + .small_parse_table = (const uint16_t *)ts_small_parse_table, + .small_parse_table_map = (const uint32_t *)ts_small_parse_table_map, + .public_symbol_map = ts_symbol_map, + .alias_map = ts_non_terminal_alias_map, + .state_count = STATE_COUNT, + }; + return &language; +} +#ifdef __cplusplus +} +#endif diff --git a/gpui/grammars/context-predicate/src/tree_sitter/parser.h b/gpui/grammars/context-predicate/src/tree_sitter/parser.h new file mode 100644 index 0000000000..c5a788ff64 --- /dev/null +++ b/gpui/grammars/context-predicate/src/tree_sitter/parser.h @@ -0,0 +1,238 @@ +#ifndef TREE_SITTER_PARSER_H_ +#define TREE_SITTER_PARSER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#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 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 uint16_t TSStateId; + +typedef struct { + bool visible : 1; + bool named : 1; + bool supertype: 1; +} 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 struct { + union { + struct { + TSStateId state; + bool extra : 1; + bool repetition : 1; + } shift; + struct { + TSSymbol symbol; + int16_t dynamic_precedence; + uint8_t child_count; + uint8_t production_id; + } reduce; + } params; + TSParseActionType type : 4; +} TSParseAction; + +typedef struct { + uint16_t lex_state; + uint16_t external_lex_state; +} TSLexMode; + +typedef union { + TSParseAction action; + struct { + uint8_t count; + bool reusable : 1; + } entry; +} TSParseActionEntry; + +struct TSLanguage { + uint32_t version; + uint32_t symbol_count; + uint32_t alias_count; + uint32_t token_count; + uint32_t external_token_count; + const char **symbol_names; + const TSSymbolMetadata *symbol_metadata; + const uint16_t *parse_table; + const TSParseActionEntry *parse_actions; + const TSLexMode *lex_modes; + const TSSymbol *alias_sequences; + uint16_t max_alias_sequence_length; + 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; + uint32_t field_count; + const TSFieldMapSlice *field_map_slices; + const TSFieldMapEntry *field_map_entries; + const char **field_names; + uint32_t large_state_count; + const uint16_t *small_parse_table; + const uint32_t *small_parse_table_map; + const TSSymbol *public_symbol_map; + const uint16_t *alias_map; + uint32_t state_count; +}; + +/* + * Lexer Macros + */ + +#define START_LEXER() \ + bool result = false; \ + bool skip = false; \ + 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) \ + { \ + { \ + .params = { \ + .shift = { \ + .state = state_value \ + } \ + }, \ + .type = TSParseActionTypeShift \ + } \ + } + +#define SHIFT_REPEAT(state_value) \ + { \ + { \ + .params = { \ + .shift = { \ + .state = state_value, \ + .repetition = true \ + } \ + }, \ + .type = TSParseActionTypeShift \ + } \ + } + +#define RECOVER() \ + { \ + { .type = TSParseActionTypeRecover } \ + } + +#define SHIFT_EXTRA() \ + { \ + { \ + .params = { \ + .shift = { \ + .extra = true \ + } \ + }, \ + .type = TSParseActionTypeShift \ + } \ + } + +#define REDUCE(symbol_val, child_count_val, ...) \ + { \ + { \ + .params = { \ + .reduce = { \ + .symbol = symbol_val, \ + .child_count = child_count_val, \ + __VA_ARGS__ \ + }, \ + }, \ + .type = TSParseActionTypeReduce \ + } \ + } + +#define ACCEPT_INPUT() \ + { \ + { .type = TSParseActionTypeAccept } \ + } + +#ifdef __cplusplus +} +#endif + +#endif // TREE_SITTER_PARSER_H_ diff --git a/gpui/src/keymap.rs b/gpui/src/keymap.rs index 9f92964fef..e38beade8c 100644 --- a/gpui/src/keymap.rs +++ b/gpui/src/keymap.rs @@ -6,7 +6,7 @@ use std::{ use tree_sitter::{Language, Node, Parser}; extern "C" { - fn tree_sitter_zed_context_predicate() -> Language; + fn tree_sitter_context_predicate() -> Language; } pub struct Matcher { @@ -247,7 +247,7 @@ impl Context { impl ContextPredicate { fn parse(source: &str) -> anyhow::Result { let mut parser = Parser::new(); - let language = unsafe { tree_sitter_zed_context_predicate() }; + let language = unsafe { tree_sitter_context_predicate() }; parser.set_language(language).unwrap(); let source = source.as_bytes(); let tree = parser.parse(source, None).unwrap();