/* SPDX-License-Identifier: MIT */ #ifndef RGBDS_ASM_RPN_H #define RGBDS_ASM_RPN_H #include #include #include #include "linkdefs.hpp" struct Symbol; struct Expression { int32_t val = 0; // If the expression's value is known, it's here std::string reason{}; // Why the expression is not known, if it isn't bool isKnown = true; // Whether the expression's value is known at assembly time bool isSymbol = false; // Whether the expression represents a symbol suitable for const diffing std::vector rpn{}; // Bytes serializing the RPN expression uint32_t rpnPatchSize = 0; // Size the expression will take in the object file Expression() = default; Expression(Expression &&) = default; #ifdef _MSC_VER // MSVC and WinFlexBison won't build without this... Expression(Expression const &) = default; #endif Expression &operator=(Expression &&) = default; int32_t getConstVal() const; Symbol const *symbolOf() const; bool isDiffConstant(Symbol const *symName) const; void makeNumber(uint32_t value); void makeSymbol(std::string const &symName); void makeBankSymbol(std::string const &symName); void makeBankSection(std::string const §Name); void makeSizeOfSection(std::string const §Name); void makeStartOfSection(std::string const §Name); void makeSizeOfSectionType(SectionType type); void makeStartOfSectionType(SectionType type); void makeHigh(); void makeLow(); void makeNeg(); void makeNot(); void makeLogicNot(); void makeBinaryOp(RPNCommand op, Expression &&src1, Expression const &src2); void makeCheckHRAM(); void makeCheckRST(); void checkNBit(uint8_t n) const; private: void clear(); uint8_t *reserveSpace(uint32_t size); uint8_t *reserveSpace(uint32_t size, uint32_t patchSize); // Makes an expression "not known", also setting its error message template void makeUnknown(Ts... parts) { isKnown = false; reason.clear(); (reason.append(parts), ...); } }; #endif // RGBDS_ASM_RPN_H