Skip to content

Commit

Permalink
Merge pull request #484 from ArkScript-lang/fix/macro-proc-on-windows
Browse files Browse the repository at this point in the history
Fix/macro proc on windows
  • Loading branch information
SuperFola authored Jul 28, 2024
2 parents b4bc6e8 + 9fc79bc commit 853612e
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 125 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ jobs:

- name: Summarize for PR
id: summary
if: ${{ steps.PR.outputs.number != null }}
if: steps.PR.outputs.pr_found == 'true'
shell: bash
run: |
echo "FUZZ_SUMMARY<<EOF" >> $GITHUB_ENV
Expand All @@ -256,15 +256,15 @@ jobs:
echo "EOF" >> $GITHUB_ENV
- name: Summarize
if: ${{ steps.PR.outputs.number == null }}
if: steps.PR.outputs.pr_found == 'false'
shell: bash
run: |
afl-whatsup -s -d output
afl-showmap -C -i output -o /dev/null -- ./${BUILD_FOLDER}/arkscript @@ -L ./lib
- name: Find Comment
uses: peter-evans/find-comment@v3
if: ${{ steps.PR.outputs.number != null }}
if: steps.PR.outputs.pr_found == 'true'
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
Expand All @@ -273,7 +273,7 @@ jobs:

- name: Create or update comment
uses: peter-evans/create-or-update-comment@v4
if: ${{ steps.PR.outputs.number != null }}
if: steps.PR.outputs.pr_found == 'true'
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ elseif (MSVC)
/wd4244 # disable warning about data loss (size_t -> char)
/wd4505 # disable warning about unused static function was deleted
/wd4068) # disable warnings about unknown pragmas.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8000000") # set stack size to 8MB
endif ()

# Link libraries
Expand Down
55 changes: 0 additions & 55 deletions include/Ark/Compiler/Macros/Pipeline.hpp

This file was deleted.

16 changes: 14 additions & 2 deletions include/Ark/Compiler/Macros/Processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@

#include <Ark/Compiler/AST/Node.hpp>
#include <Ark/Compiler/Macros/MacroScope.hpp>
#include <Ark/Compiler/Macros/Pipeline.hpp>

#include <unordered_map>
#include <memory>
#include <string>

namespace Ark::internal
{
class MacroExecutor;

/**
* @brief The class handling the macros definitions and calls, given an AST
*
Expand Down Expand Up @@ -55,7 +57,7 @@ namespace Ark::internal
unsigned m_debug; ///< The debug level
Node m_ast; ///< The modified AST
std::vector<MacroScope> m_macros; ///< Handling macros in a scope fashion
MacroExecutorPipeline m_executor_pipeline;
std::vector<std::shared_ptr<MacroExecutor>> m_executors;
std::vector<std::string> m_predefined_macros; ///< Already existing macros, non-keywords, non-builtins
std::unordered_map<std::string, Node> m_defined_functions;

Expand Down Expand Up @@ -162,6 +164,16 @@ namespace Ark::internal

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
*
* @param node a list node with a macro application, eg (= a b)
* @param expected expected argument count, not counting the macro
* @param name the name of the macro being applied
* @param kind the macro kind, empty by default (eg "operator", "condition")
*/
void checkMacroArgCount(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = "");

/**
* @brief Evaluate only the macros
*
Expand Down
21 changes: 0 additions & 21 deletions src/arkreactor/Compiler/Macros/Pipeline.cpp

This file was deleted.

142 changes: 99 additions & 43 deletions src/arkreactor/Compiler/Macros/Processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Ark/Constants.hpp>
#include <Ark/Exceptions.hpp>
#include <Ark/Builtins/Builtins.hpp>
#include <Ark/Compiler/Macros/Executor.hpp>
#include <Ark/Compiler/Macros/Executors/Symbol.hpp>
#include <Ark/Compiler/Macros/Executors/Function.hpp>
#include <Ark/Compiler/Macros/Executors/Conditional.hpp>
Expand All @@ -19,10 +20,9 @@ namespace Ark::internal
m_debug(debug)
{
// create executors pipeline
m_executor_pipeline = MacroExecutorPipeline(
{ std::make_shared<SymbolExecutor>(this),
std::make_shared<ConditionalExecutor>(this),
std::make_shared<FunctionExecutor>(this) });
m_executors = { { std::make_shared<SymbolExecutor>(this),
std::make_shared<ConditionalExecutor>(this),
std::make_shared<FunctionExecutor>(this) } };

m_predefined_macros = {
"symcat",
Expand Down Expand Up @@ -205,7 +205,15 @@ namespace Ark::internal
MaxMacroProcessingDepth),
node);

return m_executor_pipeline.applyMacro(node, depth);
for (const auto& executor : m_executors)
{
if (executor->canHandle(node))
{
if (executor->applyMacro(node, depth))
return true;
}
}
return false;
}

void MacroProcessor::unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent, const std::size_t index, const std::size_t unify_depth)
Expand Down Expand Up @@ -251,6 +259,20 @@ namespace Ark::internal
output.setPos(origin.line(), origin.col());
}

void MacroProcessor::checkMacroArgCount(const Node& node, std::size_t expected, const std::string& name, const std::string& kind)
{
const std::size_t argcount = node.constList().size();
if (argcount != expected + 1)
throwMacroProcessingError(
fmt::format(
"Interpreting a `{}'{} with {} arguments, expected {}.",
name,
kind.empty() ? kind : " " + kind,
argcount,
expected),
node);
}

Node MacroProcessor::evaluate(Node& node, unsigned depth, const bool is_not_body)
{
if (node.nodeType() == NodeType::Symbol)
Expand All @@ -262,29 +284,6 @@ namespace Ark::internal
}
if (node.nodeType() == NodeType::List && node.constList().size() > 1 && node.list()[0].nodeType() == NodeType::Symbol)
{
#define GEN_NOT_BODY(str_name, error_handler, ret) \
else if (name == (str_name) && is_not_body) \
{ \
if (node.list().size() != 3) (error_handler); \
Node one = evaluate(node.list()[1], depth + 1, is_not_body), \
two = evaluate(node.list()[2], depth + 1, is_not_body); \
return ret; \
}

#define GEN_COMPARATOR(str_name, cond) GEN_NOT_BODY( \
str_name, \
throwMacroProcessingError( \
fmt::format("Interpreting a `{}' condition with {} arguments, expected 2.", str_name, argcount), \
node), \
(cond) ? getTrueNode() : getFalseNode())

#define GEN_OP(str_name, op) GEN_NOT_BODY( \
str_name, \
throwMacroProcessingError( \
fmt::format("Interpreting a `{}' operation with {} arguments, expected 2.", str_name, argcount), \
node), \
(one.nodeType() == two.nodeType() && two.nodeType() == NodeType::Number) ? Node(one.number() op two.number()) : node)

const std::string& name = node.list()[0].string();
const std::size_t argcount = node.list().size() - 1;
if (const Node* macro = findNearestMacro(name); macro != nullptr)
Expand All @@ -293,21 +292,79 @@ namespace Ark::internal
if (node.list()[0].nodeType() == NodeType::Unused)
node.list().erase(node.constList().begin());
}
GEN_COMPARATOR("=", one == two)
GEN_COMPARATOR("!=", !(one == two))
GEN_COMPARATOR("<", one < two)
GEN_COMPARATOR(">", !(one < two) && !(one == two))
GEN_COMPARATOR("<=", one < two || one == two)
GEN_COMPARATOR(">=", !(one < two))
GEN_OP("+", +)
GEN_OP("-", -)
GEN_OP("*", *)
GEN_OP("/", /)
else if (name == "=" && is_not_body)
{
checkMacroArgCount(node, 2, "=", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one == two) ? getTrueNode() : getFalseNode();
}
else if (name == "!=" && is_not_body)
{
checkMacroArgCount(node, 2, "!=", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one != two) ? getTrueNode() : getFalseNode();
}
else if (name == "<" && is_not_body)
{
checkMacroArgCount(node, 2, "<", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one < two) ? getTrueNode() : getFalseNode();
}
else if (name == ">" && is_not_body)
{
checkMacroArgCount(node, 2, ">", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return !(one < two) && (one != two) ? getTrueNode() : getFalseNode();
}
else if (name == "<=" && is_not_body)
{
checkMacroArgCount(node, 2, "<=", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return one < two || one == two ? getTrueNode() : getFalseNode();
}
else if (name == ">=" && is_not_body)
{
checkMacroArgCount(node, 2, ">=", "condition");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return !(one < two) ? getTrueNode() : getFalseNode();
}
else if (name == "+" && is_not_body)
{
checkMacroArgCount(node, 2, "+", "operator");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one.nodeType() == two.nodeType() && two.nodeType() == NodeType::Number) ? Node(one.number() + two.number()) : node;
}
else if (name == "-" && is_not_body)
{
checkMacroArgCount(node, 2, "-", "operator");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one.nodeType() == two.nodeType() && two.nodeType() == NodeType::Number) ? Node(one.number() - two.number()) : node;
}
else if (name == "*" && is_not_body)
{
checkMacroArgCount(node, 2, "*", "operator");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one.nodeType() == two.nodeType() && two.nodeType() == NodeType::Number) ? Node(one.number() * two.number()) : node;
}
else if (name == "/" && is_not_body)
{
checkMacroArgCount(node, 2, "/", "operator");
const Node one = evaluate(node.list()[1], depth + 1, is_not_body);
const Node two = evaluate(node.list()[2], depth + 1, is_not_body);
return (one.nodeType() == two.nodeType() && two.nodeType() == NodeType::Number) ? Node(one.number() / two.number()) : node;
}
else if (name == "not" && is_not_body)
{
if (node.list().size() != 2)
throwMacroProcessingError(fmt::format("Interpreting a `not' condition with {} arguments, expected 1.", argcount), node);

checkMacroArgCount(node, 1, "not", "condition");
return (!isTruthy(evaluate(node.list()[1], depth + 1, is_not_body))) ? getTrueNode() : getFalseNode();
}
else if (name == "and" && is_not_body)
Expand Down Expand Up @@ -351,8 +408,7 @@ namespace Ark::internal
}
else if (name == "@")
{
if (node.list().size() != 3)
throwMacroProcessingError(fmt::format("Interpreting a `@' with {} arguments, expected 2.", argcount), node);
checkMacroArgCount(node, 2, "@");

Node sublist = evaluate(node.list()[1], depth + 1, is_not_body);
const Node idx = evaluate(node.list()[2], depth + 1, is_not_body);
Expand Down

0 comments on commit 853612e

Please sign in to comment.