// SPDX-License-Identifier: MIT #include "asm/macro.hpp" #include #include #include #include #include #include "asm/warning.hpp" std::shared_ptr MacroArgs::getArg(int32_t i) const { // Bracketed macro arguments adjust negative indexes such that -1 is the last argument. if (i < 0) { i += args.size() + 1; } int32_t realIndex = i + shift - 1; return realIndex < 0 || static_cast(realIndex) >= args.size() ? nullptr : args[realIndex]; } std::shared_ptr MacroArgs::getAllArgs() const { size_t nbArgs = args.size(); if (shift >= nbArgs) { return std::make_shared(""); } size_t len = 0; for (uint32_t i = shift; i < nbArgs; ++i) { len += args[i]->length() + 1; // 1 for comma } auto str = std::make_shared(); str->reserve(len + 1); // 1 for comma for (uint32_t i = shift; i < nbArgs; ++i) { std::shared_ptr const &arg = args[i]; str->append(*arg); // Commas go between args and after a last empty arg if (i < nbArgs - 1 || arg->empty()) { str->push_back(','); // no space after comma } } return str; } void MacroArgs::appendArg(std::shared_ptr arg) { if (arg->empty()) { warning(WARNING_EMPTY_MACRO_ARG, "Empty macro argument"); } args.push_back(arg); } void MacroArgs::shiftArgs(int32_t count) { if (size_t nbArgs = args.size(); count > 0 && (static_cast(count) > nbArgs || shift > nbArgs - count)) { warning(WARNING_MACRO_SHIFT, "Cannot shift macro arguments past their end"); shift = nbArgs; } else if (count < 0 && shift < static_cast(-count)) { warning(WARNING_MACRO_SHIFT, "Cannot shift macro arguments past their beginning"); shift = 0; } else { shift += count; } }