ffi M5.A.next.1b: parser accepts ..$args as a variadic-pack param
Extends parseParams in src/parser.zig:1558 to recognize a leading `..` before the optional `$` sigil and the parameter name. The old `args: ..T` form (variadic marker after the colon) still works — both paths set the same `is_variadic` flag. A pack declaration `..$args` parses as: - `is_variadic = true` (from the leading `..`) - `is_comptime = true` (from the `$` sigil) - `type_expr = inferred_type` (no `:` annotation) The no-colon branch now propagates `is_variadic` and `is_comptime` onto the Param struct so later slices (type rep, impl matching, monomorphisation) can read both flags from the parsed AST without re-deriving from token sequence. `examples/150-pack-parse.sx` flips from rejecting-with-error to positive parse smoke. No semantic effect yet — `foo` is declared but never instantiated. 191/191 example tests + `zig build test` green.
This commit is contained in:
@@ -1563,6 +1563,15 @@ pub const Parser = struct {
|
||||
try self.expect(.comma);
|
||||
if (self.current.tag == .r_paren) break;
|
||||
}
|
||||
// Leading `..` marks a variadic param at the binding site
|
||||
// (e.g., `..$args` heterogeneous pack, or future homogeneous
|
||||
// `..args: []$T`). The old `args: ..T` form keeps its marker
|
||||
// after the colon (handled below).
|
||||
var is_variadic = false;
|
||||
if (self.current.tag == .dot_dot) {
|
||||
is_variadic = true;
|
||||
self.advance();
|
||||
}
|
||||
var is_ct_param = false;
|
||||
if (self.current.tag == .dollar) {
|
||||
is_ct_param = true;
|
||||
@@ -1577,12 +1586,17 @@ pub const Parser = struct {
|
||||
// Optional type annotation: if no ':', infer type from context
|
||||
if (self.current.tag != .colon) {
|
||||
const inferred_node = try self.createNode(param_name_span.start, .{ .inferred_type = {} });
|
||||
try params.append(self.allocator, .{ .name = param_name, .name_span = param_name_span, .type_expr = inferred_node });
|
||||
try params.append(self.allocator, .{ .name = param_name, .name_span = param_name_span, .type_expr = inferred_node, .is_variadic = is_variadic, .is_comptime = is_ct_param });
|
||||
continue;
|
||||
}
|
||||
self.advance(); // consume ':'
|
||||
const is_variadic = self.current.tag == .dot_dot;
|
||||
if (is_variadic) self.advance();
|
||||
// Old syntax keeps the variadic marker after the colon
|
||||
// (`args: ..T`). Accept it even if a leading `..` already
|
||||
// appeared — both forms set the same flag.
|
||||
if (self.current.tag == .dot_dot) {
|
||||
is_variadic = true;
|
||||
self.advance();
|
||||
}
|
||||
const param_type = try self.parseTypeExpr();
|
||||
var is_comptime_param = false;
|
||||
if (is_ct_param and param_type.data == .type_expr) {
|
||||
|
||||
Reference in New Issue
Block a user