24 std::size_t args_needed = args.
list().size();
25 std::size_t args_given = node.
constList().size() - 1;
26 std::string macro_name = macro->
constList()[0].string();
30 std::unordered_map<std::string, Node> args_applied;
32 for (std::size_t i = 1, end = node.
constList().size(); i < end; ++i)
38 const std::string& arg_name = args.
list()[j].string();
41 args_applied[arg_name] = node.
constList()[i];
46 if (args_applied.find(arg_name) == args_applied.end())
52 args_applied[arg_name].push_back(node.
constList()[i]);
57 if (args_applied.size() + 1 == args_needed && has_spread)
64 if (args_given != args_needed && !has_spread)
65 throwMacroProcessingError(
"Macro `" + macro_name +
"' got " + std::to_string(args_given) +
" argument(s) but needed " + std::to_string(args_needed), node);
66 else if (args_applied.size() != args_needed && has_spread)
68 throwMacroProcessingError(
"Macro `" + macro_name +
"' got " + std::to_string(args_applied.size()) +
" argument(s) but needed at least " + std::to_string(args_needed - 1), node);
70 if (!args_applied.empty())
71 unify(args_applied, temp_body,
nullptr);
Executor for List Macros.
bool canHandle(Node &node) override
Checks if the executor can apply a macro on the passed Node.
bool applyMacro(Node &node) override
Executes macros in the Node if the Executor can handle it.
Node evaluate(Node &node, bool is_not_body)
Evaluate only the macros.
void throwMacroProcessingError(const std::string &message, const Node &node)
Throw a macro processing error.
void unify(const std::unordered_map< std::string, Node > &, Node &, Node *)
Applies the spread operator.
bool isPredefined(const std::string &symbol)
Check if a given symbol is a predefined macro.
const Node * findNearestMacro(const std::string &name) const
Find the nearest macro matching a giving name.
bool applyMacroProxy(Node &node)
Execute a node, trying to emplace macros calls.
A node of an Abstract Syntax Tree for ArkScript.
NodeType nodeType() const noexcept
Return the node type.
static const Node & getListNode()
Provide a statically initialized / correct and guaranteed to be initialized Node representing "Empty ...
const std::string & string() const noexcept
Return the string held by the value (if the node type allows it)
const std::vector< Node > & constList() const noexcept
Return the list of sub-nodes held by the node.
std::vector< Node > & list() noexcept
Return the list of sub-nodes held by the node.