diff --git a/codon/sir/attribute.cpp b/codon/sir/attribute.cpp index b27541e5..cec29267 100644 --- a/codon/sir/attribute.cpp +++ b/codon/sir/attribute.cpp @@ -1,5 +1,8 @@ -#include "value.h" +#include "attribute.h" +#include "codon/sir/func.h" +#include "codon/sir/util/cloning.h" +#include "codon/sir/value.h" #include "codon/util/fmt/ostream.h" namespace codon { @@ -36,5 +39,111 @@ std::ostream &MemberAttribute::doFormat(std::ostream &os) const { const std::string SrcInfoAttribute::AttributeName = "srcInfoAttribute"; +const std::string ListLiteralAttribute::AttributeName = "listLiteralAttribute"; + +std::unique_ptr ListLiteralAttribute::clone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto *val : elements) + elementsCloned.push_back(cv.clone(val)); + return std::make_unique(elementsCloned); +} + +std::unique_ptr +ListLiteralAttribute::forceClone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto *val : elements) + elementsCloned.push_back(cv.forceClone(val)); + return std::make_unique(elementsCloned); +} + +std::ostream &ListLiteralAttribute::doFormat(std::ostream &os) const { + std::vector strings; + for (auto *val : elements) + strings.push_back(fmt::format(FMT_STRING("{}"), *val)); + fmt::print(os, FMT_STRING("[{}]"), fmt::join(strings.begin(), strings.end(), ",")); + return os; +} + +const std::string SetLiteralAttribute::AttributeName = "setLiteralAttribute"; + +std::unique_ptr SetLiteralAttribute::clone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto *val : elements) + elementsCloned.push_back(cv.clone(val)); + return std::make_unique(elementsCloned); +} + +std::unique_ptr +SetLiteralAttribute::forceClone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto *val : elements) + elementsCloned.push_back(cv.forceClone(val)); + return std::make_unique(elementsCloned); +} + +std::ostream &SetLiteralAttribute::doFormat(std::ostream &os) const { + std::vector strings; + for (auto *val : elements) + strings.push_back(fmt::format(FMT_STRING("{}"), *val)); + fmt::print(os, FMT_STRING("set([{}])"), + fmt::join(strings.begin(), strings.end(), ",")); + return os; +} + +const std::string DictLiteralAttribute::AttributeName = "dictLiteralAttribute"; + +std::unique_ptr DictLiteralAttribute::clone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto &val : elements) + elementsCloned.push_back({cv.clone(val.key), cv.clone(val.value)}); + return std::make_unique(elementsCloned); +} + +std::unique_ptr +DictLiteralAttribute::forceClone(util::CloneVisitor &cv) const { + std::vector elementsCloned; + for (auto &val : elements) + elementsCloned.push_back({cv.forceClone(val.key), cv.forceClone(val.value)}); + return std::make_unique(elementsCloned); +} + +std::ostream &DictLiteralAttribute::doFormat(std::ostream &os) const { + std::vector strings; + for (auto &val : elements) + strings.push_back(fmt::format(FMT_STRING("{}:{}"), *val.key, *val.value)); + fmt::print(os, FMT_STRING("dict([{}])"), + fmt::join(strings.begin(), strings.end(), ",")); + return os; +} + +const std::string PartialFunctionAttribute::AttributeName = "partialFunctionAttribute"; + +std::unique_ptr +PartialFunctionAttribute::clone(util::CloneVisitor &cv) const { + std::vector argsCloned; + for (auto *val : args) + argsCloned.push_back(cv.clone(val)); + return std::make_unique(cast(cv.clone(func)), + argsCloned); +} + +std::unique_ptr +PartialFunctionAttribute::forceClone(util::CloneVisitor &cv) const { + std::vector argsCloned; + for (auto *val : args) + argsCloned.push_back(cv.forceClone(val)); + return std::make_unique(cast(cv.forceClone(func)), + argsCloned); +} + +std::ostream &PartialFunctionAttribute::doFormat(std::ostream &os) const { + std::vector strings; + for (auto *val : args) + strings.push_back(val ? fmt::format(FMT_STRING("{}"), *val) : "..."); + fmt::print(os, FMT_STRING("{}({})"), func->getName(), + fmt::join(strings.begin(), strings.end(), ",")); + return os; +} + } // namespace ir } // namespace codon diff --git a/codon/sir/attribute.h b/codon/sir/attribute.h index 48beb5b7..9c4c0429 100644 --- a/codon/sir/attribute.h +++ b/codon/sir/attribute.h @@ -14,6 +14,13 @@ namespace codon { namespace ir { +class Func; +class Value; + +namespace util { +class CloneVisitor; +} + /// Base for SIR attributes. struct Attribute { virtual ~Attribute() noexcept = default; @@ -26,14 +33,15 @@ struct Attribute { } /// @return a clone of the attribute - std::unique_ptr clone() const { - return std::unique_ptr(doClone()); + virtual std::unique_ptr clone(util::CloneVisitor &cv) const = 0; + + /// @return a clone of the attribute + virtual std::unique_ptr forceClone(util::CloneVisitor &cv) const { + return clone(cv); } private: virtual std::ostream &doFormat(std::ostream &os) const = 0; - - virtual Attribute *doClone() const = 0; }; /// Attribute containing SrcInfo @@ -48,10 +56,12 @@ struct SrcInfoAttribute : public Attribute { /// @param info the source info explicit SrcInfoAttribute(codon::SrcInfo info) : info(std::move(info)) {} + std::unique_ptr clone(util::CloneVisitor &cv) const override { + return std::make_unique(*this); + } + private: std::ostream &doFormat(std::ostream &os) const override { return os << info; } - - Attribute *doClone() const override { return new SrcInfoAttribute(*this); } }; /// Attribute containing function information @@ -76,10 +86,12 @@ struct KeyValueAttribute : public Attribute { /// string if none std::string get(const std::string &key) const; + std::unique_ptr clone(util::CloneVisitor &cv) const override { + return std::make_unique(*this); + } + private: std::ostream &doFormat(std::ostream &os) const override; - - Attribute *doClone() const override { return new KeyValueAttribute(*this); } }; /// Attribute containing type member information @@ -95,10 +107,89 @@ struct MemberAttribute : public Attribute { explicit MemberAttribute(std::map memberSrcInfo) : memberSrcInfo(std::move(memberSrcInfo)) {} + std::unique_ptr clone(util::CloneVisitor &cv) const override { + return std::make_unique(*this); + } + private: std::ostream &doFormat(std::ostream &os) const override; +}; - Attribute *doClone() const override { return new MemberAttribute(*this); } +/// Attribute attached to IR structures corresponding to list literals +struct ListLiteralAttribute : public Attribute { + static const std::string AttributeName; + + /// values contained in list literal + std::vector elements; + + explicit ListLiteralAttribute(std::vector elements) + : elements(std::move(elements)) {} + + std::unique_ptr clone(util::CloneVisitor &cv) const override; + std::unique_ptr forceClone(util::CloneVisitor &cv) const override; + +private: + std::ostream &doFormat(std::ostream &os) const override; +}; + +/// Attribute attached to IR structures corresponding to set literals +struct SetLiteralAttribute : public Attribute { + static const std::string AttributeName; + + /// values contained in set literal + std::vector elements; + + explicit SetLiteralAttribute(std::vector elements) + : elements(std::move(elements)) {} + + std::unique_ptr clone(util::CloneVisitor &cv) const override; + std::unique_ptr forceClone(util::CloneVisitor &cv) const override; + +private: + std::ostream &doFormat(std::ostream &os) const override; +}; + +/// Attribute attached to IR structures corresponding to dict literals +struct DictLiteralAttribute : public Attribute { + struct KeyValuePair { + Value *key; + Value *value; + }; + + static const std::string AttributeName; + + /// keys and values contained in dict literal + std::vector elements; + + explicit DictLiteralAttribute(std::vector elements) + : elements(std::move(elements)) {} + + std::unique_ptr clone(util::CloneVisitor &cv) const override; + std::unique_ptr forceClone(util::CloneVisitor &cv) const override; + +private: + std::ostream &doFormat(std::ostream &os) const override; +}; + +/// Attribute attached to IR structures corresponding to partial functions +struct PartialFunctionAttribute : public Attribute { + static const std::string AttributeName; + + /// function being called + Func *func; + + /// partial arguments, or null if none + /// e.g. "f(a, ..., b)" has elements [a, null, b] + std::vector args; + + PartialFunctionAttribute(Func *func, std::vector args) + : func(func), args(std::move(args)) {} + + std::unique_ptr clone(util::CloneVisitor &cv) const override; + std::unique_ptr forceClone(util::CloneVisitor &cv) const override; + +private: + std::ostream &doFormat(std::ostream &os) const override; }; } // namespace ir diff --git a/codon/sir/util/cloning.h b/codon/sir/util/cloning.h index c62ce17f..e3aaf01f 100644 --- a/codon/sir/util/cloning.h +++ b/codon/sir/util/cloning.h @@ -82,7 +82,7 @@ public: for (auto it = other->attributes_begin(); it != other->attributes_end(); ++it) { const auto *attr = other->getAttribute(*it); if (attr->needsClone()) { - ctx[id]->setAttribute(attr->clone(), *it); + ctx[id]->setAttribute(attr->clone(*this), *it); } } } @@ -125,7 +125,7 @@ public: for (auto it = other->attributes_begin(); it != other->attributes_end(); ++it) { const auto *attr = other->getAttribute(*it); if (attr->needsClone()) { - ctx[id]->setAttribute(attr->clone(), *it); + ctx[id]->setAttribute(attr->forceClone(*this), *it); } } }