Skip to content

Commit

Permalink
impl preprocessing concatenation
Browse files Browse the repository at this point in the history
  • Loading branch information
omdxp committed Sep 8, 2024
1 parent 49f5e15 commit 464b451
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 3 deletions.
4 changes: 4 additions & 0 deletions compiler.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef ROSEBUDCOMPILER_H
#define ROSEBUDCOMPILER_H
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
Expand All @@ -12,6 +13,7 @@
? size + (C_STACK_ALIGNMENT - (size % C_STACK_ALIGNMENT)) \
: size
#define PATH_MAX 4096
#define FAIL_ERR(msg) assert(0 == 1 && msg)

struct pos {
int line;
Expand Down Expand Up @@ -1146,6 +1148,8 @@ bool keyword_is_datatype(const char *keyword);
bool token_is_primitive_keyword(struct token *token);
bool token_is_operator(struct token *token, const char *value);
bool is_operator_token(struct token *token);
struct vector *tokens_join_vector(struct compile_process *compiler,
struct vector *token_vec);

bool datatype_is_struct_or_union_for_name(const char *name);
bool datatype_is_struct_or_union(struct datatype *dtype);
Expand Down
70 changes: 69 additions & 1 deletion preprocessor/preprocessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ void preprocessor_token_vec_push_src_resolve_definition(
struct vector *dst_vec, struct token *token);
struct vector *
preprocessor_definition_value(struct preprocessor_definition *def);
void preprocessor_macro_function_push_something(
struct compile_process *compiler, struct preprocessor_definition *def,
struct preprocessor_function_args *args, struct token *arg_token,
struct vector *def_token_vec, struct vector *value_vec_target);

struct preprocessor_included_file *
preprocessor_add_included_file(struct preprocessor *preprocessor,
Expand Down Expand Up @@ -1218,11 +1222,75 @@ int preprocessor_macro_function_push_something_definition(
return -1;
}

bool preprocessor_is_next_double_hash(struct vector *def_token_vec) {
bool is_double_hash = true;
vector_save(def_token_vec);
struct token *next_token = vector_peek(def_token_vec);
if (!token_is_symbol(next_token, '#')) {
is_double_hash = false;
goto out;
}

next_token = vector_peek(def_token_vec);
if (!token_is_symbol(next_token, '#')) {
is_double_hash = false;
goto out;
}

out:
vector_restore(def_token_vec);
return is_double_hash;
}

void preprocessor_handle_concat_part(struct compile_process *compiler,
struct preprocessor_definition *def,
struct preprocessor_function_args *args,
struct token *token,
struct vector *def_token_vec,
struct vector *value_vec_target) {
preprocessor_macro_function_push_something(compiler, def, args, token,
def_token_vec, value_vec_target);
}

void preprocessor_handle_concat_finalize(struct compile_process *compiler,
struct vector *tmp_vec,
struct vector *value_vec_target) {
struct vector *joined_vec = tokens_join_vector(compiler, tmp_vec);
vector_insert(value_vec_target, joined_vec, 0);
}

void preprocessor_handle_concat(struct compile_process *compiler,
struct preprocessor_definition *def,
struct preprocessor_function_args *args,
struct token *arg_token,
struct vector *def_token_vec,
struct vector *value_vec_target) {
// skip ##
vector_peek(def_token_vec);
vector_peek(def_token_vec);

struct token *right_token = vector_peek(def_token_vec);
if (!right_token) {
compiler_error(compiler, "Expected an operand");
}

struct vector *tmp_vec = vector_create(sizeof(struct token));
preprocessor_handle_concat_part(compiler, def, args, arg_token, def_token_vec,
tmp_vec);
preprocessor_handle_concat_part(compiler, def, args, right_token,
def_token_vec, tmp_vec);
preprocessor_handle_concat_finalize(compiler, tmp_vec, value_vec_target);
}

void preprocessor_macro_function_push_something(
struct compile_process *compiler, struct preprocessor_definition *def,
struct preprocessor_function_args *args, struct token *arg_token,
struct vector *def_token_vec, struct vector *value_vec_target) {
#warning "process concat"
if (preprocessor_is_next_double_hash(def_token_vec)) {
preprocessor_handle_concat(compiler, def, args, arg_token, def_token_vec,
value_vec_target);
return;
}

int res = preprocessor_macro_function_push_something_definition(
compiler, def, args, arg_token, def_token_vec, value_vec_target);
Expand Down
6 changes: 4 additions & 2 deletions test.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define ABC 0 ? 2 : 3
#define TEST(a, b) a##b

int main() { return ABC; }
int printf(const char *fmt, ...);

int main() { printf("%i", TEST(20, 30)); }
49 changes: 49 additions & 0 deletions token.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "compiler.h"
#include "helpers/buffer.h"
#include "helpers/vector.h"

#define PRIMITIVE_TYPES_TOTAL 7

Expand Down Expand Up @@ -52,3 +54,50 @@ bool token_is_primitive_keyword(struct token *token) {

return false;
}

void tokens_join_buffer_write_token(struct buffer *fmt_buf,
struct token *token) {
switch (token->type) {
case TOKEN_TYPE_IDENTIFIER:
case TOKEN_TYPE_OPERATOR:
case TOKEN_TYPE_KEYWORD:
buffer_printf(fmt_buf, "%s", token->sval);
break;

case TOKEN_TYPE_STRING:
buffer_printf(fmt_buf, "\"%s\"", token->sval);
break;

case TOKEN_TYPE_NUMBER:
buffer_printf(fmt_buf, "%lld", token->llnum);
break;

case TOKEN_TYPE_NEWLINE:
buffer_printf(fmt_buf, "\n");
break;

case TOKEN_TYPE_SYMBOL:
buffer_printf(fmt_buf, "%c", token->cval);
break;

default:
FAIL_ERR("Incompatible token type");
break;
}
}

struct vector *tokens_join_vector(struct compile_process *compiler,
struct vector *token_vec) {
struct buffer *buf = buffer_create();
vector_set_peek_pointer(token_vec, 0);
struct token *token = vector_peek(token_vec);
while (token) {
tokens_join_buffer_write_token(buf, token);
token = vector_peek(token_vec);
}

struct lex_process *lex_process =
tokens_build_for_string(compiler, buffer_ptr(buf));
assert(lex_process);
return lex_process->token_vec;
}

0 comments on commit 464b451

Please sign in to comment.