tree-sitter-grammars / tree-sitter-hare

Hare grammar for tree-sitter
MIT License
10 stars 2 forks source link

feature: for-each loops? #5

Open nicferrier opened 1 month ago

nicferrier commented 1 month ago

Did you check the tree-sitter docs?

Is your feature request related to a problem? Please describe.

Hare has this new for-each expression:

const arr = [1,2,3];
for (let item .. arr) {
   fmt::println("the item:", item)!;
};

maybe you're already working on it?

otherwise maybe I'll try and learn how tree-sitter grammars work.

Describe the solution you'd like

Support the new syntax in the grammar.

I guess it would be really cool if somehow the grammar could be derived from the grammar in hare?

Describe alternatives you've considered

No response

Additional context

No response

nicferrier commented 1 month ago

Hmmm... did I do it?

diff --git a/grammar.js b/grammar.js
index 9540a19..785ac4d 100644
--- a/grammar.js
+++ b/grammar.js
@@ -287,7 +287,72 @@ module.exports = grammar({
       field('alternative', $.expression),
     )),

-    for_statement: $ => prec.right(seq(
+    for_statement: $ => choice(
+      $.c_for,
+      $.for_each,
+    ),
+
+    for_each: $ => prec.right(seq(
+      'for',
+      '(',
+      $.for_each_iterable_binding,
+      ')',
+      field('body', $.expression),
+    )),
+
+    for_each_iterable_binding: $ => prec.right(seq(
+      $.iterable_binding_left,
+      choice(
+        $.for_each_value,
+        $.for_each_reference,
+      )
+    )),
+
+    iterable_binding_left: $ => choice(
+      $.const_binding_type_infered,
+      $.const_binding_type_specified,
+      $.let_binding_type_infered,
+      $.let_binding_type_specified,
+    ),
+
+    const_binding_type_infered: $ => prec.right(seq(
+      'const',
+      $.identifier,
+    )),
+
+    const_binding_type_specified: $ => prec.right(seq(
+      'const',
+      $.identifier,
+      ':',
+      $.type,
+    )),
+
+    let_binding_type_infered: $ => prec.right(seq(
+      'let',
+      $.identifier,
+    )),
+
+    let_binding_type_specified: $ => prec.right(seq(
+      'let',
+      $.identifier,
+      ':',
+      $.type,
+    )),
+
+    for_each_value: $ => prec.right(seq(
+      $.identifier,
+      '..',
+      $.expression
+    )),
+
+    for_each_referencer: $ => prec.right(seq(
+      $.identifier,
+      '&',
+      '..',
+      $.expression
+    )),
+
+    c_for: $ => prec.right(seq(
       'for',
       '(',
       optional(seq($.let_expression, ';')),
nicferrier@nicdesk:~/srcs/tree-sitter-hare$