summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Richard <johnny@johnnyrichard.com>2023-04-16 03:29:02 +0200
committerJohnny Richard <johnny@johnnyrichard.com>2023-04-16 03:29:02 +0200
commitd951985665bf3e0248286a30c67c28f505eb27c9 (patch)
treed8c77d73366d8a3eeb94f11163edc23201fff5c0
parentd55938b34d6b7ee2c2d7da8483aaed5c8b9078a0 (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.c24
-rw-r--r--src/lexer.h3
-rw-r--r--src/parser.c14
-rw-r--r--src/parser.h3
-rw-r--r--src/pipac.c5
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));
}
}