From 5bac2eea90892e7ae3a3a2306789627037d03a16 Mon Sep 17 00:00:00 2001 From: omdxp Date: Sun, 8 Sep 2024 22:53:33 +0100 Subject: [PATCH] impl macro strings --- compiler.h | 6 ++++++ lexer.c | 18 +++++++++++++++++- preprocessor/preprocessor.c | 38 ++++++++++++++++++++++++++++++++++++- test.c | 12 +++++++----- 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/compiler.h b/compiler.h index ea9542d..d3a0c82 100644 --- a/compiler.h +++ b/compiler.h @@ -106,6 +106,9 @@ struct token { // (5+10+20) const char *between_brackets; + + // TEST(test hello, 50) + const char *between_args; }; struct lex_process; @@ -128,6 +131,9 @@ struct lex_process { */ int current_expression_count; struct buffer *parenthesis_buffer; + + // TEST(hello test, 50) + struct buffer *arg_string_buffer; struct lex_process_functions *function; // This will be private data that the lexer does not understand diff --git a/lexer.c b/lexer.c index ea82285..857ff61 100644 --- a/lexer.c +++ b/lexer.c @@ -26,6 +26,9 @@ static char nextc() { // write paranethesis to an expression buffer (.e.g (20 + 10)) if (lex_is_in_expression()) { buffer_write(lex_process->parenthesis_buffer, c); + if (lex_process->arg_string_buffer) { + buffer_write(lex_process->arg_string_buffer, c); + } } lex_process->pos.col += 1; @@ -51,7 +54,11 @@ struct token *token_create(struct token *_token) { memcpy(&tmp_token, _token, sizeof(struct token)); tmp_token.pos = lex_file_position(); if (lex_is_in_expression()) { + assert(lex_process->parenthesis_buffer); tmp_token.between_brackets = buffer_ptr(lex_process->parenthesis_buffer); + if (lex_process->arg_string_buffer) { + tmp_token.between_args = buffer_ptr(lex_process->arg_string_buffer); + } } return &tmp_token; } @@ -228,6 +235,12 @@ static void lex_new_expression() { if (lex_process->current_expression_count == 1) { lex_process->parenthesis_buffer = buffer_create(); } + + struct token *last_token = lexer_last_token(); + if (last_token && (last_token->type == TOKEN_TYPE_IDENTIFIER || + token_is_operator(last_token, ","))) { + lex_process->arg_string_buffer = buffer_create(); + } } static void lex_finish_expression() { @@ -330,11 +343,13 @@ struct token *handle_comment() { } static struct token *token_make_symbol() { - char c = nextc(); + char c = peekc(); if (c == ')') { lex_finish_expression(); } + nextc(); + struct token *token = token_create(&(struct token){.type = TOKEN_TYPE_SYMBOL, .cval = c}); return token; @@ -536,6 +551,7 @@ struct token *read_next_token() { int lex(struct lex_process *process) { process->current_expression_count = 0; process->parenthesis_buffer = NULL; + process->arg_string_buffer = NULL; lex_process = process; process->pos.filename = process->compiler->cfile.abs_path; diff --git a/preprocessor/preprocessor.c b/preprocessor/preprocessor.c index 554ec19..ddcfe9f 100644 --- a/preprocessor/preprocessor.c +++ b/preprocessor/preprocessor.c @@ -1231,6 +1231,36 @@ void preprocessor_macro_function_push_something( } } +void preprocessor_handle_function_arg_to_string( + struct compile_process *compiler, struct vector *src_vec, + struct vector *value_vec_target, struct preprocessor_definition *def, + struct preprocessor_function_args *args) { + struct token *next_token = vector_peek(src_vec); + if (!next_token || next_token->type != TOKEN_TYPE_IDENTIFIER) { + compiler_error(compiler, "expected identifier"); + } + + int arg_index = + preprocessor_definition_argument_exists(def, next_token->sval); + if (arg_index < 0) { + compiler_error(compiler, "argument not found"); + } + + struct preprocessor_function_arg *arg = + preprocessor_function_argument_at(args, arg_index); + if (!arg) { + compiler_error(compiler, "argument not found"); + } + + struct token *first_token_for_argument = vector_peek_at(arg->tokens, 0); + + // create string token + struct token str_token; + str_token.type = TOKEN_TYPE_STRING; + str_token.sval = first_token_for_argument->between_brackets; + vector_push(value_vec_target, &str_token); +} + int preprocessor_macro_function_execute(struct compile_process *compiler, const char *func_name, struct preprocessor_function_args *args, @@ -1259,7 +1289,13 @@ int preprocessor_macro_function_execute(struct compile_process *compiler, vector_set_peek_pointer(def_token_vec, 0); struct token *token = vector_peek(def_token_vec); while (token) { -#warning "impl strings" + if (token_is_symbol(token, '#')) { + preprocessor_handle_function_arg_to_string(compiler, def_token_vec, + value_vec_target, def, args); + token = vector_peek(def_token_vec); + continue; + } + preprocessor_macro_function_push_something(compiler, def, args, token, def_token_vec, value_vec_target); token = vector_peek(def_token_vec); diff --git a/test.c b/test.c index 3820f2a..a6432df 100644 --- a/test.c +++ b/test.c @@ -1,6 +1,8 @@ -typedef struct ab { - int a; - int b; -} ab; +#define TEST_FUNC(s) #s -ab a; +int printf(const char *format, ...); + +int main() { + const char *s = TEST_FUNC(Hello World !); + printf("%s\n", s); +}