Skip to content

Commit

Permalink
impl preprocessor basic functionalites
Browse files Browse the repository at this point in the history
  • Loading branch information
omdxp committed Sep 3, 2024
1 parent 9bdd4c0 commit a34f8ad
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 10 deletions.
9 changes: 7 additions & 2 deletions compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void compiler_warning(struct compile_process *compiler, const char *msg, ...) {

int compile_file(const char *filename, const char *out_filename, int flags) {
struct compile_process *process =
compile_process_create(filename, out_filename, flags);
compile_process_create(filename, out_filename, flags, NULL);
if (!process)
return COMPILER_FAILED_WITH_ERRORS;

Expand All @@ -43,7 +43,12 @@ int compile_file(const char *filename, const char *out_filename, int flags) {
return COMPILER_FAILED_WITH_ERRORS;
}

process->token_vec = lex_process->token_vec;
process->token_vec_original = lex_process_tokens(lex_process);

// Perform preprocessing
if (preprocessor_run(process) != PREPROCESS_ALL_OK) {
return COMPILER_FAILED_WITH_ERRORS;
}

// Perform parsing
if (parse(process) != PARSE_ALL_OK) {
Expand Down
99 changes: 95 additions & 4 deletions compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
(size % C_STACK_ALIGNMENT) \
? size + (C_STACK_ALIGNMENT - (size % C_STACK_ALIGNMENT)) \
: size
#define PATH_MAX 4096

struct pos {
int line;
Expand Down Expand Up @@ -213,8 +214,86 @@ struct symbol {
void *data;
};

struct resolver_process;
enum {
PREPROCESSOR_DEFINITION_STANDARD,
PREPROCESSOR_DEFINITION_MACRO_FUNCTION,
PREPROCESSOR_DEFINITION_NATIVE_CALLBACK,
PREPROCESSOR_DEFINITION_TYPEDEF,
};

enum { PREPROCESS_ALL_OK };

struct compile_process;
struct preprocessor;
struct preprocessor_definition;
struct preprocessor_included_file;

struct preprocessor_function_arg {
// vector of struct token*
struct vector *tokens;
};

struct preprocessor_function_args {
// vector of struct preprocessor_function_arg
struct vector *args;
};

typedef int (*PREPROCESSOR_DEFINITION_NATIVE_CALL_EVALUATE)(
struct preprocessor_definition *definition,
struct preprocessor_function_args *args);
typedef struct vector *(*PREPROCESSOR_DEFINITION_NATIVE_CALL_VALUE)(
struct preprocessor_definition *definition,
struct preprocessor_function_args *args);
typedef void (*PREPROCESSOR_STATIC_INCLUDE_HANDLER_POST_CREATION)(
struct preprocessor *preprocessor,
struct preprocessor_included_file *included_file);

struct preprocessor_definition {
int type; // .i.e standard or function like macro

// name of the macro
const char *name;

union {
struct standard_preprocessor_definition {
// vector of struct token*
struct vector *value;

// vector of const char* (.i.e. arguments like ABC(a, b, c))
struct vector *args;
} standard;

struct typedef_preprocessor_definition {
struct vector *value;
} _typedef;

struct native_callback_preprocessor_definition {
PREPROCESSOR_DEFINITION_NATIVE_CALL_EVALUATE evaluate;
PREPROCESSOR_DEFINITION_NATIVE_CALL_VALUE value;
} native;
};
};

struct preprocessor_included_file {
char filename[PATH_MAX];
};

struct preprocessor {
// vector of struct_definition*
struct vector *defs;

// vector of struct preprocessor_node*
struct vector *exp_vec;

struct expressionable *expressionable;

struct compile_process *compiler;

// vector of struct preprocessor_included_file*
struct vector *includes;
};

struct resolver_process;
struct compile_process {
// The flags in regard on how this file should be compiled
int flags;
Expand All @@ -225,6 +304,9 @@ struct compile_process {
const char *abs_path;
} cfile;

// untampered vector of tokens from lexical analysis for preprocessing
struct vector *token_vec_original;

// The vector of tokens from lexical analysis
struct vector *token_vec;

Expand All @@ -250,6 +332,12 @@ struct compile_process {

// pointer to resolver process
struct resolver_process *resolver;

// vector of const char* (include directories)
struct vector *include_dirs;

// pointer to preprocessor
struct preprocessor *preprocessor;
};

enum { PARSE_ALL_OK, PARSE_GENERAL_ERROR };
Expand Down Expand Up @@ -1017,9 +1105,9 @@ enum {
};

int compile_file(const char *filename, const char *out_filename, int flags);
struct compile_process *compile_process_create(const char *filename,
const char *filename_out,
int flags);
struct compile_process *
compile_process_create(const char *filename, const char *filename_out,
int flags, struct compile_process *parent_process);

char compile_process_next_char(struct lex_process *lex_process);
char compile_process_peek_char(struct lex_process *lex_process);
Expand Down Expand Up @@ -1475,4 +1563,7 @@ int expressionable_parse_single_with_flags(
int expressionable_parse_single(struct expressionable *expressionable);
void expressionable_parse(struct expressionable *expressionable);

struct preprocessor *preprocessor_create(struct compile_process *compiler);
int preprocessor_run(struct compile_process *compiler);

#endif
17 changes: 14 additions & 3 deletions cprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include <stdio.h>
#include <stdlib.h>

struct compile_process *compile_process_create(const char *filename,
const char *filename_out,
int flags) {
struct compile_process *
compile_process_create(const char *filename, const char *filename_out,
int flags, struct compile_process *parent_process) {
FILE *file = fopen(filename, "r");
if (!file) {
return NULL;
Expand All @@ -22,6 +22,8 @@ struct compile_process *compile_process_create(const char *filename,
struct compile_process *process = calloc(1, sizeof(struct compile_process));
process->node_vec = vector_create(sizeof(struct node *));
process->node_tree_vec = vector_create(sizeof(struct node *));
process->token_vec = vector_create(sizeof(struct token *));
process->token_vec_original = vector_create(sizeof(struct token *));

process->flags = flags;
process->cfile.fp = file;
Expand All @@ -32,6 +34,15 @@ struct compile_process *compile_process_create(const char *filename,
symresolver_init(process);
symresolver_new_table(process);

if (parent_process) {
process->preprocessor = parent_process->preprocessor;
process->include_dirs = parent_process->include_dirs;
} else {
process->preprocessor = preprocessor_create(process);
process->include_dirs = vector_create(sizeof(const char *));
// setup default include directories
}

return process;
}

Expand Down
140 changes: 139 additions & 1 deletion preprocessor/preprocessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ enum {
PREPROCESSOR_TENARY_NODE,
};

struct preprocess_node {
struct preprocessor_node {
int type;
struct preprocessor_const_val {
union {
Expand Down Expand Up @@ -75,3 +75,141 @@ struct preprocess_node {

const char *sval;
};

void preprocessor_exec_error(struct compile_process *compiler,
const char *message) {
compiler_error(compiler, "#error %s", message);
}

void preprocessor_exec_warning(struct compile_process *compiler,
const char *message) {
compiler_warning(compiler, "#warning %s", message);
}

struct preprocessor_included_file *
preprocessor_add_included_file(struct preprocessor *preprocessor,
const char *filename) {
struct preprocessor_included_file *included_file =
malloc(sizeof(struct preprocessor_included_file));
strncpy(included_file->filename, filename, sizeof(included_file->filename));
vector_push(preprocessor->includes, &included_file);
return included_file;
}

void preprocessor_create_static_include(
struct preprocessor *preprocessor, const char *filename,
PREPROCESSOR_STATIC_INCLUDE_HANDLER_POST_CREATION creation_handler) {
struct preprocessor_included_file *included_file =
preprocessor_add_included_file(preprocessor, filename);
creation_handler(preprocessor, included_file);
}

bool preprocessor_is_keyword(const char *type) { return S_EQ(type, "defined"); }

struct vector *preprocessor_build_value_vector_for_integer(int value) {
struct vector *token_vec = vector_create(sizeof(struct token));
struct token t1 = {};
t1.type = TOKEN_TYPE_NUMBER;
t1.llnum = value;
vector_push(token_vec, &t1);
return token_vec;
}

void preprocessor_token_vec_push_keyword_and_identifier(
struct vector *token_vec, const char *keyword, const char *identifier) {
struct token t1 = {};
t1.type = TOKEN_TYPE_KEYWORD;
t1.sval = keyword;
vector_push(token_vec, &t1);

struct token t2 = {};
t2.type = TOKEN_TYPE_IDENTIFIER;
t2.sval = identifier;
vector_push(token_vec, &t2);
}

struct preprocessor_node *
preprocessor_node_create(struct preprocessor_node *node) {
struct preprocessor_node *res = malloc(sizeof(struct preprocessor_node));
memcpy(res, node, sizeof(struct preprocessor_node));
return res;
}

int preprocessor_definition_argument_exists(struct preprocessor_definition *def,
const char *arg) {
vector_set_peek_pointer(def->standard.args, 0);
int i = 0;
const char *current = vector_peek(def->standard.args);
while (current) {
if (S_EQ(current, arg)) {
return i;
}

i++;
current = vector_peek(def->standard.args);
}

return -1;
}

struct preprocessor_function_argument *
preprocessor_function_argument_at(struct preprocessor_function_args *args,
int index) {
return vector_at(args->args, index);
}

void preprocessor_token_push_to_function_arguments(
struct preprocessor_function_args *args, struct token *token) {
struct preprocessor_function_arg arg = {};
arg.tokens = vector_create(sizeof(struct token));
vector_push(arg.tokens, token);
vector_push(args->args, &arg);
}

void preprocessor_function_argument_push_to_vec(
struct preprocessor_function_arg *arg, struct vector *vec) {
vector_set_peek_pointer(arg->tokens, 0);
struct token *token = vector_peek(arg->tokens);
while (token) {
vector_push(vec, token);
token = vector_peek(arg->tokens);
}
}

void preprocessor_init(struct preprocessor *preprocessor) {
memset(preprocessor, 0, sizeof(struct preprocessor));
preprocessor->defs = vector_create(sizeof(struct preprocessor_definition *));
preprocessor->includes =
vector_create(sizeof(struct preprocessor_included_file *));
#warning "create proprocessor default definitions"
}

struct preprocessor *preprocessor_create(struct compile_process *compiler) {
struct preprocessor *preprocessor = malloc(sizeof(struct preprocessor));
preprocessor_init(preprocessor);
preprocessor->compiler = compiler;
return preprocessor;
}

struct token *preprocessor_next_token(struct compile_process *compiler) {
return vector_peek(compiler->token_vec_original);
}

void preprocessor_handle_token(struct compile_process *compiler,
struct token *token) {
switch (token->type) {
// handle all token types
}
}

int preprocessor_run(struct compile_process *compiler) {
#warning "add source file as an included file"
vector_set_peek_pointer(compiler->token_vec_original, 0);
struct token *token = preprocessor_next_token(compiler);
while (token) {
preprocessor_handle_token(compiler, token);
token = preprocessor_next_token(compiler);
}

return PREPROCESS_ALL_OK;
}

0 comments on commit a34f8ad

Please sign in to comment.