summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-08-13 12:49:06 +0300
committerAndreas Kling <kling@serenityos.org>2021-08-14 12:40:55 +0200
commitf6c9071f0dff0a61e9a25408e1cd9ae0ed8ca64f (patch)
tree14fffa7546894cdb7b8e9bd97f447566c116a396
parent8505fcb8ae313792d32550bffec0a72f86e60102 (diff)
downloadserenity-f6c9071f0dff0a61e9a25408e1cd9ae0ed8ca64f.zip
LibCpp: Evaluate function-like macro calls
-rw-r--r--Userland/Libraries/LibCpp/Preprocessor.cpp37
-rw-r--r--Userland/Libraries/LibCpp/Preprocessor.h1
2 files changed, 35 insertions, 3 deletions
diff --git a/Userland/Libraries/LibCpp/Preprocessor.cpp b/Userland/Libraries/LibCpp/Preprocessor.cpp
index 002f668993..35994175b4 100644
--- a/Userland/Libraries/LibCpp/Preprocessor.cpp
+++ b/Userland/Libraries/LibCpp/Preprocessor.cpp
@@ -250,14 +250,13 @@ size_t Preprocessor::do_substitution(Vector<Token> const& tokens, size_t token_i
if (!macro_call.has_value())
return token_index;
- // TODO: Evaluate macro call
- auto processed_value = defined_value.value;
Vector<Token> original_tokens;
for (size_t i = token_index; i <= macro_call->end_token_index; ++i) {
original_tokens.append(tokens[i]);
}
VERIFY(!original_tokens.is_empty());
+ auto processed_value = evaluate_macro_call(*macro_call, defined_value);
m_substitutions.append({ original_tokens, defined_value, processed_value });
Lexer lexer(processed_value);
@@ -356,9 +355,41 @@ Optional<Preprocessor::Definition> Preprocessor::create_definition(StringView li
++token_index;
}
- definition.value = line.substring_view(tokens[token_index].start().column);
+ if (token_index < tokens.size())
+ definition.value = line.substring_view(tokens[token_index].start().column);
return definition;
}
+String Preprocessor::evaluate_macro_call(MacroCall const& macro_call, Definition const& definition)
+{
+ if (macro_call.arguments.size() != definition.parameters.size()) {
+ dbgln("mismatch in # of arguments for macro call: {}", macro_call.name.text());
+ return {};
+ }
+
+ Lexer lexer { definition.value };
+ auto tokens = lexer.lex();
+
+ StringBuilder processed_value;
+ for (auto& token : tokens) {
+ if (token.type() != Token::Type::Identifier) {
+ processed_value.append(token.text());
+ continue;
+ }
+
+ auto param_index = definition.parameters.find_first_index(token.text());
+ if (!param_index.has_value()) {
+ processed_value.append(token.text());
+ continue;
+ }
+
+ auto& argument = macro_call.arguments[*param_index];
+ for (auto& arg_token : argument.tokens) {
+ processed_value.append(arg_token.text());
+ }
+ }
+ return processed_value.to_string();
+}
+
};
diff --git a/Userland/Libraries/LibCpp/Preprocessor.h b/Userland/Libraries/LibCpp/Preprocessor.h
index f91ee965f3..ab5af75d1a 100644
--- a/Userland/Libraries/LibCpp/Preprocessor.h
+++ b/Userland/Libraries/LibCpp/Preprocessor.h
@@ -65,6 +65,7 @@ private:
size_t end_token_index { 0 };
};
Optional<MacroCall> parse_macro_call(Vector<Token> const& tokens, size_t token_index);
+ String evaluate_macro_call(MacroCall const&, Definition const&);
String m_filename;
String m_program;