From 86c1127c46b0f97a7d0f2831288b30bbdd10fd8f Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 25 May 2026 21:18:09 +0300 Subject: [PATCH] ffi M1.0 (3/3): accept '=>' body in '#objc_class' member methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends parseForeignClassDecl ([src/parser.zig:1262]) with an arrow arm that mirrors the existing parseFnDecl shape — single- expression body wrapped in a one-statement block so downstream lowering sees the same AST as a brace-body method. Closes the M1.0 surface: '=> expr;' is now valid for top-level functions, struct methods, AND '#objc_class' member methods. The sx-defined class lowering (A.7 dispatch gate) is still gated, so 140-expression-bodied-objc-method.sx exercises parse-only — the body is reachable but the method is never invoked. When M1.2 lights up sx-defined class instantiation, the arrow-body form will flow through unchanged. 169 examples pass (+1 from 140 now green); zig build test green. --- src/parser.zig | 12 ++++++++++-- .../expected/140-expression-bodied-objc-method.exit | 2 +- tests/expected/140-expression-bodied-objc-method.txt | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/parser.zig b/src/parser.zig index bad8f67..e8154ea 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -1256,11 +1256,19 @@ pub const Parser = struct { } // Method body is optional: `;` → declaration (foreign or inherited - // method we just want to call); `{ ... }` → sx-side implementation - // for sx-defined classes. + // method we just want to call); `{ ... }` → sx-side block body + // for sx-defined classes; `=> expr;` → expression-body form + // (M1.0), lowered as a single-statement block holding `expr`. var body_node: ?*Node = null; if (self.current.tag == .l_brace) { body_node = try self.parseBlock(); + } else if (self.current.tag == .fat_arrow) { + self.advance(); + const expr = try self.parseExpr(); + try self.expect(.semicolon); + const stmts = try self.allocator.alloc(*Node, 1); + stmts[0] = expr; + body_node = try self.createNode(expr.span.start, .{ .block = .{ .stmts = stmts } }); } else { try self.expect(.semicolon); } diff --git a/tests/expected/140-expression-bodied-objc-method.exit b/tests/expected/140-expression-bodied-objc-method.exit index d00491f..573541a 100644 --- a/tests/expected/140-expression-bodied-objc-method.exit +++ b/tests/expected/140-expression-bodied-objc-method.exit @@ -1 +1 @@ -1 +0 diff --git a/tests/expected/140-expression-bodied-objc-method.txt b/tests/expected/140-expression-bodied-objc-method.txt index 57d4f6e..8b13789 100644 --- a/tests/expected/140-expression-bodied-objc-method.txt +++ b/tests/expected/140-expression-bodied-objc-method.txt @@ -1 +1 @@ -/Users/agra/projects/sx/examples/140-expression-bodied-objc-method.sx:15:35: error: expected ';' +