#pragma once #include #include #include #include #include "locator.h" using argtype_t = std::variant>; using modify_string_f = std::function)>; class Argtype { public: Argtype() : m_name("default") , m_desc("default argument type") , m_symbolic_pattern(R"((?:.|\n)*)") , m_pattern(R"((?:.|\n)*)") , m_python_cast("str") , m_python_format() , m_regex(std::regex(R"((?:.|\n)*)")) , m_loc() {}; Argtype(std::string name, std::string desc, std::string symbolic_pattern, std::string pattern, std::string default_value, std::string alone_value, std::string python_cast, modify_string_f python_format, const Locator& loc); std::string python_value(const std::string& var_name, std::vector value, size_t name_size); // True for the match-everything pattern shared by the string family // (string, rest, literal, and the default type). Validating against // it is pointless, and running std::regex over a large value (e.g. // @document's :text holding a whole document) overflows the regex // executor's recursion stack. bool matches_all() const { return m_pattern == R"((?:.|\n)*)"; }; std::string m_name {}; std::string m_desc {}; std::string m_symbolic_pattern {}; std::string m_pattern {}; // Default value for parameters of this type; a default given in a // klammer's parameter declaration overrides it (see // parse_optional_parameter). Useful for single-purpose types // (cell_hpos, column_width); general types (bool, float) have no // sensible universal default and leave it empty. std::string m_default {}; // Value for an optional argument whose name is written alone, with no // value after it (:number rather than :number 10). Declared by the // argument type, never by a klammer's parameter declaration: the // default is what a klammer means by silence and is properly // per-klammer, but a bare option name must read the same way in every // klammer or the writer cannot know what it means without consulting // each signature. bool declares "true", which is where the // presence-means-true convention comes from; a type whose pattern // matches everything cannot declare it (the value would swallow the // following text instead). Empty means the type has no alone value, // and a bare option name yields the empty string as before. std::string m_alone {}; // Type parameter for parameterized types like rest(2): the value N // is bound around the python cast as (lambda N: )(2)(...). // Empty means unparameterized; a type with a default parameter // (rest -> "1") is specialized by writing type(N) in a declaration. std::string m_parameter {}; std::string m_python_cast {}; modify_string_f m_python_format {}; std::regex m_regex {}; int m_count {1}; int m_mincount {1}; int m_maxcount {1}; Locator m_loc; }; std::string pyformat_string(const std::vector& value); std::string pyformat_bool(const std::vector& value); std::string pyformat_number(const std::vector& value); std::string pyformat_list(const std::vector& value); std::string pyformat_dlist(const std::vector& value);