diff --git a/tools/lsp/camligo/grammar.js b/tools/lsp/squirrel/grammar/camligo/grammar.js similarity index 87% rename from tools/lsp/camligo/grammar.js rename to tools/lsp/squirrel/grammar/camligo/grammar.js index 23b8b5d0a..78db2aa41 100644 --- a/tools/lsp/camligo/grammar.js +++ b/tools/lsp/squirrel/grammar/camligo/grammar.js @@ -7,7 +7,7 @@ let sepBy1 = (sep, rule) => let sepBy = (sep, rule) => optional(sepBy1(sep, rule)) -let par = x => seq('(', x, ')') +let par = x => seq('(', x, ')') let brackets = x => seq('[', x, ']') let ne_injection = (Kind, element) => @@ -40,7 +40,7 @@ let injection = (Kind, element) => ), ) -let tuple = x => seq(x, ',', x, repeat(seq(',', x))) +let tuple = x => seq(x, ',', x, repeat(seq(',', x))) let list__ = x => brackets(sepBy(';', x)) let nseq = x => seq(x, repeat(x)) @@ -57,7 +57,7 @@ let lop = (l, x, r) => op(l, x, r, l) module.exports = grammar({ name: 'CAMLigo', - word: $ => $.Keyword, + word: $ => $.Keyword, extras: $ => [$.ocaml_comment, $.comment, /\s/], conflicts: $ => [[$.call, $.if_then_else]], @@ -65,7 +65,8 @@ module.exports = grammar({ rules: { // debug: $ => $.expr, - contract: $ => repeat($.declaration), + // contract: $ => repeat($.declaration), + contract: $ => $.expr, expr: $ => choice( @@ -91,9 +92,9 @@ module.exports = grammar({ disj: $ => prec.left(3, rop($.disj, $.or, $.conj)), conj: $ => prec.left(4, rop($.conj, $.and, $.comp)), comp: $ => prec.left(5, rop($.comp, $.compare, $.cat)), - cat: $ => prec.left(6, lop($.cons, $.catenate, $.cat)), + cat: $ => prec.left(6, lop($.cons, $.catenate, $.cat)), cons: $ => prec.right(7, lop($.add, $.consolidate, $.cons)), - add: $ => prec.left(8, rop($.add, $.plus, $.mult)), + add: $ => prec.left(8, rop($.add, $.plus, $.mult)), mult: $ => prec.left(9, rop($.mult, $.times, $.unary)), unary: $ => @@ -341,9 +342,9 @@ module.exports = grammar({ field_decl: $ => seq( - $.field_name, - ':', - $.type_expr, + $.field_name, + ':', + $.type_expr, ), let_declaration: $ => @@ -414,7 +415,7 @@ module.exports = grammar({ $.pattern, ), - pattern: $ => sepBy1('::', $.pattern_tuple), + pattern: $ => sepBy1('::', $.pattern_tuple), pattern_tuple: $ => sepBy1(',', $.construct), construct: $ => @@ -423,7 +424,7 @@ module.exports = grammar({ $.pattern_term, ), - /////////////////////////////////////////// + /////////////////////////////////////////// type_name: $ => $.ident, field_name: $ => $.ident, @@ -448,23 +449,23 @@ module.exports = grammar({ include: $ => seq('#include', $.String), - String: $ => /\"(\\.|[^"])*\"/, - Int: $ => /-?([1-9][0-9_]*|0)/, - Nat: $ => /([1-9][0-9_]*|0)n/, - Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/, - Bytes: $ => /0x[0-9a-fA-F]+/, - Name: $ => /[a-z][a-zA-Z0-9_]*/, + String: $ => /\"(\\.|[^"])*\"/, + Int: $ => /-?([1-9][0-9_]*|0)/, + Nat: $ => /([1-9][0-9_]*|0)n/, + Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/, + Bytes: $ => /0x[0-9a-fA-F]+/, + Name: $ => /[a-z][a-zA-Z0-9_]*/, Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/, - Keyword: $ => /[A-Za-z][a-z]*/, + Keyword: $ => /[A-Za-z][a-z]*/, - False: $ => 'False', - True: $ => 'True', - Unit: $ => 'Unit', - None: $ => 'None', - Some: $ => 'Some', - skip: $ => 'skip', - rec: $ => 'rec', + False: $ => 'False', + True: $ => 'True', + Unit: $ => 'Unit', + None: $ => 'None', + Some: $ => 'Some', + skip: $ => 'skip', + rec: $ => 'rec', - attr: $ => seq('[@@', $.name, ']'), + attr: $ => seq('[@@', $.name, ']'), } }); \ No newline at end of file diff --git a/tools/lsp/squirrel/grammar/camligo/index.js b/tools/lsp/squirrel/grammar/camligo/index.js new file mode 100644 index 000000000..f8593e3b5 --- /dev/null +++ b/tools/lsp/squirrel/grammar/camligo/index.js @@ -0,0 +1,13 @@ +try { + module.exports = require("./build/Release/tree_sitter_CAMLigo_binding"); +} catch (error) { + try { + module.exports = require("./build/Debug/tree_sitter_CAMLigo_binding"); + } catch (_) { + throw error + } +} + +try { + module.exports.nodeTypeInfo = require("./src/node-types.json"); +} catch (_) {} diff --git a/tools/lsp/pascaligo/LICENSE b/tools/lsp/squirrel/grammar/pascaligo/LICENSE similarity index 100% rename from tools/lsp/pascaligo/LICENSE rename to tools/lsp/squirrel/grammar/pascaligo/LICENSE diff --git a/tools/lsp/pascaligo/grammar.js b/tools/lsp/squirrel/grammar/pascaligo/grammar.js similarity index 86% rename from tools/lsp/pascaligo/grammar.js rename to tools/lsp/squirrel/grammar/pascaligo/grammar.js index ed174dd45..22379ed41 100644 --- a/tools/lsp/pascaligo/grammar.js +++ b/tools/lsp/squirrel/grammar/pascaligo/grammar.js @@ -14,7 +14,7 @@ let op = (name, left, right, term) => ) let right_op = (name, left, right) => op(name, left, right, right) -let left_op = (name, left, right) => op(name, left, right, left) +let left_op = (name, left, right) => op(name, left, right, left) let par = x => seq('(', x, ')') let brackets = x => seq('[', x, ']') @@ -52,7 +52,7 @@ let injection = (Kind, element) => module.exports = grammar({ name: 'PascaLigo', - word: $ => $.Keyword, + word: $ => $.Keyword, extras: $ => [$.ocaml_comment, $.comment, /\s/], rules: { @@ -119,30 +119,30 @@ module.exports = grammar({ michelsonTypeOr: $ => seq( - "michelson_or", - "(", - field("left_type", $._type_expr), - ",", - field("left_type_name", $.String), - ",", - field("right_type", $._type_expr), - ",", - field("right_type_name", $.String), - ")", + "michelson_or", + "(", + field("left_type", $._type_expr), + ",", + field("left_type_name", $.String), + ",", + field("right_type", $._type_expr), + ",", + field("right_type_name", $.String), + ")", ), michelsonTypeAnd: $ => seq( - "michelson_pair", - "(", - field("left_type", $._type_expr), - ",", - field("left_type_name", $.String), - ",", - field("right_type", $._type_expr), - ",", - field("right_type_name", $.String), - ")", + "michelson_pair", + "(", + field("left_type", $._type_expr), + ",", + field("left_type_name", $.String), + ",", + field("right_type", $._type_expr), + ",", + field("right_type_name", $.String), + ")", ), invokeBinary: $ => @@ -157,10 +157,10 @@ module.exports = grammar({ par(field("arguments", $._type_expr)), ), - map: $ => 'map', + map: $ => 'map', big_map: $ => 'big_map', - list: $ => 'list', - set: $ => 'set', + list: $ => 'list', + set: $ => 'set', type_tuple: $ => par(sepBy1(',', field("element", $._type_expr))), @@ -184,7 +184,7 @@ module.exports = grammar({ record_type: $ => choice( - seq('record', sepBy(';', field("field", $.field_decl)), 'end'), + seq('record', sepBy(';', field("field", $.field_decl)), 'end'), seq('record', '[', sepBy(';', field("field", $.field_decl)), ']'), ), @@ -525,22 +525,22 @@ module.exports = grammar({ binop: $ => choice( - prec.left (0, seq(field("arg1", $._op_expr), field("op", 'or'), field("arg2", $._op_expr))), - prec.left (1, seq(field("arg1", $._op_expr), field("op", 'and'), field("arg2", $._op_expr))), - prec.right(2, seq(field("arg1", $._core_expr), field("op", 'contains'), field("arg2", $._op_expr))), - prec.left (3, seq(field("arg1", $._op_expr), field("op", $.comparison), field("arg2", $._op_expr))), - prec.right(4, seq(field("arg1", $._op_expr), field("op", '^'), field("arg2", $._op_expr))), - prec.right(5, seq(field("arg1", $._op_expr), field("op", '#'), field("arg2", $._op_expr))), - prec.left (6, seq(field("arg1", $._op_expr), field("op", $.adder), field("arg2", $._op_expr))), - prec.left (7, seq(field("arg1", $._op_expr), field("op", $.multiplier), field("arg2", $._op_expr))), + prec.left(0, seq(field("arg1", $._op_expr), field("op", 'or'), field("arg2", $._op_expr))), + prec.left(1, seq(field("arg1", $._op_expr), field("op", 'and'), field("arg2", $._op_expr))), + prec.right(2, seq(field("arg1", $._core_expr), field("op", 'contains'), field("arg2", $._op_expr))), + prec.left(3, seq(field("arg1", $._op_expr), field("op", $.comparison), field("arg2", $._op_expr))), + prec.right(4, seq(field("arg1", $._op_expr), field("op", '^'), field("arg2", $._op_expr))), + prec.right(5, seq(field("arg1", $._op_expr), field("op", '#'), field("arg2", $._op_expr))), + prec.left(6, seq(field("arg1", $._op_expr), field("op", $.adder), field("arg2", $._op_expr))), + prec.left(7, seq(field("arg1", $._op_expr), field("op", $.multiplier), field("arg2", $._op_expr))), ), unop: $ => prec.right(8, seq(field("negate", $.negate), field("arg", $._core_expr))), comparison: $ => choice('<', '<=', '>', '>=', '=', '=/='), - adder: $ => choice('-', '+'), + adder: $ => choice('-', '+'), multiplier: $ => choice('/', '*', 'mod'), - negate: $ => choice('-', 'not'), + negate: $ => choice('-', 'not'), _core_expr: $ => choice( @@ -718,8 +718,8 @@ module.exports = grammar({ field("arguments", $.arguments), ), - tuple_expr: $ => par(sepBy1(',', field("element", $._expr))), - arguments: $ => par(sepBy(',', field("argument", $._expr))), + tuple_expr: $ => par(sepBy1(',', field("element", $._expr))), + arguments: $ => par(sepBy(',', field("argument", $._expr))), _list_expr: $ => choice($.list_injection, 'nil'), @@ -802,22 +802,22 @@ module.exports = grammar({ include: $ => seq('#include', field("filename", $.String)), - String: $ => choice(/\"(\\.|[^"])*\"/, /{\|(\\.|[^\|])*\|}/), - Int: $ => /-?([1-9][0-9_]*|0)/, - Nat: $ => /([1-9][0-9_]*|0)n/, - Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/, - Bytes: $ => /0x[0-9a-fA-F]+/, - FieldName: $ => /[a-z][a-zA-Z0-9_]*/, - TypeName: $ => /[a-z][a-zA-Z0-9_]*/, - Name: $ => /[a-z][a-zA-Z0-9_]*/, + String: $ => choice(/\"(\\.|[^"])*\"/, /{\|(\\.|[^\|])*\|}/), + Int: $ => /-?([1-9][0-9_]*|0)/, + Nat: $ => /([1-9][0-9_]*|0)n/, + Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/, + Bytes: $ => /0x[0-9a-fA-F]+/, + FieldName: $ => /[a-z][a-zA-Z0-9_]*/, + TypeName: $ => /[a-z][a-zA-Z0-9_]*/, + Name: $ => /[a-z][a-zA-Z0-9_]*/, Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/, - Keyword: $ => /[A-Za-z][a-z]*/, + Keyword: $ => /[A-Za-z][a-z]*/, - False: $ => 'False', - True: $ => 'True', - Unit: $ => 'Unit', - None: $ => 'None', - skip: $ => 'skip', - recursive: $ => 'recursive', + False: $ => 'False', + True: $ => 'True', + Unit: $ => 'Unit', + None: $ => 'None', + skip: $ => 'skip', + recursive: $ => 'recursive', } }); \ No newline at end of file diff --git a/tools/lsp/squirrel/grammar/pascaligo/index.js b/tools/lsp/squirrel/grammar/pascaligo/index.js new file mode 100644 index 000000000..8d7488a21 --- /dev/null +++ b/tools/lsp/squirrel/grammar/pascaligo/index.js @@ -0,0 +1,13 @@ +try { + module.exports = require("./build/Release/tree_sitter_PascaLigo_binding"); +} catch (error) { + try { + module.exports = require("./build/Debug/tree_sitter_PascaLigo_binding"); + } catch (_) { + throw error + } +} + +try { + module.exports.nodeTypeInfo = require("./src/node-types.json"); +} catch (_) {} diff --git a/tools/lsp/pascaligo/test.ligo b/tools/lsp/squirrel/grammar/pascaligo/test.ligo similarity index 100% rename from tools/lsp/pascaligo/test.ligo rename to tools/lsp/squirrel/grammar/pascaligo/test.ligo diff --git a/tools/lsp/pascaligo/test/corpus/examples.txt b/tools/lsp/squirrel/grammar/pascaligo/test/corpus/examples.txt similarity index 100% rename from tools/lsp/pascaligo/test/corpus/examples.txt rename to tools/lsp/squirrel/grammar/pascaligo/test/corpus/examples.txt diff --git a/tools/lsp/squirrel/grammar/reasonligo/grammar.js b/tools/lsp/squirrel/grammar/reasonligo/grammar.js new file mode 100644 index 000000000..4ba1ffcc7 --- /dev/null +++ b/tools/lsp/squirrel/grammar/reasonligo/grammar.js @@ -0,0 +1,682 @@ +const PREC = { + + CALL: 300000000, + OR: 0, + AND: 1, + COMPARE: 3, + CONCAT: 5, + PLUS: 6, + MINUS: 6, + MUL: 7, + DIV: 7, + + ATTR: 1, + TYPE: 101, + LET: 100, + EXPR: 100000000, + CONSTR: 100000, + LAM: 1000, +}; + +const OPS = [ + ['+', PREC.PLUS], + ['-', PREC.MINUS], + ['mod', PREC.DIV], + ['/', PREC.DIV], + ['*', PREC.MUL], + ['++', PREC.CONCAT], + ['<', PREC.COMPARE], + ['>', PREC.COMPARE], + ['<=', PREC.COMPARE], + ['>=', PREC.COMPARE], + ['==', PREC.COMPARE], + ['!=', PREC.COMPARE], + ['&&', PREC.COMPARE], + ['||', PREC.OR], +] + +let sepBy1 = (sep, rule) => + seq( + rule, + repeat(seq(sep, rule)), + optional(sep) + ) + +let sepBy = (sep, rule) => optional(sepBy1(sep, rule)) + +let par = x => seq('(', x, ')') +let opar = x => seq(optional('('), x, optional(')')) +let brackets = x => seq('[', x, ']') +let block = x => seq('{', x, '}') + +let tuple = x => seq(x, ',', x, repeat(seq(',', x))) +let list__ = x => brackets(sepBy(';', x)) + +let nseq = x => seq(x, repeat(x)) + +module.exports = grammar({ + name: 'ReasonLigo', + + word: $ => $.Keyword, + extras: $ => [$.oneline_comment, $.block_comment, /\s/], + + conflicts: $ => [ + [$._fun_type, $.type_application], + [$._pattern, $.tuple_pattern], + [$._expr], // TODO: left-precendence is used for tuple_expr, right for nested `let`s + [$._exprf], + + [$.tuple_expr, $.parameters], + [$.record_field, $._accessor], // TODO + [$.variant], // TODO: some alien stuff + [$.sum_type], // TODO: fix in `let_declaration`. + [$.bracket_block], // TODO: same as $.lambda_body + [$.type_decl], + [$.lambda], + [$._instruction, $._expr], // switch_instr + [$._functional_block, $.bracket_block], // TODO: remove + [$.list_access], // TODO: remove + [$.list_access, $._ident], // TODO + [$.record_field, $._ident], // TODO + [$._core_pattern, $._expr], //TODO: remove as soon as possible + [$.lambda_call], // TODO: remove + [$.lambda_call, $.binary_call], + [$._expr, $.bracket_block], // TODO + [$.lambda_call, $.parameters], // TODO + [$["-"], $.negate], // unary vs binary calls + + [$.parameters, $.annot_expr], // TODO + [$.type_tuple, $._core_type], + + [$._pattern, $.annot_pattern], // TODO: constr (pat) case + [$.annot_expr, $._type_annotation], + [$.annot_expr, $.lambda_call], + [$.annot_expr, $._functional_block], + + // TODO: those are produced in conflicts of `fun_call` and `expr` in bracket blocks + [$.annot_expr, $._exprf], + [$.lambda_call, $._exprf], + [$.bracket_block, $._exprf], + [$._functional_block, $._exprf], + [$.tuple_expr, $._exprf], + [$._annot_fun_call, $._exprf], + ], + + rules: { + contract: $ => sepBy(optional(';'), field("declaration", $._declaration)), + + _expr: $ => + prec(PREC.EXPR, + seq( + choice( + $.lambda_call, + $.tuple_expr, + $._literal, + // $.fun_call, + $.constructor_call, + $.unary_call, + $.binary_call, + $.annot_expr, + $.list_expr, + $.record_expr, + $._ref, + $._ident, + $.switch_instr, + ), + ), + ), + + // TODO: workaround to move `fun_call` out of `expr` needed in bracket blocks + _exprf: $ => choice($.fun_call, $._expr), + + _annot_expr: $ => + par($.annot_expr), + + annot_expr: $ => + seq( + field("subject", $._expr), + ':', + field("type", $._type_expr), + ), + + // TODO: same as tuple_pattern + // TODO: to annotate expression we do not need to enclose it in brackets + // TODO: possible ((a : p) : q, b) + tuple_expr: $ => + par(sepBy1(',', + seq( + field("element", choice( + $.annot_expr, + $.fun_call, + $._expr, + )), + ) + )), + + constructor_call: $ => + prec(PREC.CONSTR, + seq( + field("constructor", + choice( + $._constr, + $.module_qualified, + ), + ), + field("parameters", $.parameters), + ), + ), + + lambda_call: $ => + seq( + par(field("lambda", $.lambda)), + repeat1( + choice( + field("arguments", $._expr), + par(field("arguments", $.lambda)) + ) + ), // TODO: workaround to move lambda out of expr + ), + + fun_call: $ => + prec.right(PREC.CALL, + seq( + field("f", $.Name), // TODO: may be qualified + field("arguments", $.parameters), + ) + ), + + binary_call: $ => choice( + ...OPS + .map(([op, precendence]) => + prec.left(precendence, seq( + field("left", $._exprf), + field("op", $[op]), + field("right", $._exprf), + )) + ) + ), + + // Workaround to make operators to be instructions as well + // so that they won't be stripped when naming them as fields + ...OPS.reduce( + (acc, [e, _]) => ({ ...acc, [e]: $ => seq(e) }), {} + ), + + unary_call: $ => prec.right(8, + seq( + field("negate", $.negate), + field("arg", $._exprf) + ) + ), + + negate: $ => choice('-', '!'), + + // TODO: refactor + call: $ => + prec.left(1, + choice( + seq($.call, par($._expr)), + par($._expr), + ), + ), + + switch_instr: $ => + prec.left(0, // TODO + seq( + 'switch', + choice( + field('subject', $.Name), + par(field('subject', $._exprf)), + ), + block(seq( + optional('|'), + sepBy1('|', field('case', $.alt)), + )), + ), + ), + + // TODO: it may parse expr with ';' attached to the end + alt: $ => + seq( + field("pattern", $._pattern), + '=>', + field("body", $._functional_block), + optional(';'), + ), + + + _literal: $ => + choice( + $.Nat, + $.Int, + $.Bool, + $.Tez, + $.String, + $.Bytes, + $.Unit, + $.Nil, + $.wildcard, + ), + + record_expr: $ => + seq( + block(seq( + sepBy1(',', field("assignment", choice( + $.spread, + $.record_field, + ))), + optional($._ident), // TODO: not need to be here + )) + ), + + spread: $ => seq( + '...', + field("name", $._ident), // TODO: may be possible expression + ), + + record_field: $ => + seq( + field("name", sepBy1('.', $.Name)), + ':', + field("value", $._expr), + ), + + _statement: $ => choice( + $._instruction, + ), + + _instruction: $ => + prec(PREC.EXPR, choice( + $.conditional, + $.switch_instr, + $.let_declaration, + )), + + lambda: $ => + seq( + field("lambda_head", seq( + field("arguments", $.parameters), + optional(seq(":", + field("lambda_type", + choice($._core_type, $.type_tuple), + ), + )) + )), + '=>', + field("lambda_body", $._functional_block) + ), + + parameters: $ => + par( + sepBy(',', field("parameter", seq( + choice($._exprf, $.lambda), // TODO: workaround to move lambda our of expr + optional($._type_annotation), // TODO: move it somewhere + ))) + ), + + _pattern: $ => + choice( + $.cons_pattern, + $.annot_pattern, + $._core_pattern, + ), + + cons_pattern: $ => + brackets( + seq( + field("head", $._core_pattern), + ',', + field("tail", choice( + $.spread, + $._pattern, + )), + ) + ), + + annot_pattern: $ => + par( + seq( + field("subject", $._core_pattern), + ':', + field("type", $._type_expr), + ) + ), + + _core_pattern: $ => + prec.right(PREC.CONSTR, + seq( + choice( + $.constr_pattern, + $.tuple_pattern, + $._literal, + $.Name, + ), + ) + ), + + tuple_pattern: $ => + par(tuple(field("element", $._pattern))), + + constr_pattern: $ => + prec.right(PREC.CONSTR, // TODO: left precendence fails + seq( + field("constr", $._constr), + optional( + opar( + field("arguments", $._pattern) + ), + )), + ), + + list_expr: $ => brackets( + sepBy(',', field("element", choice( + $.spread, + $._expr, + ))) + ), + + + conditional: $ => + prec.left(PREC.LET, + seq( + 'if', + par(field("selector", $._expr)), + field("then", $.bracket_block), + optional(seq( + 'else', + field("else", $.bracket_block), + )), + ), + ), + + _ref: $ => + choice( + $.module_qualified, + $.struct_qualified, + $._constr, + $.list_access, + ), + + module_qualified: $ => + seq( + field("module", $._constr), + nseq(seq('.', field("method", $.Name))), // TODO: capital letters + ), + + // TODO: may be the same as `list_access` + struct_qualified: $ => + seq( + field("struct", $.Name), + nseq(seq('.', field("method", $._accessor))), + ), + + _accessor: $ => choice($.Name, $.Int), + + list_access: $ => + // prec.left(8, + seq( + field("name", $.Name), + repeat1(brackets(field("indexes", $.Int))), + // ), + ), + + _declaration: $ => + field("declaration", + choice( + $.type_decl, + $.let_declaration, + $.include, + $.attr_decl, + ) + ), + + attr_decl: $ => + prec.left(PREC.ATTR, + nseq(brackets( + seq('@', field("name", $.Name)) + )) + ), + + type_decl: $ => + seq( + 'type', + field("type_name", $.TypeName), + '=', + field("type_value", $._type_expr), + ), + + _type_expr: $ => + choice( + $._fun_type, + $.sum_type, + $.record_type, + ), + + _fun_type: $ => + choice( + $.fun_type, + $._core_type, + $.type_tuple, + ), + + fun_type: $ => + seq( + field("domain", choice($._core_type, $.type_tuple)), + '=>', + field("codomain", $._fun_type), + ), + + _core_type: $ => + choice( + $.type_application, + $.TypeName, + $.type_string, + $.module_TypeName, + ), + + module_TypeName: $ => + seq( + $.module_name, + '.', + $.TypeName, + ), + + type_application: $ => + seq( + field("functor", $._core_type), + par(sepBy(',', field("parameter", $._type_expr))), + ), + + type_string: $ => $.String, + + type_tuple: $ => + par(sepBy1(',', field("element", $._type_expr))), + + sum_type: $ => + seq( + optional('|'), + sepBy1('|', field("variant", $.variant)), + ), + + variant: $ => + seq( + field("constructor", $._constr), + optional(par(field("arguments", $._fun_type))), + ), + + record_type: $ => + seq( + '{', + sepBy(',', field("field", $.field_decl)), + '}', + ), + + field_decl: $ => + seq( + field("field_name", $._field_name), + ':', + field("field_type", $._type_expr), + ), + + te: $ => choice( + $.lambda, + $._expr, + ), + + _functional_block: $ => + choice( + $._statement, + $._expr, + $.fun_call, + $.bracket_block, + ), + + _annot_fun_call: $ => // Workaround used only in bracket blocks + par(seq( + $.fun_call, + ':', + $._type_expr, + )), + + bracket_block: $ => + prec.right(1000000, // TODO: precendence + block( + choice( + seq( + sepBy(';', field("statement", choice( + $.constructor_call, + seq( + optional($.attr_decl), + $._statement, + ), + $.fun_call, + // $._expr, // TODO: use only `fun_call` from there, somewhat fails if called directly + ))), + optional(seq( + opar( + field("return", + choice( + $._expr, + seq( // TODO: maybe not all returned function calls need to be annotated + $.fun_call, + ':', + $._type_expr, // TODO: maybe we'll need to annotate fields here, but so far we just return multiple 'return's + ) + ) + ) + ), + optional(';'), + ))), + $.bracket_block, + ), // TODO conflict: _group bracket_block + ) + ), + + let_declaration: $ => + prec.left(PREC.LET, + seq( + 'let', + optional($.rec), + field("binding", choice( + sepBy1(',', $._core_pattern), + )), + optional(seq(':', field("type", $._type_expr))), + '=', + field("let_value", + choice( + $.lambda, + $._functional_block, + ), + ), + ) + ), + + _type_annotation: $ => + seq( + ':', + field("type", $._type_expr) + ), + + pattern_term: $ => + choice( + $.Name, + $.pattern_grouped, + ), + + pattern_grouped: $ => + seq( + '(', + $._core_pattern, + optional($._type_annotation), + ')', + ), + + pattern_list: $ => list__($._pattern), + pattern_constant: $ => + choice( + $.Nat, + $.String, + $.Bytes, + $.Int, + ), + + pattern_tuple: $ => sepBy1(',', $._construct), + + _construct: $ => + choice( + seq($._constr, nseq($.pattern_term)), + par($.pattern_term), + ), + + /////////////////////////////////////////// + + _field_name: $ => $.Name, + fun_name: $ => $.Name, + struct_name: $ => $.Name, + var: $ => $.Name, + module_name: $ => $.Name_Capital, + _constr: $ => $.Name_Capital, + // TODO: remove + _ident: $ => $.Name, + + comment: $ => choice( + $.oneline_comment, + $.block_comment + ), + + oneline_comment: $ => token(seq('//', /.*/)), + + block_comment: $ => seq( + '/*', + repeat(/./), + '*/' + ), + + include: $ => seq('#include', $.String), + + String: $ => /\"(\\.|[^"])*\"/, + Int: $ => /-?([1-9][0-9_]*|0)/, + Nat: $ => /([1-9][0-9_]*|0)n/, + Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/, + Bytes: $ => /0x[0-9a-fA-F]+/, + Name: $ => /[a-z][a-zA-Z0-9_]*/, + TypeName: $ => /[a-z][a-zA-Z0-9_]*/, + Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/, + Keyword: $ => /[A-Za-z][a-z]*/, + Bool: $ => choice($.False, $.True), + + include: $ => seq('#include', field("filename", $.String)), + + False: $ => 'false', + True: $ => 'true', + Unit: $ => '()', + Nil: $ => '[]', + None: $ => 'None', + Some: $ => 'Some', + skip: $ => 'skip', + rec: $ => 'rec', + wildcard: $ => '_', + + attr: $ => seq('[@@', $.Name, ']'), + } +}); \ No newline at end of file diff --git a/tools/lsp/squirrel/grammar/reasonligo/index.js b/tools/lsp/squirrel/grammar/reasonligo/index.js new file mode 100644 index 000000000..f8593e3b5 --- /dev/null +++ b/tools/lsp/squirrel/grammar/reasonligo/index.js @@ -0,0 +1,13 @@ +try { + module.exports = require("./build/Release/tree_sitter_CAMLigo_binding"); +} catch (error) { + try { + module.exports = require("./build/Debug/tree_sitter_CAMLigo_binding"); + } catch (_) { + throw error + } +} + +try { + module.exports.nodeTypeInfo = require("./src/node-types.json"); +} catch (_) {}