quick sort
This commit is contained in:
@@ -206,9 +206,15 @@ pub const Parser = struct {
|
||||
fn parseTypeExpr(self: *Parser) anyerror!*Node {
|
||||
const start = self.current.loc.start;
|
||||
|
||||
// Array type: [N]T
|
||||
// Array type: [N]T or Slice type: []T
|
||||
if (self.current.tag == .l_bracket) {
|
||||
self.advance(); // skip '['
|
||||
if (self.current.tag == .r_bracket) {
|
||||
// Slice type: []T
|
||||
self.advance(); // skip ']'
|
||||
const elem_type = try self.parseTypeExpr();
|
||||
return try self.createNode(start, .{ .slice_type_expr = .{ .element_type = elem_type } });
|
||||
}
|
||||
const len_node = try self.parseExpr();
|
||||
try self.expect(.r_bracket);
|
||||
const elem_type = try self.parseTypeExpr();
|
||||
@@ -231,11 +237,20 @@ pub const Parser = struct {
|
||||
|
||||
// Qualified name: ns.Type or ns.Type(args)
|
||||
while (self.current.tag == .dot) {
|
||||
const dot_lexer = self.lexer;
|
||||
const dot_current = self.current;
|
||||
const dot_prev_end = self.prev_end;
|
||||
self.advance();
|
||||
if (self.current.tag == .identifier or self.current.tag.isTypeKeyword()) {
|
||||
name = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ name, self.tokenSlice(self.current) });
|
||||
self.advance();
|
||||
} else break;
|
||||
} else {
|
||||
// Not a qualified name continuation — restore the dot
|
||||
self.lexer = dot_lexer;
|
||||
self.current = dot_current;
|
||||
self.prev_end = dot_prev_end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parameterized type: Vector(N, T) or later generic struct instantiation
|
||||
@@ -533,17 +548,27 @@ pub const Parser = struct {
|
||||
if (!found) {
|
||||
try type_params.append(self.allocator, .{ .name = param.name, .constraint = param.type_expr });
|
||||
}
|
||||
} else if (param.type_expr.data == .type_expr and param.type_expr.data.type_expr.is_generic) {
|
||||
var found = false;
|
||||
for (type_params.items) |existing| {
|
||||
if (std.mem.eql(u8, existing.name, param.type_expr.data.type_expr.name)) {
|
||||
found = true;
|
||||
break;
|
||||
} else {
|
||||
// Check for generic type param: direct $T or nested inside []$T
|
||||
const generic_type_expr: ?*Node = if (param.type_expr.data == .type_expr and param.type_expr.data.type_expr.is_generic)
|
||||
param.type_expr
|
||||
else if (param.type_expr.data == .slice_type_expr) blk: {
|
||||
const elem = param.type_expr.data.slice_type_expr.element_type;
|
||||
break :blk if (elem.data == .type_expr and elem.data.type_expr.is_generic) elem else null;
|
||||
} else null;
|
||||
|
||||
if (generic_type_expr) |gte| {
|
||||
var found = false;
|
||||
for (type_params.items) |existing| {
|
||||
if (std.mem.eql(u8, existing.name, gte.data.type_expr.name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const type_constraint = try self.createNode(param.type_expr.span.start, .{ .type_expr = .{ .name = "Type" } });
|
||||
try type_params.append(self.allocator, .{ .name = gte.data.type_expr.name, .constraint = type_constraint });
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const type_constraint = try self.createNode(param.type_expr.span.start, .{ .type_expr = .{ .name = "Type" } });
|
||||
try type_params.append(self.allocator, .{ .name = param.type_expr.data.type_expr.name, .constraint = type_constraint });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1034,6 +1059,10 @@ pub const Parser = struct {
|
||||
null;
|
||||
return try self.createNode(start, .{ .return_stmt = .{ .value = value } });
|
||||
},
|
||||
.l_bracket => {
|
||||
// Type expression in expression position: []T.[...] or [N]T.[...]
|
||||
return try self.parseTypeExpr();
|
||||
},
|
||||
.l_brace => {
|
||||
return self.parseBlock();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user