Porytiles
Loading...
Searching...
No Matches
function_call_info.cpp
Go to the documentation of this file.
2
3#include <string>
4#include <vector>
5
7
8namespace porytiles {
9
10namespace {
11
21[[nodiscard]] std::vector<std::vector<Token>>
22parse_arguments(const std::vector<Token> &tokens, std::size_t start_index, std::size_t &end_index)
23{
24 std::vector<std::vector<Token>> arguments;
25 std::vector<Token> current_arg;
26 int paren_depth = 1;
27
28 for (std::size_t i = start_index; i < tokens.size(); ++i) {
29 const Token &tok = tokens[i];
30
31 if (tok.is(TokenType::left_paren)) {
32 ++paren_depth;
33 current_arg.push_back(tok);
34 }
35 else if (tok.is(TokenType::right_paren)) {
36 --paren_depth;
37 if (paren_depth == 0) {
38 // End of arguments
39 if (!current_arg.empty()) {
40 arguments.push_back(std::move(current_arg));
41 }
42 end_index = i;
43 return arguments;
44 }
45 current_arg.push_back(tok);
46 }
47 else if (tok.is(TokenType::comma) && paren_depth == 1) {
48 // Top-level comma separates arguments
49 arguments.push_back(std::move(current_arg));
50 current_arg.clear();
51 }
52 else {
53 current_arg.push_back(tok);
54 }
55 }
56
57 // If we get here, we didn't find a matching close paren
58 end_index = tokens.size();
59 if (!current_arg.empty()) {
60 arguments.push_back(std::move(current_arg));
61 }
62 return arguments;
63}
64
65} // namespace
66
67std::vector<FunctionCallInfo>
68find_function_calls(const std::vector<Token> &tokens, const std::string &target_function_name)
69{
70 std::vector<FunctionCallInfo> result;
71
72 for (std::size_t i = 0; i + 1 < tokens.size(); ++i) {
73 // Look for: identifier(target_name) + lparen
74 if (tokens[i].is(TokenType::identifier) && tokens[i].text() == target_function_name &&
75 tokens[i + 1].is(TokenType::left_paren)) {
76
77 std::size_t end_index = 0;
78 auto arguments = parse_arguments(tokens, i + 2, end_index);
79
80 result.emplace_back(target_function_name, std::move(arguments), i);
81
82 // Skip past the closing paren to avoid re-parsing nested calls
83 i = end_index;
84 }
85 }
86
87 return result;
88}
89
90std::vector<FunctionCallInfo> find_all_function_calls(const std::vector<Token> &tokens)
91{
92 std::vector<FunctionCallInfo> result;
93
94 for (std::size_t i = 0; i + 1 < tokens.size(); ++i) {
95 // Look for: identifier + lparen
96 if (tokens[i].is(TokenType::identifier) && tokens[i + 1].is(TokenType::left_paren)) {
97 std::string func_name = tokens[i].text();
98
99 std::size_t end_index = 0;
100 auto arguments = parse_arguments(tokens, i + 2, end_index);
101
102 result.emplace_back(std::move(func_name), std::move(arguments), i);
103
104 // Skip past the closing paren to avoid re-parsing nested calls
105 i = end_index;
106 }
107 }
108
109 return result;
110}
111
112} // namespace porytiles
std::vector< FunctionCallInfo > find_all_function_calls(const std::vector< Token > &tokens)
Finds all function call expressions within a token stream.
std::vector< FunctionCallInfo > find_function_calls(const std::vector< Token > &tokens, const std::string &target_function_name)
Finds all calls to a specific function within a token stream.