patx/relay-lang

Handle dedent-before-else in if parsing

Commit 65b58f0 · Harrison Erd · 2026-02-10T17:34:45-05:00

Changeset
65b58f00d234b18140e7096a55f1b0ec05921e21
Parents
dfdbfa792086ea44469a5c8d6b36307dd1be4e43

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/src/main.rs b/src/main.rs
index f78f5cb..57b6724 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -721,6 +721,12 @@ impl Parser {
             return self.parse_import();
         }
 
+        if self.peek_else() {
+            return Err(
+                self.err_here("'else' without matching if (check indentation and block structure)")
+            );
+        }
+
         if self.peek_destructure_assign() {
             return self.parse_destructure_assign();
         }
@@ -820,7 +826,13 @@ impl Parser {
         self.expect_newline()?;
         let then_block = self.parse_block()?;
         let mut else_block = Vec::new();
+
         self.skip_newlines();
+        while self.peek_is(&Tok::Dedent) && self.peek_n_else(1) {
+            self.bump();
+            self.skip_newlines();
+        }
+
         if self.peek_else() {
             self.bump();
             self.expect_newline()?;
@@ -1204,6 +1216,10 @@ impl Parser {
             .map(|t| &t.kind == k)
             .unwrap_or(false)
     }
+    fn peek_n_else(&self, n: usize) -> bool {
+        matches!(self.t.get(self.i + n), Some(Token { kind: Tok::Keyword(k), .. }) if k == "else")
+            || matches!(self.t.get(self.i + n), Some(Token { kind: Tok::Ident(s), .. }) if s == "else")
+    }
     fn peek_op(&self, s: &str) -> bool {
         matches!(self.peek(), Some(Token { kind: Tok::Op(op), .. }) if op == s)
     }