| 154 | } // namespace |
| 155 | |
| 156 | std::string Expression::ToString() const { |
| 157 | if (auto lit = literal()) { |
| 158 | return PrintDatum(*lit); |
| 159 | } |
| 160 | |
| 161 | if (auto ref = field_ref()) { |
| 162 | if (auto name = ref->name()) { |
| 163 | return *name; |
| 164 | } |
| 165 | if (auto path = ref->field_path()) { |
| 166 | return path->ToString(); |
| 167 | } |
| 168 | return ref->ToString(); |
| 169 | } |
| 170 | |
| 171 | auto call = CallNotNull(*this); |
| 172 | auto binary = [&](std::string op) { |
| 173 | return "(" + call->arguments[0].ToString() + " " + op + " " + |
| 174 | call->arguments[1].ToString() + ")"; |
| 175 | }; |
| 176 | |
| 177 | if (auto cmp = Comparison::Get(call->function_name)) { |
| 178 | return binary(Comparison::GetOp(*cmp)); |
| 179 | } |
| 180 | |
| 181 | constexpr std::string_view kleene = "_kleene"; |
| 182 | if (call->function_name.ends_with(kleene)) { |
| 183 | auto op = call->function_name.substr(0, call->function_name.size() - kleene.size()); |
| 184 | return binary(std::move(op)); |
| 185 | } |
| 186 | |
| 187 | if (auto options = GetMakeStructOptions(*call)) { |
| 188 | std::string out = "{"; |
| 189 | auto argument = call->arguments.begin(); |
| 190 | for (const auto& field_name : options->field_names) { |
| 191 | out += field_name + "=" + argument++->ToString() + ", "; |
| 192 | } |
| 193 | out.resize(out.size() - 1); |
| 194 | out.back() = '}'; |
| 195 | return out; |
| 196 | } |
| 197 | |
| 198 | std::string out = call->function_name + "("; |
| 199 | for (const auto& arg : call->arguments) { |
| 200 | out += arg.ToString() + ", "; |
| 201 | } |
| 202 | |
| 203 | if (call->options) { |
| 204 | out += call->options->ToString(); |
| 205 | } else if (call->arguments.size()) { |
| 206 | out.resize(out.size() - 2); |
| 207 | } |
| 208 | |
| 209 | out += ')'; |
| 210 | return out; |
| 211 | } |
| 212 | |
| 213 | void PrintTo(const Expression& expr, std::ostream* os) { |