const PREC = { range: 15, call: 14, field: 13, unary: 12, cast: 11, multiplicative: 10, additive: 9, shift: 8, bitand: 7, bitxor: 6, bitor: 5, comparative: 4, and: 3, or: 2, assign: 0, closure: -1, }; module.exports = grammar({ name: "rhai", externals: ($) => [ $._string_content, $.raw_string_literal, $.float_literal, $.block_comment, ], extras: (_) => [/\s/], word: ($) => $.identifier, inline: ($) => [$._declaration_statement], supertypes: ($) => [ $._expression, $._literal, $._literal_pattern, $._declaration_statement, $._pattern, ], rules: { source_file: ($) => repeat($._statement), // statements _statement: ($) => choice($.expression_statement, $._declaration_statement), expression_statement: ($) => choice(seq($._expression, ";")), _declaration_statement: ($) => choice($.let_declaration), let_declaration: ($) => seq( "let", field("pattern", $._pattern), optional(seq("=", field("value", $._expression))), ";" ), // patterns _pattern: ($) => choice($._literal_pattern, $.identifier, "_"), // expressions _expression: ($) => choice($.assignment_expression, $._literal, prec.left($.identifier)), assignment_expression: ($) => prec.left( PREC.assign, seq(field("left", $._expression), "=", field("right", $._expression)) ), // literals _literal: ($) => choice($.string_literal, $.raw_string_literal, $.integer_literal), _literal_pattern: ($) => choice($.string_literal, $.raw_string_literal, $.integer_literal), integer_literal: (_) => token(seq(choice(/[0-9][0-9_]*/))), string_literal: ($) => seq( alias(/b?"/, '"'), repeat(choice($.escape_sequence, $._string_content)), token.immediate('"') ), escape_sequence: (_) => token.immediate( seq( "\\", choice( /[^xu]/, /u[0-9a-fA-F]{4}/, /u{[0-9a-fA-F]+}/, /x[0-9a-fA-F]{2}/ ) ) ), // identifiers identifier: ($) => /(r#)?[_\p{XID_Start}][_\p{XID_Continue}]*/, }, });