| 136 | } |
| 137 | |
| 138 | ScalarType getScalarType(const YAML::Node& node) |
| 139 | { |
| 140 | const auto& tag = node.Tag(); |
| 141 | const auto& value = node.Scalar(); |
| 142 | if (tag == "!") |
| 143 | return ScalarType::String; |
| 144 | |
| 145 | // Note that YAML allows to explicitely specify a scalar type via tag (e.g. "!!bool"), but it makes no |
| 146 | // sense in Lua: |
| 147 | // 1. Both integers and floats use the "number" type prior to Lua 5.3 |
| 148 | // 2. Strings can be quoted, which is more readable than "!!str" |
| 149 | // 3. Most of possible conversions are invalid or their result is unclear |
| 150 | // So ignore this feature for now. |
| 151 | if (tag != "?") |
| 152 | nodeError(node, "An invalid tag '" + tag + "' encountered"); |
| 153 | |
| 154 | if (value.empty()) |
| 155 | return ScalarType::Null; |
| 156 | |
| 157 | // Resolve type according to YAML 1.2 Core Schema (see https://yaml.org/spec/1.2.2/#103-core-schema) |
| 158 | static const std::regex boolRegex("true|True|TRUE|false|False|FALSE", std::regex_constants::extended); |
| 159 | if (std::regex_match(node.Scalar(), boolRegex)) |
| 160 | return ScalarType::Boolean; |
| 161 | |
| 162 | static const std::regex decimalRegex("[-+]?[0-9]+", std::regex_constants::extended); |
| 163 | if (std::regex_match(node.Scalar(), decimalRegex)) |
| 164 | return ScalarType::Decimal; |
| 165 | |
| 166 | static const std::regex floatRegex( |
| 167 | "[-+]?([.][0-9]+|[0-9]+([.][0-9]*)?)([eE][-+]?[0-9]+)?", std::regex_constants::extended); |
| 168 | if (std::regex_match(node.Scalar(), floatRegex)) |
| 169 | return ScalarType::Float; |
| 170 | |
| 171 | static const std::regex octalRegex("0o[0-7]+", std::regex_constants::extended); |
| 172 | if (std::regex_match(node.Scalar(), octalRegex)) |
| 173 | return ScalarType::Octal; |
| 174 | |
| 175 | static const std::regex hexdecimalRegex("0x[0-9a-fA-F]+", std::regex_constants::extended); |
| 176 | if (std::regex_match(node.Scalar(), hexdecimalRegex)) |
| 177 | return ScalarType::Hexadecimal; |
| 178 | |
| 179 | static const std::regex infinityRegex("[-+]?([.]inf|[.]Inf|[.]INF)", std::regex_constants::extended); |
| 180 | if (std::regex_match(node.Scalar(), infinityRegex)) |
| 181 | return ScalarType::Infinity; |
| 182 | |
| 183 | static const std::regex nanRegex("[.]nan|[.]NaN|[.]NAN", std::regex_constants::extended); |
| 184 | if (std::regex_match(node.Scalar(), nanRegex)) |
| 185 | return ScalarType::NotNumber; |
| 186 | |
| 187 | static const std::regex nullRegex("null|Null|NULL|~", std::regex_constants::extended); |
| 188 | if (std::regex_match(node.Scalar(), nullRegex)) |
| 189 | return ScalarType::Null; |
| 190 | |
| 191 | return ScalarType::String; |
| 192 | } |
| 193 | |
| 194 | sol::object getScalar(const YAML::Node& node, const sol::state_view& lua) |
| 195 | { |