diff options
author | Johnny Richard <johnny@johnnyrichard.com> | 2023-04-16 03:29:02 +0200 |
---|---|---|
committer | Johnny Richard <johnny@johnnyrichard.com> | 2023-04-16 03:29:02 +0200 |
commit | d951985665bf3e0248286a30c67c28f505eb27c9 (patch) | |
tree | d8c77d73366d8a3eeb94f11163edc23201fff5c0 | |
parent | d55938b34d6b7ee2c2d7da8483aaed5c8b9078a0 (diff) |
Start using string_view on lexer and parser
This change fixes the memory leak when token got created.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
-rw-r--r-- | src/lexer.c | 24 | ||||
-rw-r--r-- | src/lexer.h | 3 | ||||
-rw-r--r-- | src/parser.c | 14 | ||||
-rw-r--r-- | src/parser.h | 3 | ||||
-rw-r--r-- | src/pipac.c | 5 |
5 files changed, 23 insertions, 26 deletions
diff --git a/src/lexer.c b/src/lexer.c index f58b0ea..9be96a8 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -55,8 +55,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) lexer_drop_char(lexer); } token->kind = TOKEN_NUMBER; - token->value = (char *) malloc(sizeof(char) * (lexer->cur - begin + 1)); - strncpy(token->value, lexer->src + begin, lexer->cur - begin); + token->value = string_view_new(lexer->src + begin, lexer->cur - begin); token->filepath = lexer->filepath; token->row = lexer->row; token->col = begin - lexer->bol; @@ -70,8 +69,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) lexer_drop_char(lexer); } token->kind = TOKEN_NAME; - token->value = (char *) malloc(sizeof(char) * (lexer->cur - begin + 1)); - strncpy(token->value, lexer->src + begin, lexer->cur - begin); + token->value = string_view_new(lexer->src + begin, lexer->cur - begin); token->filepath = lexer->filepath; token->row = lexer->row; token->col = begin - lexer->bol; @@ -80,8 +78,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == '(') { token->kind = TOKEN_OPAREN; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, "("); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; @@ -91,8 +88,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == ')') { token->kind = TOKEN_CPAREN; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, ")"); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; @@ -102,8 +98,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == ':') { token->kind = TOKEN_COLON; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, ":"); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; @@ -113,8 +108,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == ';') { token->kind = TOKEN_SEMICOLON; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, ";"); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; @@ -124,8 +118,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == '{') { token->kind = TOKEN_OCURLY; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, "{"); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; @@ -135,8 +128,7 @@ lexer_next_token(lexer_t *lexer, token_t *token) if (lexer_is_not_eof(lexer) && lexer_current_char(lexer) == '}') { token->kind = TOKEN_CCURLY; - token->value = (char *) malloc(sizeof(char) + 1); - strcpy(token->value, "}"); + token->value = string_view_new(lexer->src, 1); token->filepath = lexer->filepath; token->row = lexer->row; token->col = lexer->cur - lexer->bol; diff --git a/src/lexer.h b/src/lexer.h index 472ee10..a091fb7 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -20,6 +20,7 @@ #include <stdint.h> #include <stdlib.h> #include <stdbool.h> +#include "string_view.h" typedef enum { TOKEN_NAME, @@ -35,7 +36,7 @@ typedef enum { typedef struct token_t { token_kind_t kind; - char *value; + string_view_t value; char *filepath; uint32_t row; uint32_t col; diff --git a/src/parser.c b/src/parser.c index 4867201..593f75a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -65,11 +65,11 @@ parser_parse_type(parser_t *parser) { token_t token = expected_token(parser, TOKEN_NAME); - if (strcmp(token.value, "i32") == 0) { + if (string_view_eq(token.value, string_view_from_str("i32"))) { return TYPE_I32; } - fprintf(stderr, "[ERROR]: expected type 'i32' but got '%s'\n", token.value); + fprintf(stderr, "[ERROR]: expected type 'i32' but got '"SVFMT"'\n", SVARG(&token.value)); exit(EXIT_FAILURE); } @@ -79,9 +79,9 @@ parser_parse_return_stmt(parser_t *parser) expected_token(parser, TOKEN_OCURLY); token_t return_keyword_token = expected_token(parser, TOKEN_NAME); - if (strcmp(return_keyword_token.value, "return") != 0) { + if (!string_view_eq(return_keyword_token.value, string_view_from_str("return"))) { // TODO: Add filename:row:col prefix to expected token exceptions - fprintf(stderr, "[ERROR]: expected 'return' keyword but got '%s'\n", return_keyword_token.value); + fprintf(stderr, "[ERROR]: expected 'return' keyword but got '"SVFMT"'\n", SVARG(&return_keyword_token.value)); exit(EXIT_FAILURE); } @@ -89,8 +89,11 @@ parser_parse_return_stmt(parser_t *parser) expected_token(parser, TOKEN_SEMICOLON); expected_token(parser, TOKEN_CCURLY); + char number_as_str[number_token.value.size]; + string_view_to_str(&number_token.value, number_as_str); + return (ast_return_stmt_t) { - .number = atoi(number_token.value) + .number = atoi(number_as_str) }; } @@ -104,7 +107,6 @@ parser_parse_function(parser_t *parser) type_t return_type = parser_parse_type(parser); return (ast_function_t) { - // FIXME: alloc memory for the ast_function.name, it's not a good idea to use the token.value .name = func_name_token.value, .return_type = return_type, .body = parser_parse_return_stmt(parser) diff --git a/src/parser.h b/src/parser.h index e9a1cb7..d44a4df 100644 --- a/src/parser.h +++ b/src/parser.h @@ -18,6 +18,7 @@ #define PARSER_H #include "lexer.h" +#include "string_view.h" typedef struct parser_t { lexer_t *lexer; @@ -32,7 +33,7 @@ typedef struct ast_return_stmt_t { } ast_return_stmt_t; typedef struct ast_function_t { - char *name; + string_view_t name; type_t return_type; ast_return_stmt_t body; } ast_function_t; diff --git a/src/pipac.c b/src/pipac.c index 993d56d..6e6df9e 100644 --- a/src/pipac.c +++ b/src/pipac.c @@ -20,11 +20,12 @@ #include "lexer.h" #include "parser.h" +#include "string_view.h" void generate_gas_x86_64_linux(ast_function_t *func) { - if (strcmp(func->name, "main") != 0) { + if (!string_view_eq(func->name, string_view_from_str("main"))) { fprintf(stderr, "[ERROR]: no main function has been defined!\n"); exit(EXIT_FAILURE); } @@ -47,7 +48,7 @@ void print_tokens(lexer_t *lexer) { token_t token; for (lexer_next_token(lexer, &token); token.kind != TOKEN_EOF; lexer_next_token(lexer, &token)) { - printf("%s:%d:%d: [kind=%d, value='%s']\n", lexer->filepath, token.row + 1, token.col + 1, token.kind, token.value); + printf("%s:%d:%d: [kind=%d, value='"SVFMT"']\n", lexer->filepath, token.row + 1, token.col + 1, token.kind, SVARG(&token.value)); } } |