-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
libexpr: store ExprLambda data in Expr::alloc #14384
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -475,53 +475,77 @@ struct Formals | |||||||
| formals.begin(), formals.end(), arg, [](const Formal & f, const Symbol & sym) { return f.name < sym; }); | ||||||||
| return it != formals.end() && it->name == arg; | ||||||||
| } | ||||||||
|
|
||||||||
| std::vector<Formal> lexicographicOrder(const SymbolTable & symbols) const | ||||||||
| { | ||||||||
| std::vector<Formal> result(formals.begin(), formals.end()); | ||||||||
| std::sort(result.begin(), result.end(), [&](const Formal & a, const Formal & b) { | ||||||||
| std::string_view sa = symbols[a.name], sb = symbols[b.name]; | ||||||||
| return sa < sb; | ||||||||
| }); | ||||||||
| return result; | ||||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| struct ExprLambda : Expr | ||||||||
| { | ||||||||
| PosIdx pos; | ||||||||
| Symbol name; | ||||||||
| Symbol arg; | ||||||||
| Formals * formals; | ||||||||
|
|
||||||||
| bool ellipsis; | ||||||||
| bool hasFormals; | ||||||||
| uint16_t nFormals; | ||||||||
| Formal * formalsStart; | ||||||||
|
Comment on lines
+488
to
+489
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh we can't because padding. Fair enough. Add comment then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh and maybe make the underlying fields private too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That change would add 8 bytes to the struct.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah the private fields to preserve packing replaces the original suggestion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general I'm not a big fan of private fields, but I know I'm in the minority here and it doesn't matter to me that much. However, we haven't been making the fields private in any of the other Expr subtypes. I'd rather change that for all the relevant Expr sub-types in a separate MR, rather than have it be inconsistent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will say from a language design perspective, putting private information in the public header / interface file is disgusting, and C++ should feel bad about it. Does that match your feelings about private fields? That said, I do think abstract data types are fine in principle, and since we want to manually control layout while not foisting these encoding details on other code, I think private fields are the best tool we have in C++ for that job. I see you have fixed it with struct FormalsSpan{
std::span<Formal> formals;
bool ellipsis;
}and then [[gnu::always_inline]] std::optional<std::span<FormalsSpan>> getOptFormals() constThis will also enforce that the original And overall the less trivial Does this sound OK? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No I think we're on opposite pages here 😆. I feel like fields should always be accessible, especially within a codebase like this. I understand the benefits of encapsulation it's just not the style I prefer. I think your idea for structure is good. I'll implement it when I have a chance. |
||||||||
|
|
||||||||
| Expr * body; | ||||||||
| DocComment docComment; | ||||||||
|
|
||||||||
| ExprLambda(PosIdx pos, Symbol arg, Formals * formals, Expr * body) | ||||||||
| ExprLambda( | ||||||||
| std::pmr::polymorphic_allocator<char> & alloc, PosIdx pos, Symbol arg, const Formals & formals, Expr * body) | ||||||||
| : pos(pos) | ||||||||
| , arg(arg) | ||||||||
| , formals(formals) | ||||||||
| , body(body) {}; | ||||||||
| , ellipsis(formals.ellipsis) | ||||||||
| , hasFormals(true) | ||||||||
| , nFormals(formals.formals.size()) | ||||||||
| , formalsStart(alloc.allocate_object<Formal>(nFormals)) | ||||||||
| , body(body) | ||||||||
| { | ||||||||
| std::ranges::copy(formals.formals, formalsStart); | ||||||||
| }; | ||||||||
|
|
||||||||
| ExprLambda(PosIdx pos, Formals * formals, Expr * body) | ||||||||
| ExprLambda(std::pmr::polymorphic_allocator<char> & alloc, PosIdx pos, Symbol arg, Expr * body) | ||||||||
| : pos(pos) | ||||||||
| , formals(formals) | ||||||||
| , body(body) | ||||||||
| , arg(arg) | ||||||||
| , hasFormals(false) | ||||||||
| , formalsStart(nullptr) | ||||||||
| , body(body) {}; | ||||||||
|
|
||||||||
| ExprLambda(std::pmr::polymorphic_allocator<char> & alloc, PosIdx pos, Formals formals, Expr * body) | ||||||||
| : ExprLambda(alloc, pos, Symbol(), formals, body) {}; | ||||||||
|
|
||||||||
| bool hasFormal(Symbol arg) const | ||||||||
| { | ||||||||
| auto formals = getFormals(); | ||||||||
| auto it = std::lower_bound( | ||||||||
| formals.begin(), formals.end(), arg, [](const Formal & f, const Symbol & sym) { return f.name < sym; }); | ||||||||
| return it != formals.end() && it->name == arg; | ||||||||
| } | ||||||||
|
|
||||||||
| void setName(Symbol name) override; | ||||||||
| std::string showNamePos(const EvalState & state) const; | ||||||||
|
|
||||||||
| inline bool hasFormals() const | ||||||||
| std::vector<Formal> getFormalsLexicographic(const SymbolTable & symbols) const | ||||||||
| { | ||||||||
| return formals != nullptr; | ||||||||
| std::vector<Formal> result(getFormals().begin(), getFormals().end()); | ||||||||
| std::sort(result.begin(), result.end(), [&](const Formal & a, const Formal & b) { | ||||||||
| std::string_view sa = symbols[a.name], sb = symbols[b.name]; | ||||||||
| return sa < sb; | ||||||||
| }); | ||||||||
| return result; | ||||||||
| } | ||||||||
|
|
||||||||
| PosIdx getPos() const override | ||||||||
| { | ||||||||
| return pos; | ||||||||
| } | ||||||||
|
|
||||||||
| std::span<Formal> getFormals() const | ||||||||
| { | ||||||||
| assert(hasFormals); | ||||||||
| return {formalsStart, nFormals}; | ||||||||
| } | ||||||||
|
|
||||||||
| virtual void setDocComment(DocComment docComment) override; | ||||||||
| COMMON_METHODS | ||||||||
| }; | ||||||||
|
|
||||||||
Uh oh!
There was an error while loading. Please reload this page.