aboutsummaryrefslogtreecommitdiffhomepage
path: root/preprocess.c
diff options
context:
space:
mode:
Diffstat (limited to 'preprocess.c')
-rw-r--r--preprocess.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/preprocess.c b/preprocess.c
index 7141dec..e909eec 100644
--- a/preprocess.c
+++ b/preprocess.c
@@ -18,7 +18,14 @@ struct PpToken {
};
typedef struct PpToken PpToken;
+enum PpMacroKind {
+ PpMacroKind_obj,
+ PpMacroKind_func,
+};
+typedef enum PpMacroKind PpMacroKind;
+
struct PpMacro {
+ PpMacroKind kind;
String name;
PpToken* tokens;
};
@@ -53,6 +60,7 @@ PpMacros* pp_macros_new() {
void add_predefined_macros(PpMacros* pp_macros) {
PpMacro* pp_macro = pp_macros->data + pp_macros->len;
+ pp_macro->kind = PpMacroKind_obj;
pp_macro->name.len = strlen("__ducc__");
pp_macro->name.data = "__ducc__";
pp_macro->tokens = calloc(1, sizeof(PpToken));
@@ -500,24 +508,50 @@ PpToken* process_include_directive(Preprocessor* pp, PpToken* tok) {
PpToken* process_define_directive(Preprocessor* pp, PpToken* tok) {
PpToken* tok2 = skip_whitespace(tok + 1);
+ PpToken* macro_replacements;
+ PpMacro* pp_macro;
if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "define")) {
++tok2;
tok2 = skip_whitespace(tok2);
if (tok2->kind == PpTokenKind_identifier) {
PpToken* macro_name = tok2;
++tok2;
- tok2 = skip_whitespace(tok2);
- if (tok2->kind == PpTokenKind_identifier || tok2->kind == PpTokenKind_pp_number) {
- PpToken* macro_replacements = tok2;
-
- PpMacro* pp_macro = pp->pp_macros->data + pp->pp_macros->len;
- pp_macro->name.len = macro_name->raw.len;
- pp_macro->name.data = macro_name->raw.data;
- pp_macro->tokens = calloc(1, sizeof(PpToken));
- pp_macro->tokens[0].kind = macro_replacements->kind;
- pp_macro->tokens[0].raw.len = macro_replacements->raw.len;
- pp_macro->tokens[0].raw.data = macro_replacements->raw.data;
- ++pp->pp_macros->len;
+ if (tok2->kind == PpTokenKind_punctuator && string_equals_cstr(&tok2->raw, "(")) {
+ ++tok2;
+ if (tok2->kind == PpTokenKind_punctuator && string_equals_cstr(&tok2->raw, ")")) {
+ ++tok2;
+ } else {
+ fatal_error("#define: invalid function-like macro syntax");
+ }
+ tok2 = skip_whitespace(tok2);
+ if (tok2->kind == PpTokenKind_identifier || tok2->kind == PpTokenKind_pp_number) {
+ macro_replacements = tok2;
+
+ pp_macro = pp->pp_macros->data + pp->pp_macros->len;
+ pp_macro->kind = PpMacroKind_func;
+ pp_macro->name.len = macro_name->raw.len;
+ pp_macro->name.data = macro_name->raw.data;
+ pp_macro->tokens = calloc(1, sizeof(PpToken));
+ pp_macro->tokens[0].kind = macro_replacements->kind;
+ pp_macro->tokens[0].raw.len = macro_replacements->raw.len;
+ pp_macro->tokens[0].raw.data = macro_replacements->raw.data;
+ ++pp->pp_macros->len;
+ }
+ } else {
+ tok2 = skip_whitespace(tok2);
+ if (tok2->kind == PpTokenKind_identifier || tok2->kind == PpTokenKind_pp_number) {
+ macro_replacements = tok2;
+
+ pp_macro = pp->pp_macros->data + pp->pp_macros->len;
+ pp_macro->kind = PpMacroKind_obj;
+ pp_macro->name.len = macro_name->raw.len;
+ pp_macro->name.data = macro_name->raw.data;
+ pp_macro->tokens = calloc(1, sizeof(PpToken));
+ pp_macro->tokens[0].kind = macro_replacements->kind;
+ pp_macro->tokens[0].raw.len = macro_replacements->raw.len;
+ pp_macro->tokens[0].raw.data = macro_replacements->raw.data;
+ ++pp->pp_macros->len;
+ }
}
}
remove_directive_tokens(tok, tok2 + 1);
@@ -528,12 +562,15 @@ PpToken* process_define_directive(Preprocessor* pp, PpToken* tok) {
void expand_macro(Preprocessor* pp, PpToken* tok) {
int pp_macro_idx = find_pp_macro(pp, &tok->raw);
- if (pp_macro_idx != -1) {
- PpToken* macro_replacements = pp->pp_macros->data[pp_macro_idx].tokens;
- tok->kind = macro_replacements->kind;
- tok->raw.data = macro_replacements->raw.data;
- tok->raw.len = macro_replacements->raw.len;
+ if (pp_macro_idx == -1) {
+ return;
}
+
+ PpMacro* pp_macro = pp->pp_macros->data + pp_macro_idx;
+ PpToken* macro_replacements = pp_macro->tokens;
+ tok->kind = macro_replacements->kind;
+ tok->raw.data = macro_replacements->raw.data;
+ tok->raw.len = macro_replacements->raw.len;
}
void process_pp_directives(Preprocessor* pp) {