MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

optimize io.c lexer

+152 -205
+152 -205
src/modules/io.c
··· 70 70 return; 71 71 } 72 72 73 + enum char_class { 74 + CC_OTHER, CC_NUL, CC_QUOTE, CC_ESCAPE, CC_LBRACE, CC_RBRACE, 75 + CC_LBRACK, CC_RBRACK, CC_COLON, CC_COMMA, CC_NEWLINE, 76 + CC_DIGIT, CC_MINUS, CC_ALPHA, CC_IDENT, CC_LT 77 + }; 78 + 79 + static const uint8_t char_class_table[256] = { 80 + [0] = CC_NUL, 81 + ['\n'] = CC_NEWLINE, ['"'] = CC_QUOTE, ['\''] = CC_QUOTE, ['\\'] = CC_ESCAPE, 82 + ['{'] = CC_LBRACE, ['}'] = CC_RBRACE, ['['] = CC_LBRACK, [']'] = CC_RBRACK, 83 + [':'] = CC_COLON, [','] = CC_COMMA, ['-'] = CC_MINUS, ['<'] = CC_LT, 84 + ['_'] = CC_IDENT, ['$'] = CC_IDENT, 85 + ['0'] = CC_DIGIT, ['1'] = CC_DIGIT, ['2'] = CC_DIGIT, ['3'] = CC_DIGIT, 86 + ['4'] = CC_DIGIT, ['5'] = CC_DIGIT, ['6'] = CC_DIGIT, ['7'] = CC_DIGIT, 87 + ['8'] = CC_DIGIT, ['9'] = CC_DIGIT, 88 + ['a'] = CC_ALPHA, ['b'] = CC_ALPHA, ['c'] = CC_ALPHA, ['d'] = CC_ALPHA, 89 + ['e'] = CC_ALPHA, ['f'] = CC_ALPHA, ['g'] = CC_ALPHA, ['h'] = CC_ALPHA, 90 + ['i'] = CC_ALPHA, ['j'] = CC_ALPHA, ['k'] = CC_ALPHA, ['l'] = CC_ALPHA, 91 + ['m'] = CC_ALPHA, ['n'] = CC_ALPHA, ['o'] = CC_ALPHA, ['p'] = CC_ALPHA, 92 + ['q'] = CC_ALPHA, ['r'] = CC_ALPHA, ['s'] = CC_ALPHA, ['t'] = CC_ALPHA, 93 + ['u'] = CC_ALPHA, ['v'] = CC_ALPHA, ['w'] = CC_ALPHA, ['x'] = CC_ALPHA, 94 + ['y'] = CC_ALPHA, ['z'] = CC_ALPHA, 95 + ['A'] = CC_ALPHA, ['B'] = CC_ALPHA, ['C'] = CC_ALPHA, ['D'] = CC_ALPHA, 96 + ['E'] = CC_ALPHA, ['F'] = CC_ALPHA, ['G'] = CC_ALPHA, ['H'] = CC_ALPHA, 97 + ['I'] = CC_ALPHA, ['J'] = CC_ALPHA, ['K'] = CC_ALPHA, ['L'] = CC_ALPHA, 98 + ['M'] = CC_ALPHA, ['N'] = CC_ALPHA, ['O'] = CC_ALPHA, ['P'] = CC_ALPHA, 99 + ['Q'] = CC_ALPHA, ['R'] = CC_ALPHA, ['S'] = CC_ALPHA, ['T'] = CC_ALPHA, 100 + ['U'] = CC_ALPHA, ['V'] = CC_ALPHA, ['W'] = CC_ALPHA, ['X'] = CC_ALPHA, 101 + ['Y'] = CC_ALPHA, ['Z'] = CC_ALPHA, 102 + }; 103 + 104 + #define KEYWORD(kw, color) \ 105 + if (memcmp(p, kw, sizeof(kw) - 1) == 0 && !isalnum((unsigned char)p[sizeof(kw) - 1]) && p[sizeof(kw) - 1] != '_') { \ 106 + io_puts(color, stream); io_puts(kw, stream); io_puts(ANSI_RESET, stream); \ 107 + p += sizeof(kw) - 1; goto next; \ 108 + } 109 + 110 + #define EMIT_UNTIL(end_char, color) \ 111 + io_puts(color, stream); \ 112 + while (*p && *p != end_char) io_putc(*p++, stream); \ 113 + if (*p == end_char) io_putc(*p++, stream); \ 114 + io_puts(ANSI_RESET, stream); goto next; 115 + 73 116 void print_value_colored(const char *str, FILE *stream) { 74 - if (io_no_color) { 75 - io_print(str, stream); 76 - return; 117 + if (io_no_color) { io_print(str, stream); return; } 118 + 119 + static void *dispatch[] = { 120 + [CC_NUL] = &&done, [CC_QUOTE] = &&quote, [CC_ESCAPE] = &&other, 121 + [CC_LBRACE] = &&lbrace, [CC_RBRACE] = &&rbrace, 122 + [CC_LBRACK] = &&lbrack, [CC_RBRACK] = &&rbrack, 123 + [CC_COLON] = &&colon, [CC_COMMA] = &&separator, [CC_NEWLINE] = &&separator, 124 + [CC_DIGIT] = &&number, [CC_MINUS] = &&minus, 125 + [CC_ALPHA] = &&alpha, [CC_IDENT] = &&ident, [CC_LT] = &&lt, [CC_OTHER] = &&other 126 + }; 127 + 128 + const char *p = str; 129 + char string_char = 0; 130 + int brace_depth = 0, array_depth = 0; 131 + bool is_key = true; 132 + 133 + goto next; 134 + 135 + next: 136 + goto *dispatch[char_class_table[(unsigned char)*p]]; 137 + 138 + done: 139 + return; 140 + 141 + quote: 142 + string_char = *p; 143 + io_puts((is_key && brace_depth > 0) ? JSON_KEY : JSON_STRING, stream); 144 + io_putc(*p++, stream); 145 + while (*p) { 146 + if (*p == '\\' && p[1]) { io_putc(*p++, stream); io_putc(*p++, stream); continue; } 147 + if (*p == string_char) { io_putc(*p++, stream); break; } 148 + io_putc(*p++, stream); 149 + } 150 + io_puts(ANSI_RESET, stream); 151 + goto next; 152 + 153 + lbrace: 154 + io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 155 + brace_depth++; is_key = true; goto next; 156 + 157 + rbrace: 158 + io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 159 + brace_depth--; is_key = false; goto next; 160 + 161 + lbrack: 162 + if (memcmp(p, "[Function", 9) == 0 || memcmp(p, "[native code]", 13) == 0) { EMIT_UNTIL(']', JSON_FUNC) } 163 + if (memcmp(p, "[Circular", 9) == 0) { EMIT_UNTIL(']', JSON_REF) } 164 + io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 165 + array_depth++; is_key = false; goto next; 166 + 167 + rbrack: 168 + io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 169 + array_depth--; is_key = false; goto next; 170 + 171 + colon: 172 + io_putc(*p++, stream); is_key = false; goto next; 173 + 174 + separator: 175 + io_putc(*p++, stream); 176 + is_key = (brace_depth > 0 && array_depth == 0); 177 + goto next; 178 + 179 + number: 180 + io_puts(JSON_NUMBER, stream); 181 + while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') 182 + io_putc(*p++, stream); 183 + io_puts(ANSI_RESET, stream); 184 + goto next; 185 + 186 + minus: 187 + if (p[1] >= '0' && p[1] <= '9') { 188 + io_puts(JSON_NUMBER, stream); io_putc(*p++, stream); 189 + while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') 190 + io_putc(*p++, stream); 191 + io_puts(ANSI_RESET, stream); 192 + goto next; 193 + } 194 + io_putc(*p++, stream); goto next; 195 + 196 + lt: 197 + if (memcmp(p, "<ref", 4) == 0) { EMIT_UNTIL('>', JSON_REF) } 198 + io_putc(*p++, stream); goto next; 199 + 200 + alpha: 201 + if (memcmp(p, "Object [", 8) == 0) { 202 + io_puts(JSON_TAG, stream); io_puts("Object [", stream); 203 + p += 8; 204 + while (*p && *p != ']') io_putc(*p++, stream); 205 + io_puts(ANSI_RESET, stream); 206 + goto next; 77 207 } 208 + KEYWORD("true", JSON_BOOL) 209 + KEYWORD("false", JSON_BOOL) 210 + KEYWORD("null", JSON_NULL) 211 + KEYWORD("undefined", JSON_NULL) 212 + KEYWORD("Infinity", JSON_NUMBER) 213 + KEYWORD("NaN", JSON_NUMBER) 78 214 79 - bool in_string = false; 80 - bool escape_next = false; 81 - bool is_key = true; 82 - int brace_depth = 0; 83 - int array_depth = 0; 84 - char string_char = 0; 85 - 86 - for (const char *p = str; *p; p++) { 87 - if (escape_next) { 88 - io_putc(*p, stream); 89 - escape_next = false; 90 - continue; 91 - } 92 - 93 - if (*p == '\\' && in_string) { 94 - io_putc(*p, stream); 95 - escape_next = true; 96 - continue; 97 - } 98 - 99 - if (*p == '\'' || *p == '"') { 100 - if (!in_string) { 101 - bool use_key_color = is_key && brace_depth > 0; 102 - io_puts(use_key_color ? JSON_KEY : JSON_STRING, stream); 103 - io_putc(*p, stream); 104 - in_string = true; 105 - string_char = *p; 106 - } else if (*p == string_char) { 107 - io_putc(*p, stream); 108 - io_puts(ANSI_RESET, stream); 109 - in_string = false; 110 - string_char = 0; 111 - } else { 112 - io_putc(*p, stream); 113 - } 114 - continue; 115 - } 116 - 117 - if (in_string) { 118 - io_putc(*p, stream); 119 - continue; 120 - } 121 - 122 - if (*p == '[' && (strncmp(p, "[Function", 9) == 0 || strncmp(p, "[native code]", 13) == 0)) { 123 - io_puts(JSON_FUNC, stream); 124 - while (*p && *p != ']') io_putc(*p++, stream); 125 - if (*p == ']') io_putc(*p, stream); 126 - io_puts(ANSI_RESET, stream); 127 - continue; 128 - } 129 - 130 - if (*p == '[' && strncmp(p, "[Circular", 9) == 0) { 131 - io_puts(JSON_REF, stream); 132 - while (*p && *p != ']') io_putc(*p++, stream); 133 - if (*p == ']') io_putc(*p, stream); 134 - io_puts(ANSI_RESET, stream); 135 - continue; 136 - } 137 - 138 - if (*p == '<' && strncmp(p, "<ref", 4) == 0) { 139 - io_puts(JSON_REF, stream); 140 - while (*p && *p != '>') io_putc(*p++, stream); 141 - if (*p == '>') io_putc(*p, stream); 142 - io_puts(ANSI_RESET, stream); 143 - continue; 144 - } 145 - 146 - if (strncmp(p, "Object [", 8) == 0) { 147 - io_puts(JSON_TAG, stream); 148 - io_puts("Object [", stream); 149 - p += 7; 150 - while (*p && *p != ']') io_putc(*++p, stream); 151 - io_puts(ANSI_RESET, stream); 152 - continue; 153 - } 154 - 155 - if (*p == ':') { 156 - io_putc(*p, stream); 157 - is_key = false; 158 - continue; 159 - } 160 - 161 - if (*p == ',') { 162 - io_putc(*p, stream); 163 - is_key = (brace_depth > 0 && array_depth == 0); 164 - continue; 165 - } 166 - 167 - if (*p == '\n') { 168 - io_putc(*p, stream); 169 - is_key = (brace_depth > 0 && array_depth == 0); 170 - continue; 171 - } 172 - 173 - if (*p == '{') { 174 - io_puts(JSON_BRACE, stream); 175 - io_putc(*p, stream); 176 - io_puts(ANSI_RESET, stream); 177 - brace_depth++; 178 - is_key = true; 179 - continue; 180 - } 181 - 182 - if (*p == '}') { 183 - io_puts(JSON_BRACE, stream); 184 - io_putc(*p, stream); 185 - io_puts(ANSI_RESET, stream); 186 - brace_depth--; 187 - is_key = false; 188 - continue; 189 - } 190 - 191 - if (*p == '[') { 192 - io_puts(JSON_BRACE, stream); 193 - io_putc(*p, stream); 194 - io_puts(ANSI_RESET, stream); 195 - array_depth++; 196 - is_key = false; 197 - continue; 198 - } 199 - 200 - if (*p == ']') { 201 - io_puts(JSON_BRACE, stream); 202 - io_putc(*p, stream); 203 - io_puts(ANSI_RESET, stream); 204 - array_depth--; 205 - is_key = false; 206 - continue; 207 - } 208 - 209 - if (strncmp(p, "true", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') { 210 - io_puts(JSON_BOOL, stream); 211 - io_puts("true", stream); 212 - io_puts(ANSI_RESET, stream); 213 - p += 3; 214 - continue; 215 - } 216 - 217 - if (strncmp(p, "false", 5) == 0 && !isalnum((unsigned char)p[5]) && p[5] != '_') { 218 - io_puts(JSON_BOOL, stream); 219 - io_puts("false", stream); 220 - io_puts(ANSI_RESET, stream); 221 - p += 4; 222 - continue; 223 - } 224 - 225 - if (strncmp(p, "null", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') { 226 - io_puts(JSON_NULL, stream); 227 - io_puts("null", stream); 228 - io_puts(ANSI_RESET, stream); 229 - p += 3; 230 - continue; 231 - } 232 - 233 - if (strncmp(p, "undefined", 9) == 0 && !isalnum((unsigned char)p[9]) && p[9] != '_') { 234 - io_puts(JSON_NULL, stream); 235 - io_puts("undefined", stream); 236 - io_puts(ANSI_RESET, stream); 237 - p += 8; 238 - continue; 239 - } 240 - 241 - if (strncmp(p, "Infinity", 8) == 0 && !isalnum((unsigned char)p[8]) && p[8] != '_') { 242 - io_puts(JSON_NUMBER, stream); 243 - io_puts("Infinity", stream); 244 - io_puts(ANSI_RESET, stream); 245 - p += 7; 246 - continue; 247 - } 248 - 249 - if (strncmp(p, "NaN", 3) == 0 && !isalnum((unsigned char)p[3]) && p[3] != '_') { 250 - io_puts(JSON_NUMBER, stream); 251 - io_puts("NaN", stream); 252 - io_puts(ANSI_RESET, stream); 253 - p += 2; 254 - continue; 255 - } 256 - 257 - if ((*p >= '0' && *p <= '9') || (*p == '-' && p[1] >= '0' && p[1] <= '9')) { 258 - io_puts(JSON_NUMBER, stream); 259 - if (*p == '-') io_putc(*p++, stream); 260 - while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') { 261 - io_putc(*p, stream); 262 - if (!((p[1] >= '0' && p[1] <= '9') || p[1] == '.' || p[1] == 'e' || p[1] == 'E' || p[1] == '+' || p[1] == '-')) break; 263 - p++; 264 - } 265 - io_puts(ANSI_RESET, stream); 266 - continue; 267 - } 268 - 269 - if (is_key && brace_depth > 0 && (isalpha((unsigned char)*p) || *p == '_' || *p == '$')) { 270 - io_puts(JSON_KEY, stream); 271 - while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') { 272 - io_putc(*p, stream); 273 - if (!(isalnum((unsigned char)p[1]) || p[1] == '_' || p[1] == '$')) break; 274 - p++; 275 - } 276 - io_puts(ANSI_RESET, stream); 277 - continue; 278 - } 279 - 280 - io_putc(*p, stream); 215 + ident: 216 + if (is_key && brace_depth > 0) { 217 + io_puts(JSON_KEY, stream); 218 + while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') io_putc(*p++, stream); 219 + io_puts(ANSI_RESET, stream); 220 + goto next; 281 221 } 222 + io_putc(*p++, stream); goto next; 223 + 224 + other: 225 + io_putc(*p++, stream); goto next; 282 226 } 227 + 228 + #undef KEYWORD 229 + #undef EMIT_UNTIL 283 230 284 231 static void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream) { 285 232 if (color && !io_no_color) io_puts(color, stream);