imports
This commit is contained in:
@@ -83,7 +83,7 @@ pub const Parser = struct {
|
||||
}
|
||||
|
||||
// All top-level declarations start with an identifier
|
||||
if (self.current.tag != .identifier and self.current.tag != .kw_Self) {
|
||||
if (!self.isIdentLike() and self.current.tag != .kw_Self) {
|
||||
return self.fail("expected identifier at top level");
|
||||
}
|
||||
const name = self.tokenSlice(self.current);
|
||||
@@ -426,7 +426,7 @@ pub const Parser = struct {
|
||||
}
|
||||
// Check for optional param name: `name: Type`
|
||||
// An identifier followed by `:` (not `::` or `:=`) is a param name
|
||||
if (self.current.tag == .identifier and self.peekNext() == .colon) {
|
||||
if (self.isIdentLike() and self.peekNext() == .colon) {
|
||||
const pname = self.tokenSlice(self.current);
|
||||
self.advance(); // skip name
|
||||
self.advance(); // skip ':'
|
||||
@@ -455,7 +455,7 @@ pub const Parser = struct {
|
||||
} });
|
||||
}
|
||||
|
||||
if (self.current.tag.isTypeKeyword() or self.current.tag == .identifier) {
|
||||
if (self.current.tag.isTypeKeyword() or self.isIdentLike()) {
|
||||
var name = self.tokenSlice(self.current);
|
||||
self.advance();
|
||||
|
||||
@@ -465,7 +465,7 @@ pub const Parser = struct {
|
||||
const dot_current = self.current;
|
||||
const dot_prev_end = self.prev_end;
|
||||
self.advance();
|
||||
if (self.current.tag == .identifier or self.current.tag.isTypeKeyword()) {
|
||||
if (self.isIdentLike() or self.current.tag.isTypeKeyword()) {
|
||||
name = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ name, self.tokenSlice(self.current) });
|
||||
self.advance();
|
||||
} else {
|
||||
@@ -1065,7 +1065,7 @@ pub const Parser = struct {
|
||||
is_ct_param = true;
|
||||
self.advance();
|
||||
}
|
||||
if (self.current.tag != .identifier) {
|
||||
if (!self.isIdentLike()) {
|
||||
return self.fail("expected parameter name");
|
||||
}
|
||||
const param_name = self.tokenSlice(self.current);
|
||||
@@ -1252,7 +1252,7 @@ pub const Parser = struct {
|
||||
|
||||
pub fn parseStmt(self: *Parser) anyerror!*Node {
|
||||
// Check if this is a declaration (IDENT followed by ::, :=, or : type)
|
||||
if (self.current.tag == .identifier) {
|
||||
if (self.isIdentLike()) {
|
||||
const saved_lexer = self.lexer;
|
||||
const saved_current = self.current;
|
||||
const saved_prev_end = self.prev_end;
|
||||
@@ -1721,10 +1721,11 @@ pub const Parser = struct {
|
||||
self.advance();
|
||||
return try self.createNode(start, .{ .identifier = .{ .name = name } });
|
||||
},
|
||||
.kw_closure => {
|
||||
// `closure` keyword used as identifier in expressions (closure intrinsic call)
|
||||
.kw_closure, .kw_protocol, .kw_impl, .kw_ufcs => {
|
||||
// Contextual keywords used as identifiers in expressions
|
||||
const name = self.tokenSlice(self.current);
|
||||
self.advance();
|
||||
return try self.createNode(start, .{ .identifier = .{ .name = "closure" } });
|
||||
return try self.createNode(start, .{ .identifier = .{ .name = name } });
|
||||
},
|
||||
.dot => {
|
||||
self.advance();
|
||||
@@ -2277,6 +2278,16 @@ pub const Parser = struct {
|
||||
|
||||
// ---- Helpers ----
|
||||
|
||||
/// Returns true if the current token can be used as an identifier name.
|
||||
/// Includes actual identifiers plus contextual keywords that are only
|
||||
/// keywords in specific syntactic positions (e.g., `protocol`, `impl`).
|
||||
fn isIdentLike(self: *const Parser) bool {
|
||||
return switch (self.current.tag) {
|
||||
.identifier, .kw_protocol, .kw_impl, .kw_ufcs, .kw_closure => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
fn isFunctionDef(self: *Parser) bool {
|
||||
const tag = self.peekPastParens() orelse return false;
|
||||
return tag == .l_brace or tag == .arrow or tag == .hash_builtin or tag == .hash_foreign or tag == .fat_arrow;
|
||||
|
||||
Reference in New Issue
Block a user