Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/macro processor #501

Merged
merged 7 commits into from
Nov 23, 2024
7 changes: 7 additions & 0 deletions include/Ark/Compiler/AST/Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ namespace Ark::internal
*/
[[nodiscard]] bool isListLike() const noexcept;

/**
* @brief Copy a node to the current one, while keeping the filename and position in the file
*
* @param source node to copy type and value from
*/
void updateValueAndType(const Node& source) noexcept;

/**
* @brief Set the Node Type object
*
Expand Down
42 changes: 13 additions & 29 deletions include/Ark/Compiler/Macros/Executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file Executor.hpp
* @author Ray John Alovera ([email protected]), Alexandre Plateau ([email protected])
* @brief The base class for all MacroExecutors
* @version 2.0
* @version 3.0
* @date 2024-03-03
*
* @copyright Copyright (c) 2021-2024
Expand Down Expand Up @@ -63,14 +63,6 @@ namespace Ark::internal
unsigned int m_debug;
MacroProcessor* m_processor; ///< This is a non-owned pointer.

/**
* @brief Set the file attributes of the output node based on the original node
* @param origin original node
* @param output output node which will be modified
* @param macro modified node, macro applied
*/
void setWithFileAttributes(const Node origin, Node& output, const Node& macro);

/**
* @brief Find the nearest macro matching a giving name
*
Expand All @@ -82,13 +74,22 @@ namespace Ark::internal
[[nodiscard]] const Node* findNearestMacro(const std::string& name) const;

/**
* @brief Registers macros based on their type
* @brief Apply a macro on a given node
* @details Proxy function for MacroProcessor::applyMacro
*
* @param node
* @param depth
*/
void applyMacroProxy(Node& node, unsigned depth);

/**
* @brief Registers macros based on their type, expand conditional macros
* @details Validate macros and register them by their name
* Proxy function for MacroProcessor::registerMacro
* Proxy function for MacroProcessor::handleMacroNode
*
* @param node A node of type Macro
*/
void registerMacro(Node& node) const;
void handleMacroNode(Node& node) const;

/**
* @brief Check if a node can be evaluated to true
Expand All @@ -111,12 +112,6 @@ namespace Ark::internal
*/
Node evaluate(Node& node, unsigned depth, bool is_not_body) const;

/**
* @brief Applies the spread operator
* @details Proxy function for MacroProcessor::unify
*/
void unify(const std::unordered_map<std::string, Node>&, Node&, Node*) const;

/**
* @brief Throw a macro processing error
* @details Proxy function for MacroProcessor::throwMacroProcessingError
Expand All @@ -125,17 +120,6 @@ namespace Ark::internal
* @param node the node in which there is an error
*/
[[noreturn]] static void throwMacroProcessingError(const std::string& message, const Node& node);

/**
* @brief Execute a node, trying to emplace macros calls
* @details Proxy function for MacroProcessor::applyMacro
*
* @param node
* @param depth
* @return true
* @return false
*/
bool applyMacroProxy(Node& node, unsigned depth) const;
};

}
Expand Down
5 changes: 4 additions & 1 deletion include/Ark/Compiler/Macros/Executors/Function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file Function.hpp
* @author Ray John Alovera ([email protected]), Alexandre Plateau ([email protected])
* @brief Executor for List Macros
* @version 2.1
* @version 3.0
* @date 2021-05-04
*
* @copyright Copyright (c) 2021-2024
Expand Down Expand Up @@ -40,6 +40,9 @@ namespace Ark::internal
* @return true if the executor can handle the given node
*/
[[nodiscard]] bool canHandle(Node& node) override;

private:
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);
};

}
Expand Down
35 changes: 5 additions & 30 deletions include/Ark/Compiler/Macros/Processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file Processor.hpp
* @author Alexandre Plateau ([email protected])
* @brief Handles the macros and their expansion in ArkScript source code
* @version 2.1
* @version 3.0
* @date 2021-02-18
*
* @copyright Copyright (c) 2021-2024
Expand Down Expand Up @@ -57,6 +57,7 @@ namespace Ark::internal
private:
Node m_ast; ///< The modified AST
std::vector<MacroScope> m_macros; ///< Handling macros in a scope fashion
std::shared_ptr<MacroExecutor> m_conditional_executor;
std::vector<std::shared_ptr<MacroExecutor>> m_executors;
std::unordered_map<std::string, Node> m_defined_functions;

Expand All @@ -83,21 +84,14 @@ namespace Ark::internal
*/
void deleteNearestMacro(const std::string& name);

/**
* @brief Recursively apply macros on a given node
*
* @param node
*/
void recurApply(Node& node);

/**
* @brief Check if a given node is a list node, and starts with a Begin
*
* @param node
* @return true if it starts with a Begin
* @return false
*/
static bool hadBegin(const Node& node);
static bool isBeginNode(const Node& node);

/**
* @brief Remove a begin block added by a macro
Expand All @@ -117,12 +111,12 @@ namespace Ark::internal
[[nodiscard]] bool isConstEval(const Node& node) const;

/**
* @brief Registers macros based on their type
* @brief Registers macros based on their type, expand conditional macros
* @details Validate macros and register them by their name
*
* @param node A node of type Macro
*/
void registerMacro(Node& node);
void handleMacroNode(Node& node);

/**
* @brief Registers a function definition node
Expand All @@ -149,25 +143,6 @@ namespace Ark::internal
*/
bool applyMacro(Node& node, unsigned depth);

/**
* @brief Unify a target node with a given map symbol => replacement node, recursively
*
* @param map
* @param target
* @param parent
* @param index position of target inside parent->list()
* @param unify_depth call depth to unify, to avoid deep recursive unification
*/
void unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent, std::size_t index, std::size_t unify_depth = 0);

/**
* @brief Set the file attributes of the output node based on the original node
* @param origin original node
* @param output output node which will be modified
* @param macro modified node, macro applied
*/
void setWithFileAttributes(const Node origin, Node& output, const Node& macro);

/**
* @brief Check if the given node has exactly the provided argument count, otherwise throws an error
*
Expand Down
6 changes: 6 additions & 0 deletions src/arkreactor/Compiler/AST/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ namespace Ark::internal
return m_type == NodeType::List || m_type == NodeType::Macro;
}

void Node::updateValueAndType(const Node& source) noexcept
{
m_type = source.m_type;
m_value = source.m_value;
}

void Node::setNodeType(const NodeType type) noexcept
{
m_type = type;
Expand Down
2 changes: 1 addition & 1 deletion src/arkreactor/Compiler/AST/Optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Ark::internal
{
m_logger.traceStart("process");
m_ast = ast;
// FIXME activate this removeUnused();
// todo: activate this removeUnused();
m_logger.traceEnd();
}

Expand Down
6 changes: 5 additions & 1 deletion src/arkreactor/Compiler/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ namespace Ark::internal
handleCalls(x, p, is_result_unused, is_terminal, var_name);
}
else
throwCompilerError("boop", x); // FIXME
throwCompilerError(
fmt::format(
"NodeType `{}' not handled in Compiler::compileExpression. Please fill an issue on GitHub: https://github.com/ArkScript-lang/Ark",
typeToString(x)),
x);
}

void Compiler::compileSymbol(const Node& x, const Page p, const bool is_result_unused)
Expand Down
24 changes: 6 additions & 18 deletions src/arkreactor/Compiler/Macros/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,19 @@ namespace Ark::internal
m_processor(processor)
{}

void MacroExecutor::setWithFileAttributes(const Node origin, Node& output, const Node& macro)
const Node* MacroExecutor::findNearestMacro(const std::string& name) const
{
output = macro;
output.setFilename(origin.filename());
output.setPos(origin.line(), origin.col());
return m_processor->findNearestMacro(name);
}

const Node* MacroExecutor::findNearestMacro(const std::string& name) const
void MacroExecutor::applyMacroProxy(Node& node, unsigned depth)
{
return m_processor->findNearestMacro(name);
m_processor->applyMacro(node, depth);
}

void MacroExecutor::registerMacro(Node& node) const
void MacroExecutor::handleMacroNode(Node& node) const
{
m_processor->registerMacro(node);
m_processor->handleMacroNode(node);
}

bool MacroExecutor::isTruthy(const Node& node) const
Expand All @@ -36,18 +34,8 @@ namespace Ark::internal
return m_processor->evaluate(node, depth, is_not_body);
}

void MacroExecutor::unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent) const
{
m_processor->unify(map, target, parent, /* index= */ 0, /* unify_depth= */ 0);
}

void MacroExecutor::throwMacroProcessingError(const std::string& message, const Node& node)
{
MacroProcessor::throwMacroProcessingError(message, node);
}

bool MacroExecutor::applyMacroProxy(Node& node, const unsigned depth) const
{
return m_processor->applyMacro(node, depth);
}
}
6 changes: 3 additions & 3 deletions src/arkreactor/Compiler/Macros/Executors/Conditional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace Ark::internal

// evaluate cond
if (isTruthy(temp))
setWithFileAttributes(node, node, if_true);
node.updateValueAndType(if_true);
else if (node.constList().size() > 3)
setWithFileAttributes(node, node, if_false);
node.updateValueAndType(if_false);
else
{
// remove node because nothing matched
Expand All @@ -22,7 +22,7 @@ namespace Ark::internal
}

if (node.nodeType() == NodeType::Macro)
registerMacro(node);
handleMacroNode(node);

return true;
}
Expand Down
Loading
Loading