#pragma once #include #include #include "argument_set.h" #include "deftype.h" #include "locator.h" #include "util.h" // An Option_set is the construct declared by the "o" target: // // @@name.o :opt.argtype default ... : @@ // // a named group of OPTIONAL parameters declared once and used by several // klammers, so that a writer learns one vocabulary (:hpos, :offset, the // caption parameters) instead of a spelling per klammer. The "o" target is // symmetric with "k": "k" declares a klammer's interface and documents it, // "o" declares an option interface and documents it. Informally a klammer // mix-in -- the term is from Flavors, where a mixin contributes slots // without necessarily contributing methods, which is the shape here: a set // contributes a DECLARATION, and the obligation to honor it stays with the // klammer that uses it. // // A set is used in the parameter list of a ".k" declaration and nowhere // else: // // @@code.k :filename @caption_args :caption_side top @ | text.literal : // // Names and types come from the set and cannot be changed at the use site; a // DEFAULT may be overridden there, because what varies between klammers is // only what silence means for that one klammer -- and kdesc shows a klammer's // effective defaults anyway. Everything a reader relies on is the same // wherever the set is used, which is the whole point of having one. // // The set keeps the katoms of each member as declared, because those are what // is spliced into the using declaration's parameter list. The parsed // Parameter_set beside them validates a use-site override at definition time // and describes the set for kdesc. class Option_set { public: Option_set() = default; Option_set(const std::string& name, const std::string& desc, const Parameter_set& parameters, const katom_lists& members, const Locator& loc); // The member parameter named `name`, or nullptr if the set has none. const Parameter* find(const std::string& name) const; // ":a :b :c" -- the members, for a diagnostic that has to show them. std::string member_names() const; std::string describe(int margin = 2) const; std::string m_name {}; std::string m_desc {}; Parameter_set m_parameters {}; // One katom list per member, in declared order, each beginning with the // member's option-name katom. katom_lists m_members {}; Locator m_loc {}; // How this set was declared, for the redefinition policy: the same // transition table that governs klammer redefinition governs sets. defmode_t m_defmode { defmode_t::def_create }; // The klammers whose ".k" declaration uses this set, in declaration // order. A set's users are as interesting as its members: they are the // klammers that promise to honor the vocabulary. std::vector m_users {}; };