Skip to content

Conversation

@nojaf
Copy link
Member

@nojaf nojaf commented Jan 12, 2026

(builds on #260)

Problem

The parser failed to recognize else and else if clauses when they appeared on a new line after the closing brace of an if block. This caused valid ReScript code to produce parse errors.

Failing code example:

if predicateA {
  foo
} // comment before else if
else if predicateB {
  bar
}

The parser would incorrectly treat else as a standalone identifier and produce a MISSING ";" error, breaking the entire parse tree.

Root Cause

The external scanner (src/scanner.c) handles newline tokens specially in ReScript. When a newline is encountered, the scanner checks what follows to determine if the newline should terminate the current statement or be ignored (allowing the statement to continue on the next line).

The scanner already had special handling for:

  • -> (pipe operator)
  • | (variant declarations and switch matches)
  • ? and : (ternaries)
  • } (block closings)
  • and (recursive definitions)

However, else was missing from this list, causing newlines before else to incorrectly terminate the if_expression.

Solution

Added a check for the else keyword in the scanner's newline handling logic (lines 245-256 in src/scanner.c). When a newline is followed by else, the scanner now treats it as a multi-line statement continuation rather than a statement terminator.

} else if (lexer->lookahead == 'e') {
  advance(lexer);
  if (lexer->lookahead == 'l') {
    advance(lexer);
    if (lexer->lookahead == 's') {
      advance(lexer);
      if (lexer->lookahead == 'e') {
        // Ignore new lines before `else` keyword (else/else if clauses)
        in_multiline_statement = true;
      }
    }
  }
}

Testing

Added a new test case "If/else with else on new line" in test/corpus/expressions.txt that covers:

  • else if on a new line (without comment)
  • else on a new line (without comment)
  • else if on a new line with a comment between } and else if
  • else on a new line with a comment between } and else

All existing tests continue to pass.

Files Changed

  • src/scanner.c - Added else keyword detection in newline handling
  • test/corpus/expressions.txt - Added test cases for else on new line

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for else/else if clauses on new lines after closing braces and introduces dict expressions and patterns to the ReScript tree-sitter grammar. Additionally, it updates development tooling and adds documentation.

Changes:

  • Fixed parser to recognize else and else if keywords when they appear on a new line after a closing brace
  • Added dict expression (dict{"key": value}) and dict pattern support for destructuring
  • Updated Node.js to v24.11.1, tree-sitter-cli to 0.26.3, and added rescript compiler as dev dependency

Reviewed changes

Copilot reviewed 12 out of 14 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/scanner.c Added else keyword detection in newline handling to allow else clauses on new lines
test/corpus/expressions.txt Added comprehensive tests for else-on-newline scenarios and dict expressions/patterns
test/highlight/functions.res Added syntax highlighting test for dict pattern in function parameters
grammar.js Added dict expression and dict_pattern rules with proper conflict resolution
queries/highlights.scm Added highlighting rules for dict keywords, properties, and parameters
src/node-types.json Generated file with dict-related node type definitions and decorator extra flag
src/grammar.json Generated file with dict grammar rules
src/tree_sitter/parser.h Removed duplicate forward declaration of TSLanguageMetadata
package.json Updated tree-sitter-cli to 0.26.3 and added rescript 12.0.2
package-lock.json Updated lockfile for new dependencies
.nvmrc Updated Node version from v23.7.0 to v24.11.1
.github/workflows/ci.yml Added Node.js setup step using .nvmrc version
CLAUDE.md Added comprehensive development documentation for AI-assisted coding

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Add 'else' to scanner's multiline statement detection, matching 'and'
handling
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@aspeddro aspeddro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@nojaf nojaf merged commit 64249e6 into rescript-lang:main Jan 13, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants