use the same bindings print for ExprAttrs and ExprLet

this also has the effect of sorting let bindings lexicographically
rather than by symbol creation order as was previously done, giving a
better canonicalization in the process.

(cherry picked from commit 6c08fba533)
Change-Id: Ia887f629305645bb8a165fbbc0d32e620912595a
This commit is contained in:
eldritch horrors 2024-03-08 09:51:51 +01:00
parent 1cf0fa0633
commit bf19eebb9b
3 changed files with 12 additions and 13 deletions

View file

@ -68,10 +68,8 @@ void ExprOpHasAttr::show(const SymbolTable & symbols, std::ostream & str) const
str << ") ? " << showAttrPath(symbols, attrPath) << ")";
}
void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
void ExprAttrs::showBindings(const SymbolTable & symbols, std::ostream & str) const
{
if (recursive) str << "rec ";
str << "{ ";
typedef const decltype(attrs)::value_type * Attr;
std::vector<Attr> sorted;
for (auto & i : attrs) sorted.push_back(&i);
@ -95,6 +93,13 @@ void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
i.valueExpr->show(symbols, str);
str << "; ";
}
}
void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
{
if (recursive) str << "rec ";
str << "{ ";
showBindings(symbols, str);
str << "}";
}
@ -150,15 +155,7 @@ void ExprCall::show(const SymbolTable & symbols, std::ostream & str) const
void ExprLet::show(const SymbolTable & symbols, std::ostream & str) const
{
str << "(let ";
for (auto & i : attrs->attrs)
if (i.second.inherited()) {
str << "inherit " << symbols[i.first] << "; ";
}
else {
str << symbols[i.first] << " = ";
i.second.e->show(symbols, str);
str << "; ";
}
attrs->showBindings(symbols, str);
str << "in ";
body->show(symbols, str);
str << ")";

View file

@ -201,6 +201,8 @@ struct ExprAttrs : Expr
ExprAttrs() : recursive(false) { };
PosIdx getPos() const override { return pos; }
COMMON_METHODS
void showBindings(const SymbolTable & symbols, std::ostream & str) const;
};
struct ExprList : Expr

View file

@ -1 +1 @@
(let c = { }; b = 2; in { a = 1; inherit b ; d = (c).d; e = (c).e; f = 3; })
(let b = 2; c = { }; in { a = 1; inherit b ; d = (c).d; e = (c).e; f = 3; })