~rockorager/tree-sitter-hare

9fcbbb9817cc59847c7c192219ee4a0e10de08bc — Tim Culverhouse 1 year, 8 months ago 6208ca5
expressions: hide many nodes

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
1 files changed, 171 insertions(+), 154 deletions(-)

M grammar.js
M grammar.js => grammar.js +171 -154
@@ 64,11 64,27 @@ module.exports = grammar({
      seq(
        "use",
        choice(
          seq($.identifier, ";"),
          seq($.name, "=", $.identifier, ";"),
          seq($.identifier, "::", "{", $.member_list, "}", ";"),
          seq($.name, "=", $.identifier, "::", "{", $.member_list, "}", ";"),
          seq($.identifier, "::", "*", ";"),
          seq(field("path", $.identifier), ";"),
          seq(field("alias", $.name), "=", field("path", $.identifier), ";"),
          seq(
            field("path", $.identifier),
            "::",
            "{",
            field("members", $.member_list),
            "}",
            ";",
          ),
          seq(
            field("alias", $.name),
            "=",
            $.identifier,
            "::",
            "{",
            $.member_list,
            "}",
            ";",
          ),
          seq(field("path", $.identifier), "::", "*", ";"),
        ),
      ),



@@ 101,10 117,10 @@ module.exports = grammar({
    _global_binding: ($) =>
      seq(
        optional($.decl_attr),
        $.identifier,
        field("name", $.identifier),
        ":",
        $.type,
        optional(seq("=", $.expression)),
        field("type", $._type),
        optional(seq("=", field("value", $._expression))),
      ),

    decl_attr: ($) =>


@@ 122,7 138,8 @@ module.exports = grammar({
        optional(","),
      ),

    _constant_binding: ($) => seq($.identifier, ":", $.type, "=", $.expression),
    _constant_binding: ($) =>
      seq($.identifier, ":", $._type, "=", $._expression),

    type_declaration: ($) => seq("type", $._type_bindings),



@@ 131,7 148,7 @@ module.exports = grammar({

    _type_binding: ($) =>
      choice(
        seq($.identifier, "=", $.type),
        seq($.identifier, "=", $._type),
        seq($.identifier, "=", $.enum_type),
      ),



@@ 141,7 158,7 @@ module.exports = grammar({
        "fn",
        field("name", $.identifier),
        field("type", $.prototype),
        optional(seq("=", $.expression)),
        optional(seq("=", $._expression)),
      ),

    fndec_attr: ($) =>


@@ 150,11 167,11 @@ module.exports = grammar({
    fntype_attr: ($) => choice("@noreturn"),

    // Types.
    type: ($) => seq(optional("const"), optional("!"), $.storage_class),
    _type: ($) => seq(optional("const"), optional("!"), $._storage_class),

    storage_class: ($) =>
    _storage_class: ($) =>
      choice(
        $.scalar_type,
        $._scalar_type,
        $.struct_type,
        $.union_type,
        $.tuple_type,


@@ 165,7 182,7 @@ module.exports = grammar({
        $.unwrapped_alias,
      ),

    scalar_type: ($) =>
    _scalar_type: ($) =>
      choice(
        $.integer_type,
        $.floating_type,


@@ 208,10 225,11 @@ module.exports = grammar({
    enum_value: ($) =>
      choice(
        $.name,
        seq($.name, "=", $.expression),
        seq($.name, "=", $._expression),
      ),

    pointer_type: ($) => choice(seq("*", $.type), seq("nullable", "*", $.type)),
    pointer_type: ($) =>
      choice(seq("*", $._type), seq("nullable", "*", $._type)),

    struct_type: ($) => seq("struct", "{", $.struct_union_fields, "}"),
    union_type: ($) => seq("union", "{", $.struct_union_fields, "}"),


@@ 227,23 245,23 @@ module.exports = grammar({
      seq(
        optional($.offset_specifier),
        choice(
          seq($.name, ":", $.type),
          seq($.name, ":", $._type),
          $.struct_type,
          $.union_type,
          $.identifier,
        ),
      ),

    offset_specifier: ($) => seq("@offset", "(", $.expression, ")"),
    offset_specifier: ($) => seq("@offset", "(", $._expression, ")"),

    tuple_type: ($) => seq("(", $.tuple_types, ")"),

    tuple_types: ($) =>
      seq(
        $.type,
        $._type,
        ",",
        $.type,
        repeat(seq(",", $.type)),
        $._type,
        repeat(seq(",", $._type)),
        optional(","),
      ),



@@ 251,24 269,24 @@ module.exports = grammar({

    tagged_types: ($) =>
      seq(
        $.type,
        $._type,
        "|",
        $.type,
        repeat(seq("|", $.type)),
        $._type,
        repeat(seq("|", $._type)),
        optional("|"),
      ),

    slice_array_type: ($) =>
      choice(
        seq("[", "]", $.type),
        seq("[", $.expression, "]", $.type),
        seq("[", "*", "]", $.type),
        seq("[", "_", "]", $.type),
        seq("[", "]", $._type),
        seq("[", $._expression, "]", $._type),
        seq("[", "*", "]", $._type),
        seq("[", "_", "]", $._type),
      ),

    function_type: ($) => seq(optional($.fntype_attr), "fn", $.prototype),

    prototype: ($) => seq("(", optional($.parameter_list), ")", $.type),
    prototype: ($) => seq("(", optional($.parameter_list), ")", $._type),

    parameter_list: ($) =>
      seq(


@@ 279,14 297,14 @@ module.exports = grammar({
        optional(","),
      ),

    parameter: ($) => choice(seq($.name, ":", $.type), seq("_", ":", $.type)),
    parameter: ($) => choice(seq($.name, ":", $._type), seq("_", ":", $._type)),

    alias_type: ($) => $.identifier,

    unwrapped_alias: ($) => seq("...", $.identifier),

    // Expressions.
    constant: ($) =>
    _constant: ($) =>
      choice(
        $.integer_constant,
        $.floating_constant,


@@ 360,8 378,8 @@ module.exports = grammar({
    array_literal: ($) => seq("[", optional($.array_members), "]"),
    array_members: ($) =>
      seq(
        $.expression,
        repeat(seq(",", $.expression)),
        $._expression,
        repeat(seq(",", $._expression)),
        optional("..."),
        optional(","),
      ),


@@ 385,65 403,65 @@ module.exports = grammar({

    field_value: ($) =>
      choice(
        seq($.name, "=", $.expression),
        seq($.name, ":", $.type, "=", $.expression),
        seq($.name, "=", $._expression),
        seq($.name, ":", $._type, "=", $._expression),
        $.struct_literal,
      ),

    plain_expression: ($) =>
    _plain_expression: ($) =>
      choice(
        $.identifier,
        $.constant,
        $._constant,
        $.array_literal,
        $.struct_literal,
      ),

    nested_expression: ($) =>
    _nested_expression: ($) =>
      choice(
        $.plain_expression,
        seq("(", $.expression, ")"),
        $._plain_expression,
        seq("(", $._expression, ")"),
        seq("(", $.tuple_items, ")"),
      ),

    tuple_items: ($) =>
      seq(
        $.expression,
        repeat1(seq(",", $.expression)),
        $._expression,
        repeat1(seq(",", $._expression)),
        optional(","),
      ),

    allocation_expression: ($) =>
      choice(
        seq("alloc", "(", $.expression, ")"),
        seq("alloc", "(", $.expression, "...", ")"),
        seq("alloc", "(", $.expression, ",", $.expression, ")"),
        seq("free", "(", $.expression, ")"),
        seq("alloc", "(", $._expression, ")"),
        seq("alloc", "(", $._expression, "...", ")"),
        seq("alloc", "(", $._expression, ",", $._expression, ")"),
        seq("free", "(", $._expression, ")"),
      ),

    append_values: ($) =>
      choice(
        seq($.expression, optional(",")),
        seq("...", $.expression, optional(",")),
        seq($.expression, ",", $.append_values),
        seq($._expression, optional(",")),
        seq("...", $._expression, optional(",")),
        seq($._expression, ",", $.append_values),
      ),

    assertion_expression: ($) =>
      seq(
        optional("static"),
        choice(
          seq("assert", "(", $.expression, ")"),
          seq("assert", "(", $.expression, ",", $.string_constant, ")"),
          seq("assert", "(", $._expression, ")"),
          seq("assert", "(", $._expression, ",", $.string_constant, ")"),
          seq("abort", "(", optional($.string_constant), ")"),
        ),
      ),

    call_expression: ($) =>
      seq($.postfix_expression, "(", optional($.argument_list), ")"),
      seq($._postfix_expression, "(", optional($.argument_list), ")"),

    argument_list: ($) =>
      seq(
        $.expression,
        repeat(seq(",", $.expression)),
        $._expression,
        repeat(seq(",", $._expression)),
        optional("..."),
        optional(","),
      ),


@@ 451,16 469,16 @@ module.exports = grammar({
    measurement_expression: ($) =>
      choice($.size_expression, $.length_expression, $.offset_expression),

    size_expression: ($) => seq("size", "(", $.type, ")"),
    size_expression: ($) => seq("size", "(", $._type, ")"),

    length_expression: ($) => seq("len", "(", $.expression, ")"),
    length_expression: ($) => seq("len", "(", $._expression, ")"),

    offset_expression: ($) =>
      seq("offset", "(", $.field_access_expression, ")"),

    field_access_expression: ($) =>
      seq(
        $.postfix_expression,
        $._postfix_expression,
        ".",
        field(
          "selector",


@@ 472,15 490,15 @@ module.exports = grammar({
      ),

    indexing_expression: ($) =>
      seq($.postfix_expression, "[", $.expression, "]"),
      seq($._postfix_expression, "[", $._expression, "]"),

    slicing_expression: ($) =>
      seq(
        $.postfix_expression,
        $._postfix_expression,
        "[",
        optional($.expression),
        optional($._expression),
        "..",
        optional($.expression),
        optional($._expression),
        "]",
      ),



@@ 495,16 513,16 @@ module.exports = grammar({
      seq(
        optional("static"),
        choice(
          seq("append", "(", $.object_selector, ",", $.expression, ")"),
          seq("append", "(", $.object_selector, ",", $.expression, "...", ")"),
          seq("append", "(", $.object_selector, ",", $._expression, ")"),
          seq("append", "(", $.object_selector, ",", $._expression, "...", ")"),
          seq(
            "append",
            "(",
            $.object_selector,
            ",",
            $.expression,
            $._expression,
            ",",
            $.expression,
            $._expression,
            ")",
          ),
        ),


@@ 517,7 535,7 @@ module.exports = grammar({
        "(",
        $.indexing_expression,
        ",",
        $.expression,
        $._expression,
        optional("..."),
        ")",
      ),


@@ 534,11 552,11 @@ module.exports = grammar({
        ")",
      ),

    error_propagation: ($) => seq($.postfix_expression, choice("?", "!")),
    error_propagation: ($) => seq($._postfix_expression, choice("?", "!")),

    postfix_expression: ($) =>
    _postfix_expression: ($) =>
      choice(
        $.nested_expression,
        $._nested_expression,
        $.call_expression,
        $.field_access_expression,
        $.indexing_expression,


@@ 560,31 578,31 @@ module.exports = grammar({
        seq("vaend", "(", $.object_selector, ")"),
      ),

    builtin_expression: ($) =>
    _builtin_expression: ($) =>
      choice(
        $.allocation_expression,
        $.assertion_expression,
        $.measurement_expression,
        $.slice_mutation_expression,
        $.postfix_expression,
        $._postfix_expression,
        $.variadic_expression,
      ),

    unary_expression: ($) =>
    _unary_expression: ($) =>
      prec.left(
        PREC.UNARY,
        choice(
          $.builtin_expression,
          $._builtin_expression,
          $.compound_expression,
          $.match_expression,
          $.switch_expression,
          seq(choice("+", "-", "~", "!", "*", "&"), $.unary_expression),
          seq(choice("+", "-", "~", "!", "*", "&"), $._unary_expression),
        ),
        // prec.right(
        //   PREC.UNARY,
        //   seq(
        //     field("operator", choice("+", "-", "~", "!", "*")),
        //     field("argument", $.unary_expression),
        //     field("argument", $._unary_expression),
        //   ),
        // ),
        // prec.right(


@@ 596,151 614,151 @@ module.exports = grammar({
    // TODO these commented out pieces
    // unary_operator: ($) => choice("+", "-", "~", "!", "*", "&"),

    cast_expression: ($) =>
    _cast_expression: ($) =>
      choice(
        $.unary_expression,
        $._unary_expression,
        prec.left(
          PREC.CAST,
          field("type_cast", seq($.cast_expression, ":", $.type)),
          field("type_cast", seq($._cast_expression, ":", $._type)),
        ),
        prec.left(
          PREC.CAST,
          field("as_cast", seq($.cast_expression, "as", $.type)),
          field("as_cast", seq($._cast_expression, "as", $._type)),
        ),
        prec.left(
          PREC.CAST,
          field("is_cast", seq($.cast_expression, "is", $.type)),
          field("is_cast", seq($._cast_expression, "is", $._type)),
        ),
      ),

    multiplicative_expression: ($) =>
    _multiplicative_expression: ($) =>
      choice(
        $.cast_expression,
        $._cast_expression,
        prec.left(
          PREC.MULTIPLY,
          seq($.multiplicative_expression, "*", $.cast_expression),
          seq($._multiplicative_expression, "*", $._cast_expression),
        ),
        prec.left(
          PREC.MULTIPLY,
          seq($.multiplicative_expression, "/", $.cast_expression),
          seq($._multiplicative_expression, "/", $._cast_expression),
        ),
        prec.left(
          PREC.MULTIPLY,
          seq($.multiplicative_expression, "%", $.cast_expression),
          seq($._multiplicative_expression, "%", $._cast_expression),
        ),
      ),

    additive_expression: ($) =>
    _additive_expression: ($) =>
      choice(
        $.multiplicative_expression,
        $._multiplicative_expression,
        prec.left(
          PREC.ADD,
          seq($.additive_expression, "+", $.multiplicative_expression),
          seq($._additive_expression, "+", $._multiplicative_expression),
        ),
        prec.left(
          PREC.ADD,
          seq($.additive_expression, "-", $.multiplicative_expression),
          seq($._additive_expression, "-", $._multiplicative_expression),
        ),
      ),

    shift_expression: ($) =>
    _shift_expression: ($) =>
      choice(
        $.additive_expression,
        $._additive_expression,
        prec.left(
          PREC.SHIFT,
          seq($.multiplicative_expression, "<<", $.cast_expression),
          seq($._multiplicative_expression, "<<", $._cast_expression),
        ),
        prec.left(
          PREC.SHIFT,
          seq($.multiplicative_expression, ">>", $.cast_expression),
          seq($._multiplicative_expression, ">>", $._cast_expression),
        ),
      ),

    and_expression: ($) =>
    _and_expression: ($) =>
      choice(
        $.shift_expression,
        $._shift_expression,
        prec.left(
          PREC.BITWISE_AND,
          seq($.and_expression, "&", $.shift_expression),
          seq($._and_expression, "&", $._shift_expression),
        ),
      ),

    exclusive_or_expression: ($) =>
    _exclusive_or_expression: ($) =>
      choice(
        $.and_expression,
        $._and_expression,
        prec.left(
          PREC.BITWISE_XOR,
          seq($.exclusive_or_expression, "^", $.and_expression),
          seq($._exclusive_or_expression, "^", $._and_expression),
        ),
      ),

    inclusive_or_expression: ($) =>
    _inclusive_or_expression: ($) =>
      choice(
        $.exclusive_or_expression,
        $._exclusive_or_expression,
        prec.left(
          PREC.BITWISE_OR,
          seq($.inclusive_or_expression, "|", $.exclusive_or_expression),
          seq($._inclusive_or_expression, "|", $._exclusive_or_expression),
        ),
      ),

    comparison_expression: ($) =>
    _comparison_expression: ($) =>
      choice(
        $.inclusive_or_expression,
        $._inclusive_or_expression,
        prec.left(
          PREC.COMPARISON,
          seq($.comparison_expression, "<", $.inclusive_or_expression),
          seq($._comparison_expression, "<", $._inclusive_or_expression),
        ),
        prec.left(
          PREC.COMPARISON,
          seq($.comparison_expression, ">", $.inclusive_or_expression),
          seq($._comparison_expression, ">", $._inclusive_or_expression),
        ),
        prec.left(
          PREC.COMPARISON,
          seq($.comparison_expression, "<=", $.inclusive_or_expression),
          seq($._comparison_expression, "<=", $._inclusive_or_expression),
        ),
        prec.left(
          PREC.COMPARISON,
          seq($.comparison_expression, ">=", $.inclusive_or_expression),
          seq($._comparison_expression, ">=", $._inclusive_or_expression),
        ),
      ),

    equality_expression: ($) =>
    _equality_expression: ($) =>
      choice(
        $.comparison_expression,
        $._comparison_expression,
        prec.left(
          PREC.EQUALITY,
          seq($.equality_expression, "==", $.comparison_expression),
          seq($._equality_expression, "==", $._comparison_expression),
        ),
        prec.left(
          PREC.EQUALITY,
          seq($.equality_expression, "!=", $.comparison_expression),
          seq($._equality_expression, "!=", $._comparison_expression),
        ),
      ),

    logical_and_expression: ($) =>
    _logical_and_expression: ($) =>
      choice(
        $.equality_expression,
        $._equality_expression,
        prec.left(
          PREC.LOGICAL_AND,
          seq($.logical_and_expression, "&&", $.equality_expression),
          seq($._logical_and_expression, "&&", $._equality_expression),
        ),
      ),

    logical_xor_expression: ($) =>
    _logical_xor_expression: ($) =>
      choice(
        $.logical_and_expression,
        $._logical_and_expression,
        prec.left(
          PREC.LOGICAL_XOR,
          seq($.logical_xor_expression, "^^", $.logical_and_expression),
          seq($._logical_xor_expression, "^^", $._logical_and_expression),
        ),
      ),

    logical_or_expression: ($) =>
    _logical_or_expression: ($) =>
      choice(
        $.logical_xor_expression,
        $._logical_xor_expression,
        prec.left(
          PREC.LOGICAL_OR,
          seq($.logical_or_expression, "||", $.logical_xor_expression),
          seq($._logical_or_expression, "||", $._logical_xor_expression),
        ),
      ),



@@ 749,38 767,38 @@ module.exports = grammar({
        seq("if", $.conditional_branch),
        // TODO get this back in
        // seq("if", $.conditional_branch, "else", $.if_expression),
        seq("if", $.conditional_branch, "else", $.expression),
        seq("if", $.conditional_branch, "else", $._expression),
      ),

    conditional_branch: ($) => seq("(", $.expression, ")", $.expression),
    conditional_branch: ($) => seq("(", $._expression, ")", $._expression),

    for_loop: ($) => seq("for", "(", $.for_predicate, ")", $.expression),
    for_loop: ($) => seq("for", "(", $.for_predicate, ")", $._expression),

    for_predicate: ($) =>
      choice(
        $.expression,
        seq($.binding_list, ";", $.expression),
        seq($.expression, ";", $.expression),
        seq($.binding_list, ";", $.expression, ";", $.expression),
        $._expression,
        seq($.binding_list, ";", $._expression),
        seq($._expression, ";", $._expression),
        seq($.binding_list, ";", $._expression, ";", $._expression),
      ),

    switch_expression: ($) =>
      seq("switch", "(", $.expression, ")", "{", $.switch_cases, "}"),
      seq("switch", "(", $._expression, ")", "{", $.switch_cases, "}"),

    switch_cases: ($) => seq($.switch_case, repeat(seq(",", $.switch_case))),

    switch_case: ($) =>
      seq("case", optional($.case_options), "=>", $.expression),
      seq("case", optional($.case_options), "=>", $._expression),

    case_options: ($) =>
      seq(
        $.expression,
        repeat(seq(",", $.expression)),
        $._expression,
        repeat(seq(",", $._expression)),
        optional(","),
      ),

    match_expression: ($) =>
      seq("match", "(", $.expression, ")", "{", $.match_cases, "}"),
      seq("match", "(", $._expression, ")", "{", $.match_cases, "}"),

    match_cases: ($) => repeat1($.match_case),



@@ 788,19 806,19 @@ module.exports = grammar({
      seq(
        "case",
        choice(
          seq("let", $.name, ":", $.type, "=>", $.expression_list),
          seq("let", $.name, ":", $._type, "=>", $.expression_list),
          seq(
            "let",
            "(",
            $.binding_names,
            ")",
            ":",
            $.type,
            $._type,
            "=>",
            $.expression_list,
          ),
          seq($.type, "=>", $.expression),
          seq("=>", $.expression),
          seq($._type, "=>", $._expression),
          seq("=>", $._expression),
        ),
      ),



@@ 808,11 826,10 @@ module.exports = grammar({
      prec.left(
        PREC.ASSIGNMENT,
        choice(
          seq($.object_selector, $.assignment_op, $.expression),
          seq("*", $.unary_expression, $.assignment_op, $.expression),
          seq($.slicing_expression, "=", $.expression),
          // TODO this one, causes a conflict
          seq("(", $.binding_names, ")", "=", $.expression),
          seq($.object_selector, $.assignment_op, $._expression),
          seq("*", $._unary_expression, $.assignment_op, $._expression),
          seq($.slicing_expression, "=", $._expression),
          seq("(", $.binding_names, ")", "=", $._expression),
        ),
      ),



@@ 844,20 861,20 @@ module.exports = grammar({

    binding: ($) =>
      choice(
        seq($.name, "=", $.expression),
        seq($.name, ":", $.type, "=", $.expression),
        seq("(", $.binding_names, ")", "=", $.expression),
        seq("(", $.binding_names, ")", ":", $.type, "=", $.expression),
        seq($.name, "=", $._expression),
        seq($.name, ":", $._type, "=", $._expression),
        seq("(", $.binding_names, ")", "=", $._expression),
        seq("(", $.binding_names, ")", ":", $._type, "=", $._expression),
      ),

    binding_names: ($) => seq($.name, repeat1(seq(",", $.name))),

    defer_expression: ($) => seq("defer", $.expression),
    defer_expression: ($) => seq("defer", $._expression),

    expression_list: ($) =>
      repeat1(
        choice(
          seq($.expression, ";"),
          seq($._expression, ";"),
          seq($.binding_list, ";"),
          seq($.defer_expression, ";"),
        ),


@@ 877,7 894,7 @@ module.exports = grammar({
      choice(
        seq("break", optional($.label)),
        seq("continue", optional($.label)),
        seq("return", optional($.expression)),
        seq("return", optional($._expression)),
        $.yield_expression,
      ),



@@ 885,16 902,16 @@ module.exports = grammar({
      seq(
        "yield",
        choice(
          $.expression,
          $._expression,
          $.label,
          seq($.label, ",", $.expression),
          seq($.label, ",", $._expression),
        ),
      ),

    expression: ($) =>
    _expression: ($) =>
      choice(
        $.assignment,
        $.logical_or_expression,
        $._logical_or_expression,
        $.if_expression,
        $.for_loop,
        $.control_statement,