|
14 | 14 |
|
15 | 15 | #include "parser/macro.h"
|
16 | 16 |
|
| 17 | +#include <cstddef> |
17 | 18 | #include <cstdint>
|
| 19 | +#include <memory> |
18 | 20 | #include <utility>
|
| 21 | +#include <vector> |
19 | 22 |
|
20 | 23 | #include "absl/status/status.h"
|
| 24 | +#include "absl/status/statusor.h" |
21 | 25 | #include "absl/strings/str_cat.h"
|
22 | 26 | #include "absl/strings/str_format.h"
|
| 27 | +#include "absl/strings/string_view.h" |
23 | 28 | #include "common/operators.h"
|
24 | 29 | #include "internal/lexis.h"
|
25 | 30 | #include "parser/source_factory.h"
|
@@ -169,4 +174,77 @@ std::vector<Macro> Macro::AllMacros() {
|
169 | 174 | };
|
170 | 175 | }
|
171 | 176 |
|
| 177 | +Macro Macro::OptMap() { |
| 178 | + return Macro( |
| 179 | + "optMap", 2, |
| 180 | + [](const std::shared_ptr<SourceFactory>& sf, int64_t macro_id, |
| 181 | + const Expr& target, const std::vector<Expr>& args) -> Expr { |
| 182 | + if (args.size() != 2) { |
| 183 | + return sf->ReportError(args[0].id(), "optMap() requires 2 arguments"); |
| 184 | + } |
| 185 | + if (!args[0].has_ident_expr()) { |
| 186 | + return sf->ReportError( |
| 187 | + args[0].id(), |
| 188 | + "optMap() variable name must be a simple identifier"); |
| 189 | + } |
| 190 | + const auto& var_name = args[0].ident_expr().name(); |
| 191 | + const auto& map_expr = args[1]; |
| 192 | + |
| 193 | + std::vector<Expr> call_args; |
| 194 | + call_args.resize(3); |
| 195 | + call_args[0] = |
| 196 | + sf->NewReceiverCallForMacro(macro_id, "hasValue", target, {}); |
| 197 | + auto iter_range = sf->NewListForMacro(macro_id, {}); |
| 198 | + auto accu_init = |
| 199 | + sf->NewReceiverCallForMacro(macro_id, "value", target, {}); |
| 200 | + auto condition = sf->NewLiteralBoolForMacro(macro_id, false); |
| 201 | + auto step = sf->NewIdentForMacro(macro_id, var_name); |
| 202 | + const auto& result = map_expr; |
| 203 | + auto fold = sf->FoldForMacro(macro_id, "#unused", iter_range, var_name, |
| 204 | + accu_init, condition, step, result); |
| 205 | + call_args[1] = |
| 206 | + sf->NewGlobalCallForMacro(macro_id, "optional.of", {fold}); |
| 207 | + call_args[2] = sf->NewGlobalCallForMacro(macro_id, "optional.none", {}); |
| 208 | + return sf->NewGlobalCallForMacro(macro_id, CelOperator::CONDITIONAL, |
| 209 | + call_args); |
| 210 | + }, |
| 211 | + true); |
| 212 | +} |
| 213 | + |
| 214 | +Macro Macro::OptFlatMap() { |
| 215 | + return Macro( |
| 216 | + "optFlatMap", 2, |
| 217 | + [](const std::shared_ptr<SourceFactory>& sf, int64_t macro_id, |
| 218 | + const Expr& target, const std::vector<Expr>& args) -> Expr { |
| 219 | + if (args.size() != 2) { |
| 220 | + return sf->ReportError(args[0].id(), |
| 221 | + "optFlatMap() requires 2 arguments"); |
| 222 | + } |
| 223 | + if (!args[0].has_ident_expr()) { |
| 224 | + return sf->ReportError( |
| 225 | + args[0].id(), |
| 226 | + "optFlatMap() variable name must be a simple identifier"); |
| 227 | + } |
| 228 | + const auto& var_name = args[0].ident_expr().name(); |
| 229 | + const auto& map_expr = args[1]; |
| 230 | + std::vector<Expr> call_args; |
| 231 | + call_args.resize(3); |
| 232 | + call_args[0] = |
| 233 | + sf->NewReceiverCallForMacro(macro_id, "hasValue", target, {}); |
| 234 | + auto iter_range = sf->NewListForMacro(macro_id, {}); |
| 235 | + auto accu_init = |
| 236 | + sf->NewReceiverCallForMacro(macro_id, "value", target, {}); |
| 237 | + auto condition = sf->NewLiteralBoolForMacro(macro_id, false); |
| 238 | + auto step = sf->NewIdentForMacro(macro_id, var_name); |
| 239 | + const auto& result = map_expr; |
| 240 | + call_args[1] = |
| 241 | + sf->FoldForMacro(macro_id, "#unused", iter_range, var_name, |
| 242 | + accu_init, condition, step, result); |
| 243 | + call_args[2] = sf->NewGlobalCallForMacro(macro_id, "optional.none", {}); |
| 244 | + return sf->NewGlobalCallForMacro(macro_id, CelOperator::CONDITIONAL, |
| 245 | + call_args); |
| 246 | + }, |
| 247 | + true); |
| 248 | +} |
| 249 | + |
172 | 250 | } // namespace cel
|
0 commit comments