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