Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement anonymous struct literals and anonymous list literals #3652

Merged
merged 10 commits into from
Nov 12, 2019

Conversation

andrewrk
Copy link
Member

@andrewrk andrewrk commented Nov 11, 2019

This implements stage1 parser support for anonymous struct literal
syntax (see #685), as well as semantic analysis support for anonymous
struct literals and anonymous list literals (see #208). The semantic
analysis works when there is a type coercion in the result location;
inferring the struct type based on the values in the literal is not
implemented yet. Also remaining to do is zig fmt support for this new
syntax and documentation updates.

Merge Checklist

  • add a behavior test case for unions
  • add a behavior test case for anon list literal syntax
  • update self-hosted / zig fmt to handle anon struct literal syntax and anon list literal syntax
  • implement struct type inference based on the literal values when the result location of an anon struct literal does not have a type coercion
  • add compile error test for implement anonymous struct literals and anonymous list literals #3652 (comment)
  • implement anon list literal when the result location does not have a type coercion. this will make an anon struct type with field names numbered with indexes.
  • update documentation and grammar

Future Related Work

@daurnimator
Copy link
Contributor

daurnimator commented Nov 11, 2019

What about anonymous union literals? @as(MyUnion, .{.Foo = 42})

@andrewrk
Copy link
Member Author

What about anonymous union literals? @as(MyUnion, .{.Foo = 42})

Ah good call. That's part of this too. Adding a checklist item for this.

test "anonymous union literal syntax" {
    const S = struct {
        const Number = struct {
            int: i32,
            float: f64,
        };

        fn doTheTest() void {
            var i: Number = .{.int = 42};
            var f: Number = .{.float = 12.34};
            expect(i.int == 42);
            expect(f.float == 12.34);
        }
    };
    S.doTheTest();
    comptime S.doTheTest();
}

@andrewrk
Copy link
Member Author

Oops, I actually just accidentally typed struct instead of union in the test case listed in #3652 (comment). I actually had unions working just fine already :)

@data-man
Copy link
Contributor

Without a dot it will be more convenient, IMHO.

@andrewrk
Copy link
Member Author

Without a dot it will be more convenient, IMHO.

It certainly would. But then it would lose consistency with anon enum literal syntax, anon list literal syntax, and it would create a syntax ambiguity with blocks:

var x = {

Are we initializing a struct or running a block of code?

@data-man
Copy link
Contributor

var i: Number = <int = 42>;

@JesseRMeyer
Copy link

JesseRMeyer commented Nov 11, 2019

What about ditching the {} altogether?

    var i: Number = .int = 42; // implies '.int = 42, .float = <default float value>; see below
    var j: Number = .int = 42, .float = 42.0;

@emekoi Hi, what's confusing about this? In the original design, a parser has to chew through ".{" to figure out that a struct is being initialized, to clear the ambiguities that @andrewrk points out. The specialized syntax does away with that, and makes an extremely common task less obtuse to author.

This implements stage1 parser support for anonymous struct literal
syntax (see #685), as well as semantic analysis support for anonymous
struct literals and anonymous list literals (see #208). The semantic
analysis works when there is a type coercion in the result location;
inferring the struct type based on the values in the literal is not
implemented yet. Also remaining to do is zig fmt support for this new
syntax and documentation updates.
@andrewrk
Copy link
Member Author

Another checklist item, add a compile error test for this (incorrectly passes in master, correctly gives compile error in this branch). Thanks @dimenus for the case

pub const StaticGeoType = enum {
    Rect,
    Cube,
};

fn descFn() []const u8 {
    return comptime [_]u8{ 1, 2, 3, 4 };
}

const AttrDescFn = fn () []const u8;

const Geo3DTex2D = createGeometry([5]f32, u16, descFn);

pub fn createGeometry(comptime VertType: type, comptime IndType: type, attrDescFn: AttrDescFn) type {
    return struct {
        vertices: []VertType,
        vertStride: usize = @sizeOf(VertType),
        vertBaseTypeSize: usize = @sizeOf(VertType),
        indices: []IndType,
        indBaseTypeSize: usize = @sizeOf(IndType),
        getAttrDescFn: AttrDescFn = attrDescFn,
    };
}

pub fn getGeo3DTex2D(comptime geo_type: StaticGeoType) Geo3DTex2D {
    switch (geo_type) {
        .Rect => return Geo3DTex2D{
            .vertices = [_][5]f32{
                [_]f32{ -0.5, -0.5, 0.0, 0.0, 0.0 },
                [_]f32{ 0.5, -0.5, 0.0, 1.0, 0.0 },
                [_]f32{ 0.5, 0.5, 0.0, 1.0, 1.0 },
                [_]f32{ -0.5, 0.5, 0.0, 0.0, 1.0 },
            },
            .indices = [_]u16{ 0, 1, 2, 2, 3, 0 },
        },
        .Cube => @compileError("Cube is not implemented yet"),
    }
}

test "array compliation error" {
    var geo_data = comptime getGeo3DTex2D(.Rect);
}

@Rocknest
Copy link
Contributor

wait 1 release cycle, and remove the deprecated old syntax.

Does it mean that StructName {.a = b} will be removed? Why?

@andrewrk
Copy link
Member Author

Does it mean that StructName {.a = b} will be removed? Why?

The null hypothesis is to not have extra syntax. Why should it be added to the language?

@Rocknest
Copy link
Contributor

@andrewrk What about enums?

@andrewrk
Copy link
Member Author

That's a good point - you could make an analogy with Enum.name being redundant with @as(Enum, .name).

@ghost
Copy link

ghost commented Nov 11, 2019

Are we going to lose the underscore syntax [_]u8 for arrays?

Maybe a new @as variant will be required, something like @asArray(u8, .{1, 2, 3}) ?

@andrewrk
Copy link
Member Author

andrewrk commented Nov 11, 2019

Are we going to lose the underscore syntax [_]u8 for arrays?

This syntax is not really redundant with anything, as you noted by suggesting that it would require different syntax to replace. So I don't see any reason to change that.

As for the other redundant syntax, let's leave it be for a bit, and see how it feels. If it makes it worse in practice to use @as(Foo, .{.a = b}) rather than Foo{.a = b}, then it's worth considering to keep the redundant syntax.

I'll make a proposal issue for removing the redundant syntax and we can discuss there. I won't rush it.

@andrewrk
Copy link
Member Author

@data-man & @JesseRMeyer if you want your proposals to be taken seriously, file new issues, please - this PR is an implementation of two already accepted proposals.

@andrewrk andrewrk merged commit 5502160 into master Nov 12, 2019
@andrewrk andrewrk deleted the anon-container-lit branch November 12, 2019 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants