Try to match a two-character token at position i. Returns true and advances i if matched. */
| 222 | |
| 223 | /* Try to match a two-character token at position i. Returns true and advances i if matched. */ |
| 224 | static bool lex_try_two_char(const char *input, int len, int *i, cbm_lex_result_t *out) { |
| 225 | static const struct { |
| 226 | char c1, c2; |
| 227 | cbm_token_type_t type; |
| 228 | const char *text; |
| 229 | } pairs[] = { |
| 230 | {'!', '=', TOK_NEQ, "!="}, {'<', '>', TOK_NEQ, "<>"}, {'=', '~', TOK_EQTILDE, "=~"}, |
| 231 | {'>', '=', TOK_GTE, ">="}, {'<', '=', TOK_LTE, "<="}, {'.', '.', TOK_DOTDOT, ".."}, |
| 232 | }; |
| 233 | char c = input[*i]; |
| 234 | if (*i + SKIP_ONE >= len) { |
| 235 | return false; |
| 236 | } |
| 237 | char c2 = input[*i + SKIP_ONE]; |
| 238 | for (int p = 0; p < (int)(sizeof(pairs) / sizeof(pairs[0])); p++) { |
| 239 | if (c == pairs[p].c1 && c2 == pairs[p].c2) { |
| 240 | lex_push(out, pairs[p].type, pairs[p].text, *i); |
| 241 | *i += PAIR_LEN; |
| 242 | return true; |
| 243 | } |
| 244 | } |
| 245 | return false; |
| 246 | } |
| 247 | |
| 248 | /* Try to match a single-character token. Returns TOK_EOF if not matched. */ |
| 249 | static cbm_token_type_t lex_single_char(char c) { |