|
@@ -1,140 +1,124 @@
|
|
|
// @ts-nocheck
|
|
|
|
|
|
-const SqStr = /'[^']*'/
|
|
|
-const DqStr = /"[^"]*"/
|
|
|
-const Comment = /\/\*([^\*\/]|\*[^\/]|[^\*]\/)*\*\/|\/\/[^\n]*/
|
|
|
+// DO NOT EDIT TOKENS/RULES (generated from syntax_test.go)
|
|
|
+
|
|
|
+// TOKENS
|
|
|
+const Doc = /\/\/\/[^\n]*/
|
|
|
+const Comment = /\/\/[^\n]*/
|
|
|
const Blank = /[ \t\r ]+/
|
|
|
-const LF = /\n+/
|
|
|
-const Int = /\-?0[xX][0-9A-Fa-f]+|\-?0[oO][0-7]+|\-?0[bB][01]+|\-?\d[\d_]*/
|
|
|
+const LF = /[\n]+/
|
|
|
+const Text = /'[^']*'|"(\\"|[^"])*"/
|
|
|
+const Int = /\-?0[xX][0-9A-Fa-f]+|\-?0[oO][0-7]+|\-?0[bB][01]+|\-?\d+/
|
|
|
const Float = /\-?\d+(\.\d+)?[Ee][\+\-]?\d+|\-?\d+\.\d+/
|
|
|
+const Byte = /\\x[0-9A-Fa-f][0-9A-Fa-f]/
|
|
|
const Char = /`.`|\\u[0-9A-Fa-f]+|\\[a-z]/
|
|
|
-const Name = /[^0-9\{\}\[\]\(\)\.,:;\&\|\\'"` \t\r \n][^\{\}\[\]\(\)\.,:;\&\|\\'"` \t\r \n]*/
|
|
|
+const Name = /[^0-9\{\}\[\]\(\)\.,:;@#\|\&\\'"` \t\r \n][^\{\}\[\]\(\)\.,:;@#\|\&\\'"` \t\r \n]*/
|
|
|
+
|
|
|
+const IgnoreRule = $ => Comment
|
|
|
+const IgnoreTokens = [Blank, LF]
|
|
|
+const IgnoreRuleKey = 'tree_sitter_ignore_rule'
|
|
|
|
|
|
module.exports = grammar({
|
|
|
- name: 'kumachan',
|
|
|
- extras: $ => [$.comment, Blank, LF],
|
|
|
- rules: (raw => {
|
|
|
- let rules = {}
|
|
|
- for (let [k,v] of Object.entries(raw)) {
|
|
|
- let decorate = (g, f) => $ => f(g($))
|
|
|
- if (k == 'inline_type_args' || k == 'inline_ref') {
|
|
|
- v = decorate(v, x => prec.left(x))
|
|
|
- } else {
|
|
|
- v = decorate(v, x => prec.right(x))
|
|
|
- }
|
|
|
- if (k == 'call_cps') {
|
|
|
- v = decorate(v, x => prec(1, x))
|
|
|
- }
|
|
|
- rules[k] = v
|
|
|
- }
|
|
|
- return rules
|
|
|
- })({
|
|
|
- source_file: $ => $.stmts,
|
|
|
- stmts: $ => repeat1($.stmt),
|
|
|
- stmt: $ => choice($.entry, $.asset, $.decl_type, $.decl_const, $.decl_method, $.decl_func),
|
|
|
- entry: $ => seq('entry', $.expr, ';'),
|
|
|
- asset: $ => seq(optional('export'), 'asset', $.name, ':', $.type, $.string_text, ';'),
|
|
|
- name: $ => Name,
|
|
|
- type: $ => choice($.type_literal, $.type_ref),
|
|
|
- type_ref: $ => seq(optional($.module_prefix), $.name, optional($.type_args)),
|
|
|
- module_prefix: $ => choice(seq($.name, '::'), '::'),
|
|
|
- type_args: $ => seq('[', $.type, repeat(seq(',', $.type)), ']'),
|
|
|
- type_literal: $ => $.repr,
|
|
|
- repr: $ => choice($.repr_func, $.repr_tuple, $.repr_record),
|
|
|
- repr_tuple: $ => choice(seq('(', ')'), seq('(', $.type, repeat(seq(',', $.type)), ')')),
|
|
|
- repr_record: $ => choice(seq('{', '}'), seq('{', $.field, repeat(seq(',', $.field)), '}')),
|
|
|
- field: $ => seq($.name, ':', $.type),
|
|
|
- repr_func: $ => seq('&', $.input_type, '=>', $.output_type),
|
|
|
- input_type: $ => $.type,
|
|
|
- output_type: $ => $.type,
|
|
|
- decl_type: $ => seq('type', $.name, optional($.type_params), optional(seq('impl', '(', repeat1($.type_decl_ref), ')')), optional($.type_def), ';'),
|
|
|
- type_decl_ref: $ => seq(optional($.module_prefix), $.name),
|
|
|
- type_def: $ => choice($.native_type, $.enum_type, $.interface_type, $.box_type),
|
|
|
- native_type: $ => 'native',
|
|
|
- enum_type: $ => seq('enum', '{', repeat1($.decl_type), '}'),
|
|
|
- interface_type: $ => seq('interface', $.repr_record),
|
|
|
- box_type: $ => seq(optional($.box_option), optional('weak'), $.inner_type, optional($.defaults)),
|
|
|
- box_option: $ => choice('protected', 'opaque'),
|
|
|
- inner_type: $ => $.type,
|
|
|
- defaults: $ => seq('default', '{', $.default_item, repeat(seq(',', $.default_item)), '}'),
|
|
|
- default_item: $ => seq($.name, ':', $.expr),
|
|
|
- type_params: $ => seq('[', $.type_param, repeat(seq(',', $.type_param)), ']'),
|
|
|
- type_param: $ => seq(optional($.type_variance), $.name, optional(seq('=', $.type)), optional($.type_bound)),
|
|
|
- type_variance: $ => choice('in', 'out'),
|
|
|
- type_bound: $ => seq(choice('<', '>'), $.type),
|
|
|
- decl_func: $ => seq(optional('export'), 'function', $.name, ':', $.signature, optional($.body), ';'),
|
|
|
- signature: $ => seq(optional($.type_params), optional($.implicit_input), $.repr_func, optional($.defaults)),
|
|
|
- implicit_input: $ => $.repr_record,
|
|
|
- body: $ => choice($.native, $.lambda),
|
|
|
- native: $ => seq('native', $.string_text),
|
|
|
- lambda: $ => seq('&', $.pattern, optional($.rec), '=>', $.expr),
|
|
|
- rec: $ => seq('rec', '(', $.name, ')'),
|
|
|
- pattern: $ => choice($.pattern_trivial, $.pattern_tuple, $.pattern_record),
|
|
|
- pattern_trivial: $ => $.name,
|
|
|
- pattern_tuple: $ => choice(seq('(', ')'), seq('(', $.name, repeat(seq(',', $.name)), ')')),
|
|
|
- pattern_record: $ => choice(seq('{', '}'), seq('{', $.name, optional(seq(':', $.name)), repeat(seq(',', $.name, optional(seq(':', $.name)))), '}')),
|
|
|
- decl_method: $ => seq(optional('export'), 'method', $.receiver, '.', $.name, ':', $.type, optional($.body), ';'),
|
|
|
+ name: 'kumachan',
|
|
|
+ extras: $ => [$[IgnoreRuleKey], ...IgnoreTokens],
|
|
|
+ rules: (raw => {
|
|
|
+ let rules = {}
|
|
|
+ for (let [k,v] of Object.entries(raw)) {
|
|
|
+ rules[k] = v
|
|
|
+ }
|
|
|
+ rules[IgnoreRuleKey] = IgnoreRule
|
|
|
+ return rules
|
|
|
+ })({
|
|
|
+ // RULES
|
|
|
+ source_file: $ => seq($.ns, repeat($.alias), repeat($.stmt)),
|
|
|
+ ns: $ => seq('namespace', optional($.name), '::'),
|
|
|
+ name: $ => Name,
|
|
|
+ alias: $ => seq(optional('#'), 'using', optional($.alias_name), $.alias_target),
|
|
|
+ alias_name: $ => seq($.name, '='),
|
|
|
+ alias_target: $ => choice($.alias_to_ns, $.alias_to_ref_base),
|
|
|
+ alias_to_ns: $ => seq('namespace', $.name),
|
|
|
+ alias_to_ref_base: $ => $.ref_base,
|
|
|
+ stmt: $ => choice($.decl_entry, $.decl_type, $.decl_func, $.decl_const, $.decl_method),
|
|
|
+ decl_entry: $ => seq(optional($.docs), optional('#'), 'entry', $.block),
|
|
|
+ docs: $ => repeat1($.doc),
|
|
|
+ doc: $ => Doc,
|
|
|
+ decl_type: $ => seq(optional($.docs), optional('#'), 'type', $.name, optional($.type_params), optional($.impl), $.type_def),
|
|
|
+ type_params: $ => seq('[', optional(seq($.name, repeat(seq(',', $.name)))), ']'),
|
|
|
+ impl: $ => seq('(', optional(seq($.ref_base, repeat(seq(',', $.ref_base)))), ')'),
|
|
|
+ ref_base: $ => seq(optional($.ns_prefix), $.name),
|
|
|
+ ns_prefix: $ => seq($.name, '::'),
|
|
|
+ type_def: $ => choice('native', $.record, $.interface, $.union, $.enum),
|
|
|
+ record: $ => seq('record', $.record_def),
|
|
|
+ record_def: $ => seq('{', optional(seq($.field, repeat(seq(',', $.field)))), '}'),
|
|
|
+ field: $ => seq(optional($.docs), $.name, $.type, optional($.field_default)),
|
|
|
+ field_default: $ => seq('(', $.expr, ')'),
|
|
|
+ interface: $ => seq('interface', '{', optional(seq($.method, repeat(seq(',', $.method)))), '}'),
|
|
|
+ method: $ => seq(optional($.docs), $.name, $.type),
|
|
|
+ union: $ => seq('union', '{', seq($.type, repeat(seq(',', $.type))), '}'),
|
|
|
+ enum: $ => seq('enum', '{', seq($.enum_item, repeat(seq(',', $.enum_item))), '}'),
|
|
|
+ enum_item: $ => seq(optional($.docs), $.name),
|
|
|
+ decl_func: $ => seq(optional($.docs), optional('#'), choice('function', 'operator'), optional('variadic'), $.name, $.sig, $.body),
|
|
|
+ sig: $ => seq(optional($.type_params), $.inputs, optional($.implicit), $.output),
|
|
|
+ inputs: $ => $.record_def,
|
|
|
+ implicit: $ => $.inputs,
|
|
|
+ output: $ => $.type,
|
|
|
+ body: $ => choice($.native_body, $.block),
|
|
|
+ native_body: $ => seq('native', '(', $.text, ')'),
|
|
|
+ decl_const: $ => seq(optional($.docs), optional('#'), 'const', $.name, $.type, $.body),
|
|
|
+ decl_method: $ => seq(optional($.docs), optional('#'), 'method', $.receiver, '.', $.name, $.type, $.body),
|
|
|
receiver: $ => $.name,
|
|
|
- decl_const: $ => seq(optional('export'), 'const', $.name, ':', $.type, optional($.const_value), ';'),
|
|
|
- const_value: $ => choice($.native, $.expr),
|
|
|
- expr: $ => seq($.term, optional($.pipeline)),
|
|
|
- pipeline: $ => seq($.pipe, optional($.pipeline)),
|
|
|
- pipe: $ => choice($.pipe_cast, $.pipe_func, $.pipe_get, $.pipe_interior),
|
|
|
- pipe_cast: $ => seq('.', '[', $.type, ']'),
|
|
|
- pipe_func: $ => seq('.', '{', $.callee, optional($.expr), '}'),
|
|
|
- callee: $ => $.expr,
|
|
|
- pipe_get: $ => seq('.', $.name),
|
|
|
- pipe_interior: $ => seq('.', '(', $.name, ')'),
|
|
|
- term: $ => choice (
|
|
|
- $.call, $.ctor_lambda, $.pipeline_lambda, $.lambda,
|
|
|
- $.select, $.switch, $.if,
|
|
|
- $.block, $.record, $.tuple, $.inline_ref,
|
|
|
- $.list, $.int, $.float, $.formatter, $.string, $.char
|
|
|
- ),
|
|
|
- call: $ => choice($.call_prefix, $.call_infix, $.call_cps),
|
|
|
- call_prefix: $ => seq('{', $.callee, $.expr, '}'),
|
|
|
- call_infix: $ => seq('(', $.infix_left, $.operator, $.infix_right, ')'),
|
|
|
- operator: $ => $.expr,
|
|
|
- infix_left: $ => $.expr,
|
|
|
- infix_right: $ => $.expr,
|
|
|
- ctor_lambda: $ => seq('|', $.type_ref, '|'),
|
|
|
- pipeline_lambda: $ => seq('|', optional($.pipeline), '|'),
|
|
|
- select: $ => seq('select', '(', $.exprlist, ')', ':', $.multi_branch_list, 'end'),
|
|
|
- exprlist: $ => seq($.expr, repeat(seq(',', $.expr))),
|
|
|
- multi_branch_list: $ => repeat1(seq($.multi_branch, ',')),
|
|
|
- multi_branch: $ => choice(seq('default', ':', $.expr), seq('case', $.multi_branch_key, repeat(seq(',', $.multi_branch_key)), optional($.pattern), ':', $.expr)),
|
|
|
- multi_branch_key: $ => seq('(', $.name, repeat(seq(',', $.name)), ')'),
|
|
|
- switch: $ => seq('switch', $.expr, ':', $.branch_list, 'end'),
|
|
|
- branch_list: $ => repeat1(seq($.branch, ',')),
|
|
|
- branch: $ => choice(seq('default', ':', $.expr), seq('case', $.name, repeat(seq(',', $.name)), optional($.pattern), ':', $.expr)),
|
|
|
- if: $ => seq('if', $.expr, ':', $.expr, ',', repeat($.elif), 'else', ':', $.expr),
|
|
|
- elif: $ => seq('elif', $.expr, ':', $.expr, ','),
|
|
|
- block: $ => seq($.binding, $.block_value),
|
|
|
- binding: $ => seq('let', $.pattern, ':=', $.expr),
|
|
|
- block_value: $ => seq(',', $.expr),
|
|
|
- call_cps: $ => seq($.cps_symbol, $.callee, choice($.block, seq($.cps_input, ',', $.cps_output))),
|
|
|
- cps_symbol: $ => '\\',
|
|
|
- cps_input: $ => $.expr,
|
|
|
- cps_output: $ => $.expr,
|
|
|
- record: $ => choice(seq('{', '}'), seq('{', optional($.update), $.pairlist, '}')),
|
|
|
- pairlist: $ => seq($.pair, repeat(seq(',', $.pair))),
|
|
|
- pair: $ => choice(seq($.name, ':', $.expr), $.name),
|
|
|
- update: $ => seq('...', $.expr, ','),
|
|
|
- tuple: $ => choice(seq('(', ')'), seq(optional('parallel'), '(', $.exprlist, ')')),
|
|
|
- inline_ref: $ => seq(optional($.inline_module_prefix), $.name, optional($.inline_type_args)),
|
|
|
- inline_module_prefix: $ => seq($.name, '::'),
|
|
|
- inline_type_args: $ => seq('::', '[', $.type, repeat(seq(',', $.type)), ']'),
|
|
|
- list: $ => choice(seq('[', ']'), seq('[', $.exprlist, ']')),
|
|
|
- int: $ => Int,
|
|
|
- float: $ => Float,
|
|
|
- formatter: $ => seq($.formatter_text, repeat(seq('..', $.formatter_part))),
|
|
|
- formatter_part: $ => choice($.formatter_text, $.char),
|
|
|
- formatter_text: $ => DqStr,
|
|
|
- string: $ => seq($.string_text, repeat(seq('..', $.string_part))),
|
|
|
- string_part: $ => choice($.string_text, $.char),
|
|
|
- string_text: $ => SqStr,
|
|
|
- char: $ => Char,
|
|
|
- comment: $ => Comment,
|
|
|
- })
|
|
|
+ type: $ => $.ref,
|
|
|
+ ref: $ => seq($.ref_base, optional($.type_args)),
|
|
|
+ type_args: $ => seq('[', optional(seq($.type, repeat(seq(',', $.type)))), ']'),
|
|
|
+ expr: $ => seq(repeat($.cast), $.term, repeat($.pipe)),
|
|
|
+ cast: $ => seq('(', '[', $.type, ']', ')'),
|
|
|
+ pipe: $ => choice($.pipe_call, $.pipe_infix, $.pipe_cast, $.pipe_get, $.pipe_interior),
|
|
|
+ pipe_call: $ => choice($.call_ordered, $.call_unordered),
|
|
|
+ call_ordered: $ => seq('(', optional(seq($.expr, repeat(seq(',', $.expr)))), ')'),
|
|
|
+ call_unordered: $ => seq('{', optional(seq($.arg_mapping, repeat(seq(',', $.arg_mapping)))), '}'),
|
|
|
+ arg_mapping: $ => seq($.name, optional($.arg_mapping_to)),
|
|
|
+ arg_mapping_to: $ => seq(':', $.expr),
|
|
|
+ pipe_infix: $ => seq(optional('#'), '|', $.ref, $.pipe_call),
|
|
|
+ pipe_cast: $ => seq('.', $.cast),
|
|
|
+ pipe_get: $ => seq('.', $.name),
|
|
|
+ pipe_interior: $ => seq('.', '(', $.ref_base, ')'),
|
|
|
+ term: $ => choice($.infix_term, $.lambda, $.if, $.when, $.each, $.block, $.ref_term, $.int, $.float, $.char, $.bytes, $.string),
|
|
|
+ infix_term: $ => seq('(', $.infix_left, $.operator, $.infix_right, ')'),
|
|
|
+ infix_left: $ => $.expr,
|
|
|
+ operator: $ => $.ref,
|
|
|
+ infix_right: $ => $.expr,
|
|
|
+ lambda: $ => seq('{', optional($.pattern), optional($.lambda_self), '=>', $.expr, '}'),
|
|
|
+ lambda_self: $ => seq('&', $.name),
|
|
|
+ pattern: $ => choice($.pattern_single, $.pattern_multiple),
|
|
|
+ pattern_single: $ => $.name,
|
|
|
+ pattern_multiple: $ => seq('(', seq($.name, repeat(seq(',', $.name))), ')'),
|
|
|
+ if: $ => seq('if', '(', seq($.cond, repeat(seq(',', $.cond))), ')', $.if_yes, repeat($.elif), 'else', $.if_no),
|
|
|
+ cond: $ => seq(optional($.cond_pattern), $.expr),
|
|
|
+ cond_pattern: $ => seq('let', $.pattern, '='),
|
|
|
+ if_yes: $ => $.block,
|
|
|
+ if_no: $ => $.block,
|
|
|
+ elif: $ => seq('if', '(', seq($.cond, repeat(seq(',', $.cond))), ')', $.block),
|
|
|
+ when: $ => seq('when', '(', $.expr, ')', '{', seq($.case, repeat(seq(',', $.case))), '}'),
|
|
|
+ case: $ => seq(optional('#'), seq($.name, repeat(seq('|', $.name))), optional($.pattern), '=>', $.expr),
|
|
|
+ each: $ => seq('each', '(', $.type, ')', '{', seq($.case, repeat(seq(',', $.case))), '}'),
|
|
|
+ block: $ => seq('{', repeat($.binding), $.expr, '}'),
|
|
|
+ binding: $ => choice($.binding_plain, $.binding_cps),
|
|
|
+ binding_plain: $ => seq(optional('#'), choice('let', 'const'), $.pattern, '=', $.expr, ','),
|
|
|
+ binding_cps: $ => seq(optional('#'), '@', $.ref, optional($.cps_pattern), $.expr, ','),
|
|
|
+ cps_pattern: $ => seq($.pattern, '='),
|
|
|
+ ref_term: $ => seq(optional($.new), $.ref),
|
|
|
+ new: $ => seq('new', optional($.new_tag)),
|
|
|
+ new_tag: $ => seq(':', $.name),
|
|
|
+ int: $ => Int,
|
|
|
+ float: $ => Float,
|
|
|
+ char: $ => Char,
|
|
|
+ bytes: $ => repeat1($.byte),
|
|
|
+ byte: $ => Byte,
|
|
|
+ string: $ => seq($.text, repeat($.string_part)),
|
|
|
+ text: $ => Text,
|
|
|
+ string_part: $ => seq('..', $.string_part_content),
|
|
|
+ string_part_content: $ => choice($.text, $.char),
|
|
|
+ })
|
|
|
});
|
|
|
|
|
|
+
|