#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 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 {}; // 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);