Skip to content

Commit 3c01309

Browse files
committed
feat(macro processor, error): adding better error messages when a macro fails, to show the macro we were expanding and what failed
1 parent 770fa09 commit 3c01309

31 files changed

+134
-33
lines changed

include/Ark/Compiler/Macros/Executor.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ namespace Ark::internal
5858
*/
5959
virtual bool canHandle(Node& node) = 0;
6060

61+
/**
62+
* @brief Returns the macro node that will be expanded
63+
*
64+
* @param node AST node on which the executor will run
65+
* @return Node
66+
*/
67+
virtual Node macroNode(Node& node) = 0;
68+
6169
protected:
6270
unsigned int m_debug;
6371
MacroProcessor* m_processor; ///< This is a non-owned pointer.
@@ -118,7 +126,7 @@ namespace Ark::internal
118126
* @param message the error
119127
* @param node the node in which there is an error
120128
*/
121-
[[noreturn]] static void throwMacroProcessingError(const std::string& message, const Node& node);
129+
[[noreturn]] void throwMacroProcessingError(const std::string& message, const Node& node);
122130
};
123131

124132
}

include/Ark/Compiler/Macros/Executors/Conditional.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ namespace Ark::internal
3939
* @return true if the executor can handle the given node
4040
*/
4141
[[nodiscard]] bool canHandle(Node& node) override;
42+
43+
[[nodiscard]] Node macroNode(Node& node) override;
4244
};
4345

4446
}

include/Ark/Compiler/Macros/Executors/Function.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace Ark::internal
2828
/**
2929
*
3030
* @param node
31-
* @param depth depth of the macro processor evalution
31+
* @param depth depth of the macro processor evaluation
3232
* @return true if the applying worked
3333
*/
3434
bool applyMacro(Node& node, unsigned depth) override;
@@ -40,6 +40,8 @@ namespace Ark::internal
4040
*/
4141
[[nodiscard]] bool canHandle(Node& node) override;
4242

43+
[[nodiscard]] Node macroNode(Node& node) override;
44+
4345
private:
4446
void unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent, std::size_t index = 0, std::size_t unify_depth = 0);
4547
};

include/Ark/Compiler/Macros/Executors/Symbol.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace Ark::internal
2828
/**
2929
*
3030
* @param node
31-
* @param depth depth of the macro processor evalution
31+
* @param depth depth of the macro processor evaluation
3232
* @return true if the applying worked
3333
*/
3434
bool applyMacro(Node& node, unsigned depth) override;
@@ -39,6 +39,8 @@ namespace Ark::internal
3939
* @return true if the executor can handle the given node
4040
*/
4141
[[nodiscard]] bool canHandle(Node& node) override;
42+
43+
[[nodiscard]] Node macroNode(Node& node) override;
4244
};
4345

4446
}

include/Ark/Compiler/Macros/Processor.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ namespace Ark::internal
5555
friend class MacroExecutor;
5656

5757
private:
58-
Node m_ast; ///< The modified AST
59-
std::vector<MacroScope> m_macros; ///< Handling macros in a scope fashion
58+
Node m_ast; ///< The modified AST
59+
std::vector<MacroScope> m_macros; ///< Handling macros in a scope fashion
60+
std::vector<Node> m_macros_being_applied; ///< Stack of macros being applied. The last one is the current one we are working on
6061
std::shared_ptr<MacroExecutor> m_conditional_executor;
6162
std::vector<std::shared_ptr<MacroExecutor>> m_executors;
6263
std::unordered_map<std::string, Node> m_defined_functions;
@@ -152,7 +153,7 @@ namespace Ark::internal
152153
* @param name the name of the macro being applied
153154
* @param kind the macro kind, empty by default (eg "operator", "condition")
154155
*/
155-
static void checkMacroArgCountEq(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = "");
156+
void checkMacroArgCountEq(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = "");
156157

157158
/**
158159
* @brief Check if the given node has at least the provided argument count, otherwise throws an error
@@ -162,7 +163,7 @@ namespace Ark::internal
162163
* @param name the name of the macro being applied
163164
* @param kind the macro kind, empty by default (eg "operator", "condition")
164165
*/
165-
static void checkMacroArgCountGe(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = "");
166+
void checkMacroArgCountGe(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = "");
166167

167168
/**
168169
* @brief Evaluate only the macros
@@ -181,15 +182,15 @@ namespace Ark::internal
181182
* @return true
182183
* @return false
183184
*/
184-
static bool isTruthy(const Node& node);
185+
bool isTruthy(const Node& node);
185186

186187
/**
187188
* @brief Throw a macro processing error
188189
*
189190
* @param message the error
190191
* @param node the node in which there is an error
191192
*/
192-
[[noreturn]] static void throwMacroProcessingError(const std::string& message, const Node& node);
193+
[[noreturn]] void throwMacroProcessingError(const std::string& message, const Node& node) const;
193194
};
194195
}
195196

include/Ark/Exceptions.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ namespace Ark
103103
const std::size_t col;
104104
const std::string expr;
105105
const std::optional<internal::utf8_char_t> symbol;
106+
const bool is_macro_expansion = false;
106107

107108
CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const std::optional<internal::utf8_char_t> maybe_symbol = std::nullopt) :
108109
filename(std::move(filename_)),
@@ -111,6 +112,15 @@ namespace Ark
111112
expr(std::move(expression)),
112113
symbol(maybe_symbol)
113114
{}
115+
116+
CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const bool from_macro_expansion) :
117+
filename(std::move(filename_)),
118+
line(lineNum),
119+
col(column),
120+
expr(std::move(expression)),
121+
symbol(std::nullopt),
122+
is_macro_expansion(from_macro_expansion)
123+
{}
114124
};
115125

116126
/**

src/arkreactor/Compiler/Macros/Executor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ namespace Ark::internal
3636

3737
void MacroExecutor::throwMacroProcessingError(const std::string& message, const Node& node)
3838
{
39-
MacroProcessor::throwMacroProcessingError(message, node);
39+
m_processor->throwMacroProcessingError(message, node);
4040
}
4141
}

src/arkreactor/Compiler/Macros/Executors/Conditional.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ namespace Ark::internal
3434
{
3535
return node.nodeType() == NodeType::Macro && node.list()[0].nodeType() == NodeType::Keyword && node.list()[0].keyword() == Keyword::If;
3636
}
37+
38+
Node ConditionalExecutor::macroNode(Node& node)
39+
{
40+
return node;
41+
}
3742
}

src/arkreactor/Compiler/Macros/Executors/Function.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ namespace Ark::internal
8787
return false;
8888
}
8989

90+
Node FunctionExecutor::macroNode(Node& node)
91+
{
92+
const Node& first = node.list()[0];
93+
if (const Node* macro = findNearestMacro(first.string()); macro != nullptr && macro->constList().size() == 3)
94+
return *macro;
95+
return {};
96+
}
97+
9098
void FunctionExecutor::unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent, const std::size_t index, const std::size_t unify_depth)
9199
{
92100
if (unify_depth > MaxMacroUnificationDepth)

src/arkreactor/Compiler/Macros/Executors/Symbol.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,11 @@ namespace Ark::internal
2323

2424
return false;
2525
}
26+
27+
Node SymbolExecutor::macroNode(Node& node)
28+
{
29+
if (const Node* macro = findNearestMacro(node.string()); macro != nullptr)
30+
return *macro;
31+
return {};
32+
}
2633
}

0 commit comments

Comments
 (0)