From 6ca377762516888b0488d60c971e0660ae6035f4 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Fri, 14 Oct 2016 22:17:01 +0200 Subject: token_list using an array for memory efficiency --- interpreter/lex.c | 92 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'interpreter/lex.c') diff --git a/interpreter/lex.c b/interpreter/lex.c index 5032bfb..497ee8e 100644 --- a/interpreter/lex.c +++ b/interpreter/lex.c @@ -34,87 +34,89 @@ unsigned char lex_name_length(char *input) { } struct token_list *lex(struct token_list *list, char *input) { - struct token_list *first_list; bool create_new_token; while (*input && is_space_char(*input)) input++; - if (*input == 0) { + if (*input == 0) return list; - } - if (list) { - first_list = list; - while (list->rest) list = list->rest; - list->rest = my_calloc(1, sizeof(struct token_list)); - list = list->rest; - } else { - first_list = list = my_calloc(1, sizeof(struct token_list)); + if (!list) { + list = my_calloc(1, + sizeof(struct token_list) + + INITIAL_TOKEN_LIST_SIZE * sizeof(struct token) + 1); + list->length = INITIAL_TOKEN_LIST_SIZE; + list->index = 0; } - create_new_token = 1; + create_new_token = true; while (*input) { - list->elem.var = NULL; + if (list->index >= list->length) { + list = my_realloc(list, + sizeof(struct token_list) + + 2 * list->length * sizeof(struct token) + 1); + list->length *= 2; + } + + list->elems[list->index].var = NULL; switch (*input) { - case ';': list->elem.kind = TOKEN_SEMICOLON; break; - case ':': list->elem.kind = TOKEN_COLON; break; - case '(': list->elem.kind = TOKEN_OPEN_P; break; - case ')': list->elem.kind = TOKEN_CLOSE_P; break; - case '[': list->elem.kind = TOKEN_OPEN_SQ; break; - case ']': list->elem.kind = TOKEN_CLOSE_SQ; break; - case '=': list->elem.kind = TOKEN_EQUALS; break; - case ',': list->elem.kind = TOKEN_COMMA; break; + case ';': list->elems[list->index].kind = TOKEN_SEMICOLON; break; + case ':': list->elems[list->index].kind = TOKEN_COLON; break; + case '(': list->elems[list->index].kind = TOKEN_OPEN_P; break; + case ')': list->elems[list->index].kind = TOKEN_CLOSE_P; break; + case '[': list->elems[list->index].kind = TOKEN_OPEN_SQ; break; + case ']': list->elems[list->index].kind = TOKEN_CLOSE_SQ; break; + case '=': list->elems[list->index].kind = TOKEN_EQUALS; break; + case ',': list->elems[list->index].kind = TOKEN_COMMA; break; default: if (input[0] == '/' && input[1] == '/') { while (input && input[0] != '\n') input++; + create_new_token = false; break; - } - if (input[0] == 'c' && input[1] == 'o' && input[2] == 'd' && - input[3] == 'e' && is_space_char(input[4])) { - list->elem.kind = TOKEN_CODE; + } else if (input[0] == 'c' && input[1] == 'o' && + input[2] == 'd' && input[3] == 'e' && + is_space_char(input[4])) { + list->elems[list->index].kind = TOKEN_CODE; input += 4; break; - } - if (input[0] == 'i' && input[1] == 'm' && input[2] == 'p' && - input[3] == 'o' && input[4] == 'r' && - input[5] == 't' && is_space_char(input[6])) { - list->elem.kind = TOKEN_IMPORT; + } else if (input[0] == 'i' && input[1] == 'm' && + input[2] == 'p' && input[3] == 'o' && + input[4] == 'r' && input[5] == 't' && + is_space_char(input[6])) { + list->elems[list->index].kind = TOKEN_IMPORT; input += 6; break; - } - if (is_int_char(*input)) { + } else if (is_int_char(*input)) { char *s; unsigned char len = lex_int_length(input); s = my_calloc(1, len + 1); - list->elem.kind = TOKEN_INT; - list->elem.var = my_calloc(1, sizeof(int)); + list->elems[list->index].kind = TOKEN_INT; + list->elems[list->index].var = my_calloc(1, sizeof(int)); strncpy(s, input, len); - *((int*) list->elem.var) = atoi(s); + *((int*) list->elems[list->index].var) = atoi(s); my_free(s); input += len - 1; } else if (is_name_char(*input)) { unsigned char len = lex_name_length(input); - list->elem.kind = TOKEN_NAME; - list->elem.var = my_calloc(1, len + 1); - strncpy(list->elem.var, input, len); + list->elems[list->index].kind = TOKEN_NAME; + list->elems[list->index].var = my_calloc(1, len + 1); + strncpy(list->elems[list->index].var, input, len); input += len - 1; } else if (is_space_char(*input)) { - create_new_token = 0; + create_new_token = false; } else { - free_token_list(first_list); - my_free(first_list); + free_token_list(list); + my_free(list); return NULL; } } do input++; while (*input && is_space_char(*input)); - if (*input && create_new_token) { - list->rest = my_calloc(1, sizeof(struct token_list)); - list = list->rest; - } + if (create_new_token) + list->index++; } - return first_list; + return list; } -- cgit v1.2.3