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:
@@ -1,14 +1,14 @@
|
||||
// Variadic heterogeneous type packs — `..$args` — parse lockin.
|
||||
// Variadic heterogeneous type packs — `..$args` — parse smoke.
|
||||
//
|
||||
// First slice of the pack feature: the parser does not yet accept
|
||||
// `..$args` (variadic-marker + comptime sigil + name, no type
|
||||
// annotation). This test pins the current parse-rejection so the
|
||||
// next commit's parser change is visible as a behavior shift.
|
||||
// First positive slice of the pack feature: the parser accepts
|
||||
// `..$args` (variadic marker + comptime sigil + name) as a
|
||||
// parameter declaration. No semantic effect yet — the function
|
||||
// is declared but never instantiated; main exists so the example
|
||||
// has runnable output.
|
||||
//
|
||||
// Expected next commit: parser accepts `..$args` and this test
|
||||
// either flips to a successful parse (compile error from later
|
||||
// passes that haven't been wired up yet) or is replaced by a
|
||||
// positive test.
|
||||
// Next slices: type-system representation of the pack, impl
|
||||
// matching for `Closure(..$args) -> $R`, runtime indexing
|
||||
// (`args[$i]`), and the `#insert build_x($args, ...)` pattern.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
@@ -17,6 +17,6 @@ foo :: (..$args) -> s64 {
|
||||
}
|
||||
|
||||
main :: () -> s32 {
|
||||
print("never reached\n");
|
||||
print("pack parse ok\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
1
|
||||
0
|
||||
|
||||
@@ -1 +1 @@
|
||||
/Users/agra/projects/sx/examples/150-pack-parse.sx:15:9: error: expected parameter name
|
||||
pack parse ok
|
||||
|
||||
Reference in New Issue
Block a user