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

[SUGGESTION] Aggregate initialization of structs/objects #401

Closed
realgdman opened this issue May 1, 2023 · 7 comments
Closed

[SUGGESTION] Aggregate initialization of structs/objects #401

realgdman opened this issue May 1, 2023 · 7 comments

Comments

@realgdman
Copy link

I haven't found a way to aggregate initialize struct.

Background: I'm working with Entity-Component-System. It supposes to have many POD structs. Writing constructor in each is cumbersome.
In C++ they could be simply initialized with S s { 1, 7 };
I don't know if I missed correct syntax or it is intended, or is it bug.

S : @struct type = {
public x : int;
public y : float;
}

main: () = {
//s1: S = (1, 2); //cpp2 Ok, cpp1 no matching ctor S s1 {1, 2};

//s2: S;
//s2 = (1, 2); //cpp2 Ok, cpp1 no matching ctor s2.construct(1,2);
}

foo: (inout s3 : S) = {
//s3 = (1, 2); //cpp2 Ok, cpp1 no viable overloaded = s3 = 1, 2;
//s4 = ((1, 2)); //cpp2 Ok, cpp1 no viable overloaded = s4 = 1, 2;
//s5 = (.x=1, .y=2); //I know named not in cpp2 yet
//s6 = {1, 2}; //cpp2 ill formed initializer at {
//also tried for fun s7 = (copy (1, 2) - it emits cpp1 copy(1,2) }`

If it is intended to not have aggregate init, it would be good to have some meta facility, like one autogenerated constructor, which have as parameters all data members in order.

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

See 1886ed2#r110677033.
You can't declare aggregates in Cpp2 yet.

@realgdman
Copy link
Author

Also currently on that assignment, parens got removed, which popped little evil comma operator.

Reproduction example
S : type = {
public x : int = 0;
public y : float = 0;
operator=: (out this, i: int, j: float) = { x = i; y = j; }
operator=: (inout this, i: int) = x = i; //introduced assignment operator
}

main: () = {
s: S = (1, 2);
s = (3, 4); //in cpp1: s = 3, 4; clang warning unused result
std::cout << "(s.x)$; (s.y)$\n"; //print 3; 0.00
}

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

That's #321.

@realgdman
Copy link
Author

realgdman commented May 1, 2023

Writing constructor in each is cumbersome.

Actually its not allowed to write custom constructor for @struct
error: while applying @struct - a struct may not have a user-defined operator=
So I step back to s: S = (); s.myinit(x, y);

@realgdman
Copy link
Author

I have read p0707 proposal, and I see what is meant by @aggregate meta, but I was talking purely about simplicity of use of @struct meta. Because POD structs easy to aggregate initialize in cpp1 by S s { 1, 7 }; compared to my cpp2 s: S = (); s.myinit(1, 7); because I think cpp2 doesnt have that syntax.

@realgdman
Copy link
Author

realgdman commented May 1, 2023

Small proof of concept, only for ints. Before line

basic_value(t); // a plain_struct is-a basic_value

std::string ctor_params = "";
std::string ctor_body = "";
for (auto m : t.get_members()) {
if(m.is_object()) {
ctor_params += ", ctor_" + std::string(m.name()) + ": int";
//TODO reflection +std::string(m.as_object().get_type());
ctor_body += '\n' + std::string(m.name()) + " = ctor_" +
std::string(m.name()) + ";";
}
}
std::string ctor = "operator=: (out this" + ctor_params + ") = {"
+ ctor_body + "}";
t.add_member(ctor);

After which this cpp2 compiles:

S : @struct type = {
x : int = 0;
y : int = 0;
z : i32 = 0;
}

main: () = {
sA: S = (1, 3, 5);
std::cout << sA.y; //prints 3
}

Which generates cpp2
operator=: (out this, ctor_x: int, ctor_y: int, ctor_z: int) = { x = ctor_x; y = ctor_y; z = ctor_z;}

Which emits cpp1
S::S(cpp2::in<int> ctor_x, cpp2::in<int> ctor_y, cpp2::in<int> ctor_z) : x{ ctor_x }, y{ ctor_y }, z{ ctor_z }{}

@realgdman
Copy link
Author

Closing in favor of #426 to avoid duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants