| 137 | } // namespace codecvt |
| 138 | |
| 139 | void compiler_type::process_char_buff(const std::deque<char> &raw_buff, std::deque<token_base *> &tokens, |
| 140 | charset encoding) |
| 141 | { |
| 142 | if (raw_buff.empty()) |
| 143 | throw compile_error("Received empty character buffer."); |
| 144 | std::unique_ptr<codecvt::charset> cvt = nullptr; |
| 145 | switch (encoding) { |
| 146 | case charset::ascii: |
| 147 | cvt = std::make_unique<codecvt::ascii>(); |
| 148 | break; |
| 149 | case charset::utf8: |
| 150 | cvt = std::make_unique<codecvt::utf8>(); |
| 151 | break; |
| 152 | case charset::gbk: |
| 153 | cvt = std::make_unique<codecvt::gbk>(); |
| 154 | break; |
| 155 | } |
| 156 | std::u32string buff = cvt->local2wide(raw_buff); |
| 157 | std::u32string tmp; |
| 158 | token_types type = token_types::null; |
| 159 | bool inside_char = false; |
| 160 | bool inside_str = false; |
| 161 | bool escape = false; |
| 162 | for (auto it = buff.begin(); it != buff.end();) { |
| 163 | if (inside_char) { |
| 164 | if (escape) { |
| 165 | tmp += escape_map.match(*it); |
| 166 | escape = false; |
| 167 | } |
| 168 | else if (*it == '\\') { |
| 169 | escape = true; |
| 170 | } |
| 171 | else if (*it == '\'') { |
| 172 | if (tmp.empty()) |
| 173 | throw compile_error("Do not allow empty character."); |
| 174 | if (tmp.size() > 1) |
| 175 | throw compile_error("Char must be a single character."); |
| 176 | if (tmp[0] > CHAR_MAX) |
| 177 | throw compile_error("Do not support unicode character. Please using string instead."); |
| 178 | tokens.push_back(new_value((char) tmp[0])); |
| 179 | tmp.clear(); |
| 180 | inside_char = false; |
| 181 | } |
| 182 | else { |
| 183 | tmp += *it; |
| 184 | } |
| 185 | ++it; |
| 186 | continue; |
| 187 | } |
| 188 | if (inside_str) { |
| 189 | if (escape) { |
| 190 | tmp += escape_map.match(*it); |
| 191 | escape = false; |
| 192 | } |
| 193 | else if (*it == '\\') { |
| 194 | escape = true; |
| 195 | } |
| 196 | else if (*it == '\"') { |
no test coverage detected