grammar.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // @ts-nocheck
  2. const Pragma = /#[^\n]*/
  3. const SqStr = /'[^']*'/
  4. const DqStr = /"[^"]*"/
  5. const Comment = /\/\*([^\*\/]|\*[^\/]|[^\*]\/)*\*\/|\/\/[^\n]*/
  6. const Blank = /[ \t\r ]+/
  7. const LF = /\n+/
  8. const Int = /\-?0[xX][0-9A-Fa-f]+|\-?0[oO][0-7]+|\-?0[bB][01]+|\-?\d[\d_]*/
  9. const Float = /\-?\d+(\.\d+)?[Ee][\+\-]?\d+|\-?\d+\.\d+/
  10. const Char = /`.`|\\u[0-9A-Fa-f]+|\\[a-z]/
  11. const Name = /[^0-9\{\}\[\]\(\)\.,:;\#\&\|\\'"` \t\r \n][^\{\}\[\]\(\)\.,:;\#\&\|\\'"` \t\r \n]*/
  12. module.exports = grammar({
  13. name: 'kumachan',
  14. extras: $ => [$.comment, $.pragma, Blank, LF],
  15. rules: (raw => {
  16. let rules = {}
  17. for (let [k,v] of Object.entries(raw)) {
  18. let decorate = (g, f) => $ => f(g($))
  19. if (k == 'inline_type_args' || k == 'inline_ref') {
  20. v = decorate(v, x => prec.left(x))
  21. } else {
  22. v = decorate(v, x => prec.right(x))
  23. }
  24. rules[k] = v
  25. }
  26. return rules
  27. })({
  28. source_file: $ => $.stmts,
  29. stmts: $ => repeat1($.stmt),
  30. stmt: $ => choice($.import, $.do, $.decl_type, $.decl_const, $.decl_func),
  31. import: $ => seq('import', $.name, 'from', $.string_text, ';'),
  32. name: $ => Name,
  33. do: $ => seq('do', $.expr, ';'),
  34. type: $ => choice($.type_literal, $.type_ref),
  35. type_ref: $ => seq(optional($.module_prefix), $.name, optional($.type_args)),
  36. module_prefix: $ => choice(seq($.name, '::'), '::'),
  37. type_args: $ => seq('[', $.type, repeat(seq(',', $.type)), ']'),
  38. type_literal: $ => $.repr,
  39. repr: $ => choice($.repr_func, $.repr_tuple, $.repr_bundle),
  40. repr_tuple: $ => choice(seq('(', ')'), seq('(', $.type, repeat(seq(',', $.type)), ')')),
  41. repr_bundle: $ => choice(seq('{', '}'), seq('{', $.field, repeat(seq(',', $.field)), '}')),
  42. field: $ => seq($.name, ':', $.type),
  43. repr_func: $ => seq('&', $.input_type, '=>', $.output_type),
  44. input_type: $ => $.type,
  45. output_type: $ => $.type,
  46. decl_type: $ => seq('type', $.name, optional($.type_params), optional($.type_value), ';'),
  47. type_value: $ => choice($.native_type, $.implicit_type, $.enum_type, $.boxed_type),
  48. native_type: $ => 'native',
  49. implicit_type: $ => seq('implicit', $.repr_bundle),
  50. enum_type: $ => seq('enum', '{', repeat1($.decl_type), '}'),
  51. boxed_type: $ => seq(optional($.box_option), optional('weak'), $.inner_type),
  52. box_option: $ => choice('protected', 'opaque'),
  53. inner_type: $ => $.type,
  54. type_params: $ => seq('[', $.type_param, repeat(seq(',', $.type_param)), ']'),
  55. type_param: $ => seq(optional(seq('[', $.type, ']')), $.name, optional($.type_bound)),
  56. type_bound: $ => seq(choice('<', '>'), $.type),
  57. decl_func: $ => seq(optional('export'), 'function', $.name, ':', optional($.type_params), $.signature, optional($.body), ';'),
  58. signature: $ => seq(optional($.implicit_input), $.repr_func),
  59. implicit_input: $ => seq('(', $.type, repeat(seq(',', $.type)), ')'),
  60. body: $ => choice($.native, $.lambda),
  61. native: $ => seq('native', $.string_text),
  62. lambda: $ => seq('&', $.pattern, '=>', $.expr),
  63. pattern: $ => choice($.pattern_trivial, $.pattern_tuple, $.pattern_bundle),
  64. pattern_trivial: $ => $.name,
  65. pattern_tuple: $ => choice(seq('(', ')'), seq('(', $.name, repeat(seq(',', $.name)), ')')),
  66. pattern_bundle: $ => choice(seq('{', '}'), seq('{', $.name, optional(seq(':', $.name)), repeat(seq(',', $.name, optional(seq(':', $.name)))), '}')),
  67. decl_const: $ => seq(optional('export'), 'const', $.name, ':', $.type, optional($.const_value), ';'),
  68. const_value: $ => seq(':=', choice($.native, $.expr)),
  69. expr: $ => seq($.term, optional($.pipeline)),
  70. pipeline: $ => seq($.pipe, optional($.pipeline)),
  71. pipe: $ => choice (
  72. $.pipe_func, $.pipe_cast,
  73. $.pipe_get, $.pipe_field_ref,
  74. $.pipe_switch, $.pipe_branch_ref
  75. ),
  76. pipe_func: $ => seq('.', '{', $.callee, optional($.expr), '}'),
  77. callee: $ => seq($.expr),
  78. pipe_cast: $ => seq('.', '[', $.type, ']'),
  79. pipe_get: $ => seq('.', $.name),
  80. pipe_field_ref: $ => seq('.', '&', $.name),
  81. pipe_switch: $ => seq('.', '(', $.type_ref, ')'),
  82. pipe_branch_ref: $ => seq('.', '&', '(', $.type_ref, ')'),
  83. term: $ => choice (
  84. $.call, $.lambda, $.multi_switch, $.switch, $.if,
  85. $.block, $.cps, $.bundle, $.tuple, $.inline_ref,
  86. $.array, $.int, $.float, $.formatter, $.string, $.char
  87. ),
  88. call: $ => choice($.call_prefix, $.call_infix),
  89. call_prefix: $ => seq('{', $.callee, $.expr, '}'),
  90. call_infix: $ => seq('(', $.infix_left, $.operator, $.infix_right, ')'),
  91. operator: $ => $.expr,
  92. infix_left: $ => $.expr,
  93. infix_right: $ => $.expr,
  94. multi_switch: $ => seq('select', '(', $.exprlist, ')', ':', $.multi_branch_list, 'end'),
  95. exprlist: $ => seq($.expr, repeat(seq(',', $.expr))),
  96. multi_branch_list: $ => repeat1(seq($.multi_branch, ',')),
  97. multi_branch: $ => seq($.multi_branch_key, ':', $.expr),
  98. multi_branch_key: $ => choice('default', seq('case', $.multi_ref, optional($.multi_pattern))),
  99. multi_ref: $ => seq('(', $.type_ref_list, ')'),
  100. type_ref_list: $ => seq($.type_ref, repeat(seq(',', $.type_ref))),
  101. multi_pattern: $ => $.pattern_tuple,
  102. switch: $ => seq('switch', $.expr, ':', $.branch_list, 'end'),
  103. branch_list: $ => repeat1(seq($.branch, ',')),
  104. branch: $ => choice(seq('default', ':', $.expr), seq('case', $.type_ref, repeat(seq(',', $.type_ref)), optional($.pattern), ':', $.expr)),
  105. if: $ => seq('if', $.expr, ':', $.expr, ',', repeat($.elif), 'else', ':', $.expr),
  106. elif: $ => seq('elif', $.expr, ':', $.expr, ','),
  107. block: $ => seq($.binding, $.block_value),
  108. binding: $ => seq('let', $.pattern, optional($.binding_type), ':=', $.expr),
  109. binding_type: $ => seq(':', optional('rec'), $.type),
  110. block_value: $ => seq(',', $.expr),
  111. cps: $ => seq('|', optional($.cps_binding), $.inline_ref, $.cps_input, ',', $.cps_output),
  112. cps_binding: $ => seq($.pattern, optional($.binding_type), ':='),
  113. cps_input: $ => $.expr,
  114. cps_output: $ => $.expr,
  115. bundle: $ => choice(seq('{', '}'), seq('{', optional($.update), $.pairlist, '}')),
  116. pairlist: $ => seq($.pair, repeat(seq(',', $.pair))),
  117. pair: $ => choice(seq($.name, ':', $.expr), $.name),
  118. update: $ => seq('...', $.expr, ','),
  119. tuple: $ => choice(seq('(', ')'), seq('(', $.exprlist, ')')),
  120. inline_ref: $ => seq(optional($.inline_module_prefix), $.name, optional($.inline_type_args)),
  121. inline_module_prefix: $ => seq($.name, '::'),
  122. inline_type_args: $ => seq('::', '[', $.type, repeat(seq(',', $.type)), ']'),
  123. array: $ => choice(seq('[', ']'), seq('[', $.exprlist, ']')),
  124. int: $ => Int,
  125. float: $ => Float,
  126. formatter: $ => seq($.formatter_text, repeat(seq('..', $.formatter_part))),
  127. formatter_part: $ => choice($.formatter_text, $.char),
  128. formatter_text: $ => DqStr,
  129. string: $ => seq($.string_text, repeat(seq('..', $.string_part))),
  130. string_part: $ => choice($.string_text, $.char),
  131. string_text: $ => SqStr,
  132. char: $ => Char,
  133. comment: $ => Comment,
  134. pragma: $ => Pragma,
  135. })
  136. });