diff --git a/include/Ark/Compiler/AST/Optimizer.hpp b/include/Ark/Compiler/AST/Optimizer.hpp index 2ca5cb3fe..de3b3da7d 100644 --- a/include/Ark/Compiler/AST/Optimizer.hpp +++ b/include/Ark/Compiler/AST/Optimizer.hpp @@ -2,10 +2,10 @@ * @file Optimizer.hpp * @author Alexandre Plateau (lexplt.dev@gmail.com) * @brief Optimizes a given ArkScript AST - * @version 0.4 - * @date 2020-10-27 + * @version 1.0 + * @date 2024-07-09 * - * @copyright Copyright (c) 2020-2021 + * @copyright Copyright (c) 2020-2024 * */ @@ -32,8 +32,9 @@ namespace Ark::internal /** * @brief Construct a new Optimizer * + * @param debug level of debug */ - explicit Optimizer(uint16_t options) noexcept; + explicit Optimizer(unsigned debug) noexcept; /** * @brief Send the AST to the optimizer, then run the different optimization strategies on it @@ -51,7 +52,7 @@ namespace Ark::internal private: Node m_ast; - uint16_t m_options; + unsigned m_debug; std::unordered_map m_sym_appearances; /** @@ -74,7 +75,7 @@ namespace Ark::internal * @param node * @param func */ - void runOnGlobalScopeVars(Node& node, const std::function& func); + void runOnGlobalScopeVars(Node& node, const std::function& func); /** * @brief Count the occurrences of each symbol in the AST, recursively diff --git a/include/Ark/Compiler/Compiler.hpp b/include/Ark/Compiler/Compiler.hpp index b6d3bceb6..46ad57cbb 100644 --- a/include/Ark/Compiler/Compiler.hpp +++ b/include/Ark/Compiler/Compiler.hpp @@ -60,6 +60,12 @@ namespace Ark friend class Welder; private: + struct Page + { + std::size_t index; + bool is_temp; + }; + // tables: symbols, values, plugins and codes std::vector m_symbols; std::vector m_defined_symbols; @@ -86,27 +92,27 @@ namespace Ark /** * @brief helper functions to get a temp or finalized code page * - * @param i page index, if negative, refers to a temporary code page + * @param page page descriptor * @return std::vector& */ - std::vector& page(const int i) noexcept + std::vector& page(const Page page) noexcept { - if (i >= 0) - return m_code_pages[i]; - return m_temp_pages[-i - 1]; + if (!page.is_temp) + return m_code_pages[page.index]; + return m_temp_pages[page.index]; } /** * @brief helper functions to get a temp or finalized code page * - * @param i page index, if negative, refers to a temporary code page + * @param page page descriptor * @return std::vector* */ - std::vector* page_ptr(const int i) noexcept + std::vector* page_ptr(const Page page) noexcept { - if (i >= 0) - return &m_code_pages[i]; - return &m_temp_pages[-i - 1]; + if (!page.is_temp) + return &m_code_pages[page.index]; + return &m_temp_pages[page.index]; } /** @@ -210,16 +216,16 @@ namespace Ark * @param is_terminal * @param var_name */ - void compileExpression(const internal::Node& x, int p, bool is_result_unused, bool is_terminal, const std::string& var_name = ""); - - void compileSymbol(const internal::Node& x, int p, bool is_result_unused); - void compileSpecific(const internal::Node& c0, const internal::Node& x, int p, bool is_result_unused); - void compileIf(const internal::Node& x, int p, bool is_result_unused, bool is_terminal, const std::string& var_name); - void compileFunction(const internal::Node& x, int p, bool is_result_unused, const std::string& var_name); - void compileLetMutSet(internal::Keyword n, const internal::Node& x, int p); - void compileWhile(const internal::Node& x, int p); - void compilePluginImport(const internal::Node& x, int p); - void handleCalls(const internal::Node& x, int p, bool is_result_unused, bool is_terminal, const std::string& var_name); + void compileExpression(const internal::Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name = ""); + + void compileSymbol(const internal::Node& x, Page p, bool is_result_unused); + void compileSpecific(const internal::Node& c0, const internal::Node& x, Page p, bool is_result_unused); + void compileIf(const internal::Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name); + void compileFunction(const internal::Node& x, Page p, bool is_result_unused, const std::string& var_name); + void compileLetMutSet(internal::Keyword n, const internal::Node& x, Page p); + void compileWhile(const internal::Node& x, Page p); + void compilePluginImport(const internal::Node& x, Page p); + void handleCalls(const internal::Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name); /** * @brief Register a given node in the symbol table diff --git a/include/Ark/Files.hpp b/include/Ark/Files.hpp index 998d90056..f439e75f6 100644 --- a/include/Ark/Files.hpp +++ b/include/Ark/Files.hpp @@ -2,8 +2,8 @@ * @file Files.hpp * @author Alexandre Plateau (lexplt.dev@gmail.com) * @brief Lots of utilities about the filesystem - * @version 0.2 - * @date 2021-11-25 + * @version 0.3 + * @date 2024-07-09 * * @copyright Copyright (c) 2021-2024 * @@ -62,16 +62,16 @@ namespace Ark::Utils if (!ifs.good()) return std::vector {}; - const std::size_t pos = ifs.tellg(); + const auto pos = ifs.tellg(); // reserve appropriate number of bytes - std::vector temp(pos); + std::vector temp(static_cast(pos)); ifs.seekg(0, std::ios::beg); ifs.read(&temp[0], pos); ifs.close(); - auto bytecode = std::vector(pos); + auto bytecode = std::vector(static_cast(pos)); // TODO would it be faster to memcpy? - for (std::size_t i = 0; i < pos; ++i) + for (std::size_t i = 0; i < static_cast(pos); ++i) bytecode[i] = static_cast(temp[i]); return bytecode; } diff --git a/include/Ark/Utils.hpp b/include/Ark/Utils.hpp index deadf8480..5bdbad43c 100644 --- a/include/Ark/Utils.hpp +++ b/include/Ark/Utils.hpp @@ -2,8 +2,8 @@ * @file Utils.hpp * @author Alexandre Plateau (lexplt.dev@gmail.com) * @brief Lots of utilities about string, filesystem and more - * @version 0.4 - * @date 2020-10-27 + * @version 1.0 + * @date 2024-07-09 * * @copyright Copyright (c) 2020-2024 * @@ -65,9 +65,9 @@ namespace Ark::Utils * * @param str1 * @param str2 - * @return int + * @return std::size_t */ - int levenshteinDistance(const std::string& str1, const std::string& str2); + std::size_t levenshteinDistance(const std::string& str1, const std::string& str2); } #endif diff --git a/include/Ark/VM/ExecutionContext.hpp b/include/Ark/VM/ExecutionContext.hpp index 49232c7b6..fa0ebb3b1 100644 --- a/include/Ark/VM/ExecutionContext.hpp +++ b/include/Ark/VM/ExecutionContext.hpp @@ -32,7 +32,7 @@ namespace Ark::internal static inline unsigned Count = 0; const bool primary; ///< Tells if the current ExecutionContext is the primary one or not - int ip = 0; ///< Instruction pointer + std::size_t ip = 0; ///< Instruction pointer std::size_t pp = 0; ///< Page pointer uint16_t sp = 0; ///< Stack pointer uint16_t fc = 0; ///< Frame count diff --git a/include/Ark/VM/Plugin.hpp b/include/Ark/VM/Plugin.hpp index e4a36c40a..d4ff2911f 100644 --- a/include/Ark/VM/Plugin.hpp +++ b/include/Ark/VM/Plugin.hpp @@ -17,6 +17,7 @@ #if defined(ARK_OS_WINDOWS) // do not include winsock.h # define WIN32_LEAN_AND_MEAN +# define NOMINMAX # include #elif defined(ARK_OS_LINUX) # include diff --git a/include/Ark/VM/VM.hpp b/include/Ark/VM/VM.hpp index 6b0d62c93..ad308f846 100644 --- a/include/Ark/VM/VM.hpp +++ b/include/Ark/VM/VM.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -298,9 +299,9 @@ namespace Ark * @brief Function called when the CALL instruction is met in the bytecode * * @param context - * @param argc_ number of arguments already sent, default to -1 if it needs to search for them by itself + * @param argc number of arguments already sent */ - inline void call(internal::ExecutionContext& context, int16_t argc_ = -1); + inline void call(internal::ExecutionContext& context, uint16_t argc); }; #include "inline/VM.inl" diff --git a/include/Ark/VM/Value.hpp b/include/Ark/VM/Value.hpp index 552ee568f..d453c1b37 100644 --- a/include/Ark/VM/Value.hpp +++ b/include/Ark/VM/Value.hpp @@ -209,7 +209,7 @@ namespace Ark return A.constList().empty(); case ValueType::Number: - return !A.number(); + return A.number() == 0.0; case ValueType::String: return A.string().empty(); diff --git a/include/Ark/VM/inline/VM.inl b/include/Ark/VM/inline/VM.inl index 4abb30693..0bd564d49 100644 --- a/include/Ark/VM/inline/VM.inl +++ b/include/Ark/VM/inline/VM.inl @@ -20,18 +20,21 @@ Value VM::call(const std::string& name, Args&&... args) push(*it2, context); // find function object and push it if it's a pageaddr/closure - const uint16_t id = static_cast(std::distance(m_state.m_symbols.begin(), it)); - Value* var = findNearestVariable(id, context); - if (var != nullptr) + if (const auto dist = std::distance(m_state.m_symbols.begin(), it); std::cmp_less(dist, std::numeric_limits::max())) { - if (!var->isFunction()) - throwVMError(ErrorKind::Type, "Can't call '" + name + "': it isn't a Function but a " + types_to_str[static_cast(var->valueType())]); + const uint16_t id = static_cast(dist); + Value* var = findNearestVariable(id, context); + if (var != nullptr) + { + if (!var->isFunction()) + throwVMError(ErrorKind::Type, "Can't call '" + name + "': it isn't a Function but a " + types_to_str[static_cast(var->valueType())]); - push(Value(var), context); - context.last_symbol = id; + push(Value(var), context); + context.last_symbol = id; + } + else + throwVMError(ErrorKind::Scope, "Couldn't find variable " + name); } - else - throwVMError(ErrorKind::Scope, "Couldn't find variable " + name); const std::size_t frames_count = context.fc; // call it @@ -59,7 +62,7 @@ Value VM::resolve(const Value* val, Args&&... args) if (!val->isFunction()) throw TypeError("Value::resolve couldn't resolve a non-function"); - const int ip = context.ip; + const std::size_t ip = context.ip; const std::size_t pp = context.pp; // convert and push arguments in reverse order @@ -71,7 +74,7 @@ Value VM::resolve(const Value* val, Args&&... args) const std::size_t frames_count = context.fc; // call it - call(context, static_cast(sizeof...(Args))); + call(context, static_cast(sizeof...(Args))); // reset instruction pointer, otherwise the safeRun method will start at ip = -1 // without doing context.ip++ as intended (done right after the call() in the loop, but here // we start outside this loop) @@ -90,10 +93,10 @@ Value VM::resolve(const Value* val, Args&&... args) inline Value VM::resolve(internal::ExecutionContext* context, std::vector& n) { - if (!n[0].isFunction()) + if (!n[0].isFunction()) // TODO use fmt throw TypeError("VM::resolve couldn't resolve a non-function (" + types_to_str[static_cast(n[0].valueType())] + ")"); - const int ip = context->ip; + const std::size_t ip = context->ip; const std::size_t pp = context->pp; // convert and push arguments in reverse order @@ -103,7 +106,7 @@ inline Value VM::resolve(internal::ExecutionContext* context, std::vector const std::size_t frames_count = context->fc; // call it - call(*context, static_cast(n.size() - 1)); + call(*context, static_cast(n.size() - 1)); // reset instruction pointer, otherwise the safeRun method will start at ip = -1 // without doing context.ip++ as intended (done right after the call() in the loop, but here // we start outside this loop) @@ -190,22 +193,24 @@ inline void VM::swapStackForFunCall(const uint16_t argc, internal::ExecutionCont default: // 2 or more elements { - const int16_t first = context.sp - argc; + const auto first = static_cast(context.sp - argc); // move first argument to the very end - context.stack[context.sp + 1] = context.stack[first + 0]; + context.stack[context.sp + 1] = context.stack[static_cast(first + 0)]; // move second argument right before the last one - context.stack[context.sp + 0] = context.stack[first + 1]; + context.stack[context.sp + 0] = context.stack[static_cast(first + 1)]; // move the rest, if any - int16_t x = 2; - const int16_t stop = ((argc % 2 == 0) ? argc : (argc - 1)) / 2; + uint16_t x = 2; + const uint16_t stop = ((argc % 2 == 0) ? argc : (argc - 1)) / 2; while (x <= stop) { - // destination , origin - std::swap(context.stack[context.sp - x + 1], context.stack[first + x]); + // destination, origin + std::swap( + context.stack[static_cast(context.sp - x + 1)], + context.stack[static_cast(first + x)]); ++x; } - context.stack[first + 0] = Value(static_cast(context.pp)); - context.stack[first + 1] = Value(ValueType::InstPtr, static_cast(context.ip)); + context.stack[static_cast(first + 0)] = Value(static_cast(context.pp)); + context.stack[static_cast(first + 1)] = Value(ValueType::InstPtr, static_cast(context.ip)); context.sp += 2; break; } @@ -234,7 +239,7 @@ inline void VM::returnFromFuncCall(internal::ExecutionContext& context) context.locals.pop_back(); } -inline void VM::call(internal::ExecutionContext& context, const int16_t argc_) +inline void VM::call(internal::ExecutionContext& context, const uint16_t argc) { /* Argument: number of arguments when calling the function @@ -245,18 +250,6 @@ inline void VM::call(internal::ExecutionContext& context, const int16_t argc_) */ using namespace internal; - uint16_t argc = 0; - - // handling calls from C++ code - if (argc_ <= -1) [[unlikely]] - { - ++context.ip; - argc = (static_cast(m_state.m_pages[context.pp][context.ip]) << 8) + static_cast(m_state.m_pages[context.pp][context.ip + 1]); - ++context.ip; - } - else - argc = argc_; - Value function = *popAndResolveAsPtr(context); context.stacked_closure_scopes.emplace_back(nullptr); diff --git a/include/CLI/REPL/Repl.hpp b/include/CLI/REPL/Repl.hpp index ad4387604..3edb4e207 100644 --- a/include/CLI/REPL/Repl.hpp +++ b/include/CLI/REPL/Repl.hpp @@ -44,7 +44,7 @@ namespace Ark std::string m_code; bool m_running; - int m_old_ip; + std::size_t m_old_ip; std::vector m_lib_env; State m_state; VM m_vm; diff --git a/include/utf8.hpp b/include/utf8.hpp index 8a7d26b6e..da5072504 100644 --- a/include/utf8.hpp +++ b/include/utf8.hpp @@ -40,7 +40,7 @@ namespace utf8 for (const char* s = input; *s != 0; ++s) { - codepoint_ = ((codepoint_ << shift) | details::ASCIIHexToInt[*s]); + codepoint_ = ((codepoint_ << shift) | details::ASCIIHexToInt[static_cast(*s)]); shift = 4; } @@ -68,10 +68,10 @@ namespace utf8 { int32_t cdp = 0; const Utf8Type type = utf8type(input, &cdp); - const char c0 = details::ASCIIHexToInt[input[0]]; - const char c1 = details::ASCIIHexToInt[input[1]]; - const char c2 = details::ASCIIHexToInt[input[2]]; - const char c3 = details::ASCIIHexToInt[input[3]]; + const char c0 = details::ASCIIHexToInt[static_cast(input[0])]; + const char c1 = details::ASCIIHexToInt[static_cast(input[1])]; + const char c2 = details::ASCIIHexToInt[static_cast(input[2])]; + const char c3 = details::ASCIIHexToInt[static_cast(input[3])]; switch (type) { @@ -84,41 +84,41 @@ namespace utf8 case Utf8Type::LatinExtra: { - dest[0] = (0xc0 | ((c1 & 0x7) << 2)) | ((c2 & 0xc) >> 2); - dest[1] = (0x80 | ((c2 & 0x3) << 4)) | c3; + dest[0] = static_cast((0xc0 | ((c1 & 0x7) << 2)) | ((c2 & 0xc) >> 2)); + dest[1] = static_cast((0x80 | ((c2 & 0x3) << 4)) | c3); dest[2] = 0; break; } case Utf8Type::BasicMultiLingual: { - dest[0] = 0xe0 | c0; - dest[1] = (0x80 | (c1 << 2)) | ((c2 & 0xc) >> 2); - dest[2] = (0x80 | ((c2 & 0x3) << 4)) | c3; + dest[0] = static_cast(0xe0 | c0); + dest[1] = static_cast((0x80 | (c1 << 2)) | ((c2 & 0xc) >> 2)); + dest[2] = static_cast((0x80 | ((c2 & 0x3) << 4)) | c3); dest[3] = 0; break; } case Utf8Type::OthersPlanesUnicode: { - const char c4 = details::ASCIIHexToInt[input[4]]; + const char c4 = details::ASCIIHexToInt[static_cast(input[4])]; if (cdp <= 0xfffff) { - dest[0] = 0xf0 | ((c0 & 0xc) >> 2); - dest[1] = (0x80 | ((c0 & 0x3) << 4)) | c1; - dest[2] = (0x80 | (c2 << 2)) | ((c3 & 0xc) >> 2); - dest[3] = (0x80 | ((c3 & 0x3) << 4)) | c4; + dest[0] = static_cast(0xf0 | ((c0 & 0xc) >> 2)); + dest[1] = static_cast((0x80 | ((c0 & 0x3) << 4)) | c1); + dest[2] = static_cast((0x80 | (c2 << 2)) | ((c3 & 0xc) >> 2)); + dest[3] = static_cast((0x80 | ((c3 & 0x3) << 4)) | c4); dest[4] = 0; } else { - const char c5 = details::ASCIIHexToInt[input[5]]; + const char c5 = details::ASCIIHexToInt[static_cast(input[5])]; - dest[0] = (0xf0 | ((c0 & 0x1) << 2)) | ((c1 & 0xc) >> 2); - dest[1] = ((0x80 | ((c1 & 0x3) << 4)) | ((c1 & 0xc) >> 2)) | c2; - dest[2] = (0x80 | (c3 << 2)) | ((c4 & 0xc) >> 2); - dest[3] = (0x80 | ((c4 & 0x3) << 4)) | c5; + dest[0] = static_cast((0xf0 | ((c0 & 0x1) << 2)) | ((c1 & 0xc) >> 2)); + dest[1] = static_cast(((0x80 | ((c1 & 0x3) << 4)) | ((c1 & 0xc) >> 2)) | c2); + dest[2] = static_cast((0x80 | (c3 << 2)) | ((c4 & 0xc) >> 2)); + dest[3] = static_cast((0x80 | ((c4 & 0x3) << 4)) | c5); dest[4] = 0; } break; @@ -234,36 +234,36 @@ namespace utf8 { if (codepoint >= 0x0000 && codepoint <= 0x007f) { - dest[0] = codepoint; + dest[0] = static_cast(codepoint); dest[1] = 0; } else if (codepoint > 0x007f && codepoint <= 0x07ff) { - dest[0] = 0x80; + dest[0] = -128; if (codepoint > 0xff) - dest[0] |= (codepoint >> 6); - dest[0] |= ((codepoint & 0xc0) >> 6); - dest[1] = 0x80 | (codepoint & 0x3f); + dest[0] |= static_cast((codepoint >> 6)); + dest[0] |= static_cast(((codepoint & 0xc0) >> 6)); + dest[1] = static_cast(0x80 | (codepoint & 0x3f)); dest[2] = 0; } else if (codepoint > 0x07ff && codepoint <= 0xffff) { - dest[0] = 0xe0; + dest[0] = -32; if (codepoint > 0xfff) - dest[0] |= ((codepoint & 0xf000) >> 12); - dest[1] = (0x80 | ((codepoint & 0xf00) >> 6)) | ((codepoint & 0xf0) >> 6); - dest[2] = (0x80 | (codepoint & 0x30)) | (codepoint & 0xf); + dest[0] |= static_cast(((codepoint & 0xf000) >> 12)); + dest[1] = static_cast((0x80 | ((codepoint & 0xf00) >> 6)) | ((codepoint & 0xf0) >> 6)); + dest[2] = static_cast((0x80 | (codepoint & 0x30)) | (codepoint & 0xf)); dest[3] = 0; } else if (codepoint > 0xffff && codepoint <= 0x10ffff) { - dest[0] = 0xf0; + dest[0] = -16; if (codepoint > 0xfffff) - dest[0] |= ((codepoint & 0x100000) >> 18); - dest[0] |= ((codepoint & 0xc0000) >> 18); - dest[1] = (0x80 | ((codepoint & 0x30000) >> 12)) | ((codepoint & 0xf000) >> 12); - dest[2] = (0x80 | ((codepoint & 0xf00) >> 6)) | ((codepoint & 0xc0) >> 6); - dest[3] = (0x80 | (codepoint & 0x30)) | (codepoint & 0xf); + dest[0] |= static_cast(((codepoint & 0x100000) >> 18)); + dest[0] |= static_cast(((codepoint & 0xc0000) >> 18)); + dest[1] = static_cast((0x80 | ((codepoint & 0x30000) >> 12)) | ((codepoint & 0xf000) >> 12)); + dest[2] = static_cast((0x80 | ((codepoint & 0xf00) >> 6)) | ((codepoint & 0xc0) >> 6)); + dest[3] = static_cast((0x80 | (codepoint & 0x30)) | (codepoint & 0xf)); dest[4] = 0; } else diff --git a/src/arkreactor/Builtins/List.cpp b/src/arkreactor/Builtins/List.cpp index 162ac3ef5..ae12cfecf 100644 --- a/src/arkreactor/Builtins/List.cpp +++ b/src/arkreactor/Builtins/List.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -54,7 +54,7 @@ namespace Ark::internal::Builtins::List std::vector& l = n[0].list(); for (auto it = l.begin(), it_end = l.end(); it != it_end; ++it) { - if (*it == n[1]) + if (*it == n[1]) // FIXME cast return Value(static_cast(std::distance(l.begin(), it))); } @@ -96,11 +96,11 @@ namespace Ark::internal::Builtins::List throw std::runtime_error(fmt::format("list:slice: start position ({}) must be less or equal to the end position ({})", start, end)); if (start < 0) throw std::runtime_error(fmt::format("list:slice: start index {} can not be less than 0", start)); - if (static_cast(end) > n[0].list().size()) + if (std::cmp_greater(end, n[0].list().size())) throw std::runtime_error(fmt::format("list:slice: end index {} out of range (length: {})", end, n[0].list().size())); std::vector list; - for (long i = start; i < end; i += step) + for (auto i = static_cast(start); std::cmp_less(i, end); i += static_cast(step)) list.push_back(n[0].list()[i]); return Value(std::move(list)); diff --git a/src/arkreactor/Builtins/String.cpp b/src/arkreactor/Builtins/String.cpp index ec9dae7a2..536694d8d 100644 --- a/src/arkreactor/Builtins/String.cpp +++ b/src/arkreactor/Builtins/String.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -115,10 +116,10 @@ namespace Ark::internal::Builtins::String n); long id = static_cast(n[1].number()); - if (id < 0 || static_cast(id) >= n[0].stringRef().size()) + if (id < 0 || std::cmp_greater_equal(id, n[0].stringRef().size())) throw std::runtime_error(fmt::format("str:removeAt: index {} out of range (length: {})", id, n[0].stringRef().size())); - n[0].stringRef().erase(id, 1); + n[0].stringRef().erase(static_cast(id), 1); return n[0]; } diff --git a/src/arkreactor/Builtins/System.cpp b/src/arkreactor/Builtins/System.cpp index 3ae5ab099..cf03bea2a 100644 --- a/src/arkreactor/Builtins/System.cpp +++ b/src/arkreactor/Builtins/System.cpp @@ -19,6 +19,17 @@ namespace Ark::internal::Builtins::System { + namespace + { + struct close_file_deleter + { + int operator()(FILE* file) const noexcept + { + return pclose(file); + } + }; + } + /** * @name sys:exec * @brief Execute a system specific command @@ -40,7 +51,7 @@ namespace Ark::internal::Builtins::System #ifdef ARK_ENABLE_SYSTEM std::array buffer; std::string result; - std::unique_ptr pipe(popen(n[0].string().c_str(), "r"), pclose); + std::unique_ptr pipe(popen(n[0].string().c_str(), "r"), close_file_deleter()); if (!pipe) throw std::runtime_error("sys:exec: couldn't retrieve command output"); while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) diff --git a/src/arkreactor/Compiler/AST/BaseParser.cpp b/src/arkreactor/Compiler/AST/BaseParser.cpp index d639f42ae..8a17cc931 100644 --- a/src/arkreactor/Compiler/AST/BaseParser.cpp +++ b/src/arkreactor/Compiler/AST/BaseParser.cpp @@ -1,6 +1,7 @@ #include #include +#include #include namespace Ark::internal @@ -26,7 +27,9 @@ namespace Ark::internal auto next = i + 1 < end ? m_it_to_row[i + 1].first : m_str.end(); if (current < it && it < next) { - m_it_to_row.insert(m_it_to_row.begin() + i + 1, std::make_pair(it, row)); + m_it_to_row.insert( + m_it_to_row.begin() + static_cast(i) + 1, + std::make_pair(it, row)); break; } } @@ -76,7 +79,7 @@ namespace Ark::internal void BaseParser::backtrack(const long n) { - if (static_cast(n) >= m_str.size()) + if (std::cmp_greater_equal(n, m_str.size())) return; m_it = m_str.begin() + n; @@ -96,7 +99,7 @@ namespace Ark::internal } // compute the position in the line std::string_view view = m_str; - const auto it_pos = std::distance(m_str.begin(), m_it); + const auto it_pos = static_cast(std::distance(m_str.begin(), m_it)); view = view.substr(0, it_pos); const auto nearest_newline_index = view.find_last_of('\n'); if (nearest_newline_index != std::string_view::npos) diff --git a/src/arkreactor/Compiler/AST/Node.cpp b/src/arkreactor/Compiler/AST/Node.cpp index addb98a9b..2dd1f5b61 100644 --- a/src/arkreactor/Compiler/AST/Node.cpp +++ b/src/arkreactor/Compiler/AST/Node.cpp @@ -342,7 +342,7 @@ namespace Ark::internal return A.constList().empty(); case NodeType::Number: - return !A.number(); + return A.number() == 0.0; case NodeType::Capture: [[fallthrough]]; diff --git a/src/arkreactor/Compiler/AST/Optimizer.cpp b/src/arkreactor/Compiler/AST/Optimizer.cpp index 6c2729e00..09639d5f2 100644 --- a/src/arkreactor/Compiler/AST/Optimizer.cpp +++ b/src/arkreactor/Compiler/AST/Optimizer.cpp @@ -1,19 +1,16 @@ -#include #include namespace Ark::internal { - Optimizer::Optimizer(const uint16_t options) noexcept : + Optimizer::Optimizer(const unsigned debug) noexcept : m_ast(), - m_options(options) + m_debug(debug) {} void Optimizer::process(const Node& ast) { m_ast = ast; - - if (m_options & FeatureRemoveUnusedVars) - remove_unused(); + // FIXME activate this remove_unused(); } const Node& Optimizer::ast() const noexcept @@ -38,23 +35,29 @@ namespace Ark::internal countOccurences(m_ast); // logic: remove piece of code with only 1 reference, if they aren't function calls - runOnGlobalScopeVars(m_ast, [this](const Node& node, Node& parent, const int idx) { + runOnGlobalScopeVars(m_ast, [this](const Node& node, Node& parent, const std::size_t idx) { std::string name = node.constList()[1].string(); // a variable was only declared and never used if (m_sym_appearances.contains(name) && m_sym_appearances[name] == 1 && parent.list()[idx].list()[2].nodeType() != NodeType::List) - parent.list().erase(parent.list().begin() + idx); // erase the node from the list + { + if (m_debug > 1) + std::cout << "Removing unused variable '" << name << "'" << std::endl; + // erase the node from the list + parent.list().erase(parent.list().begin() + static_cast::difference_type>(idx)); + } }); } - void Optimizer::runOnGlobalScopeVars(Node& node, const std::function& func) + void Optimizer::runOnGlobalScopeVars(Node& node, const std::function& func) { - int i = static_cast(node.constList().size()); + auto i = node.constList().size(); // iterate only on the first level, using reverse iterators to avoid copy-delete-move to nowhere for (auto it = node.list().rbegin(); it != node.list().rend(); ++it) { i--; - if (!it->constList().empty() && it->constList()[0].nodeType() == NodeType::Keyword) + if (it->nodeType() == NodeType::List && !it->constList().empty() && + it->constList()[0].nodeType() == NodeType::Keyword) { Keyword kw = it->constList()[0].keyword(); diff --git a/src/arkreactor/Compiler/BytecodeReader.cpp b/src/arkreactor/Compiler/BytecodeReader.cpp index 7f4ad150f..a54e07e99 100644 --- a/src/arkreactor/Compiler/BytecodeReader.cpp +++ b/src/arkreactor/Compiler/BytecodeReader.cpp @@ -23,15 +23,15 @@ namespace Ark if (!ifs.good()) throw std::runtime_error(fmt::format("[BytecodeReader] Couldn't open file '{}'", file)); - const std::size_t pos = ifs.tellg(); + const auto pos = ifs.tellg(); // reserve appropriate number of bytes - std::vector temp(pos); + std::vector temp(static_cast(pos)); ifs.seekg(0, std::ios::beg); ifs.read(&temp[0], pos); ifs.close(); - m_bytecode = bytecode_t(pos); - for (std::size_t i = 0; i < pos; ++i) + m_bytecode = bytecode_t(static_cast(pos)); + for (std::size_t i = 0; i < static_cast(pos); ++i) m_bytecode[i] = static_cast(temp[i]); } @@ -108,7 +108,7 @@ namespace Ark { std::string content; while (m_bytecode[i] != 0) - content += m_bytecode[i++]; + content.push_back(static_cast(m_bytecode[i++])); i++; block.symbols.push_back(content); @@ -143,14 +143,14 @@ namespace Ark { std::string val; while (m_bytecode[i] != 0) - val.push_back(m_bytecode[i++]); + val.push_back(static_cast(m_bytecode[i++])); block.values.emplace_back(std::stod(val)); } else if (type == STRING_TYPE) { std::string val; while (m_bytecode[i] != 0) - val.push_back(m_bytecode[i++]); + val.push_back(static_cast(m_bytecode[i++])); block.values.emplace_back(val); } else if (type == FUNC_TYPE) @@ -489,7 +489,7 @@ namespace Ark uint16_t BytecodeReader::readNumber(std::size_t& i) const { - const uint16_t x = static_cast(m_bytecode[i]) << 8; + const uint16_t x = static_cast(m_bytecode[i] << 8); const uint16_t y = m_bytecode[++i]; return x + y; } diff --git a/src/arkreactor/Compiler/Compiler.cpp b/src/arkreactor/Compiler/Compiler.cpp index 1fa3e2cbc..cfc20cd9c 100644 --- a/src/arkreactor/Compiler/Compiler.cpp +++ b/src/arkreactor/Compiler/Compiler.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -30,7 +31,11 @@ namespace Ark m_code_pages.emplace_back(); // create empty page // gather symbols, values, and start to create code segments - compileExpression(ast, /* current_page */ 0, /* is_result_unused */ false, /* is_terminal */ false); + compileExpression( + ast, + /* current_page */ Page { .index = 0, .is_temp = false }, + /* is_result_unused */ false, + /* is_terminal */ false); // throw an error on undefined symbol uses checkForUndefinedSymbol(); @@ -50,8 +55,8 @@ namespace Ark throw std::overflow_error("Size of page " + std::to_string(i) + " exceeds the maximum size of 2^16 - 1"); m_bytecode.push_back(Instruction::CODE_SEGMENT_START); - m_bytecode.push_back(static_cast((page_size & 0xff00) >> 8)); - m_bytecode.push_back(static_cast(page_size & 0x00ff)); + m_bytecode.push_back(static_cast((page_size & 0xff00) >> 8)); + m_bytecode.push_back(static_cast(page_size & 0x00ff)); for (auto inst : page) { @@ -106,18 +111,18 @@ namespace Ark // push version for (const int n : std::array { ARK_VERSION_MAJOR, ARK_VERSION_MINOR, ARK_VERSION_PATCH }) { - m_bytecode.push_back(static_cast((n & 0xff00) >> 8)); - m_bytecode.push_back(static_cast(n & 0x00ff)); + m_bytecode.push_back(static_cast((n & 0xff00) >> 8)); + m_bytecode.push_back(static_cast(n & 0x00ff)); } // push timestamp - const unsigned long long timestamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); - for (std::size_t i = 0; i < 8; ++i) + const long long timestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + for (long i = 0; i < 8; ++i) { - const unsigned shift = 8 * (7 - i); - uint8_t ts_byte = (timestamp & (0xffULL << shift)) >> shift; + const long shift = 8 * (7 - i); + const auto ts_byte = static_cast((timestamp & (0xffLL << shift)) >> shift); m_bytecode.push_back(ts_byte); } } @@ -125,19 +130,19 @@ namespace Ark void Compiler::pushSymAndValTables() { const std::size_t symbol_size = m_symbols.size(); - if (symbol_size > std::numeric_limits::max()) + if (symbol_size > std::numeric_limits::max()) // TODO use fmt throw std::overflow_error("Too many symbols: " + std::to_string(symbol_size) + ", exceeds the maximum size of 2^16 - 1"); m_bytecode.push_back(SYM_TABLE_START); - m_bytecode.push_back(static_cast((symbol_size & 0xff00) >> 8)); - m_bytecode.push_back(static_cast(symbol_size & 0x00ff)); + m_bytecode.push_back(static_cast((symbol_size & 0xff00) >> 8)); + m_bytecode.push_back(static_cast(symbol_size & 0x00ff)); for (const auto& sym : m_symbols) { // push the string, null terminated std::string s = sym.string(); for (const char i : s) - m_bytecode.push_back(i); + m_bytecode.push_back(static_cast(i)); m_bytecode.push_back(0_u8); } @@ -146,8 +151,8 @@ namespace Ark throw std::overflow_error("Too many values: " + std::to_string(value_size) + ", exceeds the maximum size of 2^16 - 1"); m_bytecode.push_back(VAL_TABLE_START); - m_bytecode.push_back(static_cast((value_size & 0xff00) >> 8)); - m_bytecode.push_back(static_cast(value_size & 0x00ff)); + m_bytecode.push_back(static_cast((value_size & 0xff00) >> 8)); + m_bytecode.push_back(static_cast(value_size & 0x00ff)); for (const ValTableElem& val : m_values) { @@ -157,21 +162,21 @@ namespace Ark const auto n = std::get(val.value); std::string t = std::to_string(n); for (const char i : t) - m_bytecode.push_back(i); + m_bytecode.push_back(static_cast(i)); } else if (val.type == ValTableElemType::String) { m_bytecode.push_back(STRING_TYPE); auto t = std::get(val.value); for (const char i : t) - m_bytecode.push_back(i); + m_bytecode.push_back(static_cast(i)); } else if (val.type == ValTableElemType::PageAddr) { m_bytecode.push_back(FUNC_TYPE); const std::size_t addr = std::get(val.value); - m_bytecode.push_back(static_cast((addr & 0xff00) >> 8)); - m_bytecode.push_back(static_cast(addr & 0x00ff)); + m_bytecode.push_back(static_cast((addr & 0xff00) >> 8)); + m_bytecode.push_back(static_cast(addr & 0x00ff)); } else throw Error("The compiler is trying to put a value in the value table, but the type isn't handled.\nCertainly a logic problem in the compiler source code"); @@ -266,7 +271,7 @@ namespace Ark throw CodeError(message, node.filename(), node.line(), node.col(), node.repr()); } - void Compiler::compileExpression(const Node& x, const int p, const bool is_result_unused, const bool is_terminal, const std::string& var_name) + void Compiler::compileExpression(const Node& x, const Page p, const bool is_result_unused, const bool is_terminal, const std::string& var_name) { // register symbols if (x.nodeType() == NodeType::Symbol) @@ -359,7 +364,7 @@ namespace Ark throwCompilerError("boop", x); // FIXME } - void Compiler::compileSymbol(const Node& x, const int p, const bool is_result_unused) + void Compiler::compileSymbol(const Node& x, const Page p, const bool is_result_unused) { const std::string& name = x.string(); @@ -377,19 +382,21 @@ namespace Ark } } - void Compiler::compileSpecific(const Node& c0, const Node& x, const int p, const bool is_result_unused) + void Compiler::compileSpecific(const Node& c0, const Node& x, const Page p, const bool is_result_unused) { std::string name = c0.string(); Instruction inst = getSpecific(name).value(); // length of at least 1 since we got a symbol name - const uint16_t argc = x.constList().size() - 1; + const auto argc = x.constList().size() - 1u; // error, can not use append/concat/pop (and their in place versions) with a <2 length argument list if (argc < 2 && inst != LIST) throwCompilerError(fmt::format("Can not use {} with less than 2 arguments", name), c0); + if (std::cmp_greater(argc, std::numeric_limits::max())) + throwCompilerError(fmt::format("Too many arguments ({}), exceeds 65'535", argc), x); // compile arguments in reverse order - for (uint16_t i = x.constList().size() - 1; i > 0; --i) + for (std::size_t i = x.constList().size() - 1u; i > 0; --i) { const auto node = x.constList()[i]; if (nodeProducesOutput(node)) @@ -399,7 +406,7 @@ namespace Ark } // put inst and number of arguments - page(p).emplace_back(inst, computeSpecificInstArgc(inst, argc)); + page(p).emplace_back(inst, computeSpecificInstArgc(inst, static_cast(argc))); if (is_result_unused && name.back() != '!') // in-place functions never push a value { @@ -408,7 +415,7 @@ namespace Ark } } - void Compiler::compileIf(const Node& x, const int p, const bool is_result_unused, const bool is_terminal, const std::string& var_name) + void Compiler::compileIf(const Node& x, const Page p, const bool is_result_unused, const bool is_terminal, const std::string& var_name) { // compile condition compileExpression(x.constList()[1], p, false, false); @@ -433,7 +440,7 @@ namespace Ark page(p)[jump_to_end_pos].data = static_cast(page(p).size()); } - void Compiler::compileFunction(const Node& x, const int p, const bool is_result_unused, const std::string& var_name) + void Compiler::compileFunction(const Node& x, const Page p, const bool is_result_unused, const std::string& var_name) { if (const auto args = x.constList()[1]; args.nodeType() != NodeType::List) throwCompilerError(fmt::format("Expected a well formed argument(s) list, got a {}", typeToString(args)), args); @@ -459,9 +466,9 @@ namespace Ark // create new page for function body m_code_pages.emplace_back(); - const std::size_t page_id = m_code_pages.size() - 1; + const Page function_body_page = Page { .index = m_code_pages.size() - 1, .is_temp = false }; // save page_id into the constants table as PageAddr and load the const - page(p).emplace_back(LOAD_CONST, addValue(page_id, x)); + page(p).emplace_back(LOAD_CONST, addValue(function_body_page.index, x)); // pushing arguments from the stack into variables in the new scope for (const auto& node : x.constList()[1].constList()) @@ -469,15 +476,15 @@ namespace Ark if (node.nodeType() == NodeType::Symbol) { addDefinedSymbol(node.string()); - page(page_id).emplace_back(MUT, addSymbol(node)); + page(function_body_page).emplace_back(MUT, addSymbol(node)); } } // push body of the function - compileExpression(x.constList()[2], page_id, false, true, var_name); + compileExpression(x.constList()[2], function_body_page, false, true, var_name); // return last value on the stack - page(page_id).emplace_back(RET); + page(function_body_page).emplace_back(RET); // if the computed function is unused, pop it if (is_result_unused) @@ -487,7 +494,7 @@ namespace Ark } } - void Compiler::compileLetMutSet(const Keyword n, const Node& x, const int p) + void Compiler::compileLetMutSet(const Keyword n, const Node& x, const Page p) { if (const auto sym = x.constList()[1]; sym.nodeType() != NodeType::Symbol) throwCompilerError(fmt::format("Expected a symbol, got a {}", typeToString(sym)), sym); @@ -512,7 +519,7 @@ namespace Ark page(p).emplace_back(STORE, i); } - void Compiler::compileWhile(const Node& x, const int p) + void Compiler::compileWhile(const Node& x, const Page p) { if (x.constList().size() != 3) throwCompilerError("Invalid node ; if it was computed by a macro, check that a node is returned", x); @@ -534,7 +541,7 @@ namespace Ark page(p)[jump_to_end_pos].data = static_cast(page(p).size()); } - void Compiler::compilePluginImport(const Node& x, const int p) + void Compiler::compilePluginImport(const Node& x, const Page p) { std::string path; const Node package_node = x.constList()[1]; @@ -554,10 +561,10 @@ namespace Ark page(p).emplace_back(PLUGIN, id); } - void Compiler::handleCalls(const Node& x, const int p, bool is_result_unused, const bool is_terminal, const std::string& var_name) + void Compiler::handleCalls(const Node& x, const Page p, bool is_result_unused, const bool is_terminal, const std::string& var_name) { m_temp_pages.emplace_back(); - const int proc_page = -static_cast(m_temp_pages.size()); + const Page proc_page = Page { .index = m_temp_pages.size() - 1u, .is_temp = true }; constexpr std::size_t start_index = 1; const auto node = x.constList()[0]; @@ -694,7 +701,7 @@ namespace Ark if (it == m_symbols.end()) { m_symbols.push_back(sym); - it = m_symbols.begin() + m_symbols.size() - 1; + it = m_symbols.begin() + static_cast::difference_type>(m_symbols.size() - 1); } const auto distance = std::distance(m_symbols.begin(), it); @@ -710,7 +717,7 @@ namespace Ark if (it == m_values.end()) { m_values.push_back(v); - it = m_values.begin() + m_values.size() - 1; + it = m_values.begin() + static_cast::difference_type>(m_values.size() - 1); } const auto distance = std::distance(m_values.begin(), it); @@ -726,7 +733,7 @@ namespace Ark if (it == m_values.end()) { m_values.push_back(v); - it = m_values.begin() + m_values.size() - 1; + it = m_values.begin() + static_cast::difference_type>(m_values.size() - 1); } const auto distance = std::distance(m_values.begin(), it); diff --git a/src/arkreactor/Compiler/ImportSolver.cpp b/src/arkreactor/Compiler/ImportSolver.cpp index e55c5fa32..77ed2f3cd 100644 --- a/src/arkreactor/Compiler/ImportSolver.cpp +++ b/src/arkreactor/Compiler/ImportSolver.cpp @@ -111,7 +111,9 @@ namespace Ark::internal for (std::size_t j = 2, end_j = node.constList().size(); j < end_j; ++j) { if (i + j - 1 < x.list().size()) - x.list().insert(x.list().begin() + i + j - 1, node.constList()[j]); + x.list().insert( + x.list().begin() + static_cast::difference_type>(i + j - 1), + node.constList()[j]); else x.list().push_back(node.constList()[j]); } diff --git a/src/arkreactor/Compiler/Macros/Processor.cpp b/src/arkreactor/Compiler/Macros/Processor.cpp index 8cbe8e19c..f1fd7082d 100644 --- a/src/arkreactor/Compiler/Macros/Processor.cpp +++ b/src/arkreactor/Compiler/Macros/Processor.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -156,7 +157,7 @@ namespace Ark::internal if (hadBegin(node.list()[i]) && !had) removeBegin(node, i); else if (node.list()[i].nodeType() == NodeType::Macro || node.list()[i].nodeType() == NodeType::Unused) - node.list().erase(node.constList().begin() + i); + node.list().erase(node.constList().begin() + static_cast::difference_type>(i)); } else // running on non-macros { @@ -169,7 +170,7 @@ namespace Ark::internal if (hadBegin(node.list()[i]) && !had) added_begin = true; else if (node.list()[i].nodeType() == NodeType::Unused) - node.list().erase(node.constList().begin() + i); + node.list().erase(node.constList().begin() + static_cast::difference_type>(i)); if (node.nodeType() == NodeType::List) { @@ -228,8 +229,10 @@ namespace Ark::internal throwMacroProcessingError(fmt::format("Can not unify a {} to a Spread", typeToString(sub_node)), sub_node); for (std::size_t i = 1, end = sub_node.list().size(); i < end; ++i) - parent->list().insert(parent->list().begin() + index + i, sub_node.list()[i]); - parent->list().erase(parent->list().begin() + index); // remove the spread + parent->list().insert( + parent->list().begin() + static_cast::difference_type>(index + i), + sub_node.list()[i]); + parent->list().erase(parent->list().begin() + static_cast::difference_type>(index)); // remove the spread } } @@ -348,8 +351,8 @@ namespace Ark::internal if (sublist.nodeType() == NodeType::List && idx.nodeType() == NodeType::Number) { - const long size = static_cast(sublist.list().size()); - long real_size = size; + const std::size_t size = sublist.list().size(); + std::size_t real_size = size; long num_idx = static_cast(idx.number()); // if the first node is the function call to "list", don't count it @@ -361,10 +364,10 @@ namespace Ark::internal } Node output; - if (num_idx >= 0 && num_idx < size) - output = sublist.list()[num_idx]; - else if (const auto c = size + num_idx; num_idx < 0 && c < size && c >= 0) - output = sublist.list()[c]; + if (num_idx >= 0 && std::cmp_less(num_idx, size)) + output = sublist.list()[static_cast(num_idx)]; + else if (const auto c = static_cast(size) + num_idx; num_idx < 0 && std::cmp_less(c, size) && c >= 0) + output = sublist.list()[static_cast(c)]; else throwMacroProcessingError(fmt::format("Index ({}) out of range (list size: {})", num_idx, real_size), node); @@ -443,7 +446,7 @@ namespace Ark::internal switch (ev.nodeType()) { - case NodeType::Number: + case NodeType::Number: // TODO use fmt sym += std::to_string(static_cast(ev.number())); // we don't want '.' in identifiers break; @@ -573,9 +576,11 @@ namespace Ark::internal const std::size_t previous = i; for (std::size_t block_idx = 1, end = lst.constList().size(); block_idx < end; ++block_idx) - node.list().insert(node.constList().begin() + i + block_idx, lst.list()[block_idx]); + node.list().insert( + node.constList().begin() + static_cast::difference_type>(i + block_idx), + lst.list()[block_idx]); - node.list().erase(node.constList().begin() + previous); + node.list().erase(node.constList().begin() + static_cast::difference_type>(previous)); } } } diff --git a/src/arkreactor/Compiler/Welder.cpp b/src/arkreactor/Compiler/Welder.cpp index 61d9ad354..2e816ad2e 100644 --- a/src/arkreactor/Compiler/Welder.cpp +++ b/src/arkreactor/Compiler/Welder.cpp @@ -57,7 +57,9 @@ namespace Ark return false; std::ofstream output(filename, std::ofstream::binary); - output.write(reinterpret_cast(&m_bytecode[0]), m_bytecode.size() * sizeof(uint8_t)); + output.write( + reinterpret_cast(&m_bytecode[0]), + static_cast(m_bytecode.size() * sizeof(uint8_t))); output.close(); return true; } diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index 066b26f2e..7b89a143a 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -42,28 +42,28 @@ namespace Ark::Diagnostics switch (c) { case '(': - pairing_color_index = std::abs(line_color_context_counts.open_parentheses) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_parentheses)) % pairing_color_size; line_color_context_counts.open_parentheses++; break; case ')': line_color_context_counts.open_parentheses--; - pairing_color_index = std::abs(line_color_context_counts.open_parentheses) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_parentheses)) % pairing_color_size; break; case '[': - pairing_color_index = std::abs(line_color_context_counts.open_square_braces) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_square_braces)) % pairing_color_size; line_color_context_counts.open_square_braces++; break; case ']': line_color_context_counts.open_square_braces--; - pairing_color_index = std::abs(line_color_context_counts.open_square_braces) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_square_braces)) % pairing_color_size; break; case '{': - pairing_color_index = std::abs(line_color_context_counts.open_curly_braces) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_curly_braces)) % pairing_color_size; line_color_context_counts.open_curly_braces++; break; case '}': line_color_context_counts.open_curly_braces--; - pairing_color_index = std::abs(line_color_context_counts.open_curly_braces) % pairing_color_size; + pairing_color_index = static_cast(std::abs(line_color_context_counts.open_curly_braces)) % pairing_color_size; break; default: break; diff --git a/src/arkreactor/Utils.cpp b/src/arkreactor/Utils.cpp index af6a58f18..c06a25959 100644 --- a/src/arkreactor/Utils.cpp +++ b/src/arkreactor/Utils.cpp @@ -2,11 +2,11 @@ namespace Ark::Utils { - int levenshteinDistance(const std::string& str1, const std::string& str2) + std::size_t levenshteinDistance(const std::string& str1, const std::string& str2) { const std::size_t str1_len = str1.size(); const std::size_t str2_len = str2.size(); - std::vector edit_distances(str1_len + 1, std::vector(str2_len + 1, 0)); + std::vector edit_distances(str1_len + 1, std::vector(str2_len + 1, 0)); for (std::size_t i = 0; i < str1_len + 1; i++) edit_distances[i][0] = i; @@ -18,7 +18,7 @@ namespace Ark::Utils { for (std::size_t j = 1; j < str2_len + 1; j++) { - const int indicator = str1[i - 1] == str2[j - 1] ? 0 : 1; + const std::size_t indicator = str1[i - 1] == str2[j - 1] ? 0 : 1; edit_distances[i][j] = std::min({ edit_distances[i - 1][j] + 1, // deletion edit_distances[i][j - 1] + 1, // insertion diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index ddcc52841..5ea94505e 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -76,10 +77,14 @@ namespace Ark return m_no_value; } - const auto id = static_cast(std::distance(m_state.m_symbols.begin(), it)); - Value* var = findNearestVariable(id, context); - if (var != nullptr) - return *var; + const auto dist = std::distance(m_state.m_symbols.begin(), it); + if (std::cmp_less(dist, std::numeric_limits::max())) + { + const auto id = static_cast(dist); + Value* var = findNearestVariable(id, context); + if (var != nullptr) + return *var; + } m_no_value = Builtins::nil; return m_no_value; } @@ -147,7 +152,7 @@ namespace Ark // put it in the global frame, aka the first one auto it = std::ranges::find(m_state.m_symbols, std::string(map[i].name)); if (it != m_state.m_symbols.end()) - (context.locals[0]).push_back(static_cast(std::distance(m_state.m_symbols.begin(), it)), Value(map[i].value)); + context.locals[0].push_back(static_cast(std::distance(m_state.m_symbols.begin(), it)), Value(map[i].value)); ++i; } @@ -234,7 +239,9 @@ namespace Ark // put it in the global frame, aka the first one auto it = std::ranges::find(m_state.m_symbols, std::string(map[i].name)); if (it != m_state.m_symbols.end()) - m_execution_contexts[0]->locals[0].push_back(static_cast(std::distance(m_state.m_symbols.begin(), it)), Value(map[i].value)); + m_execution_contexts[0]->locals[0].push_back( + static_cast(std::distance(m_state.m_symbols.begin(), it)), + Value(map[i].value)); ++i; } @@ -270,7 +277,7 @@ namespace Ark // get current instruction [[maybe_unused]] uint8_t padding = m_state.m_pages[context.pp][context.ip]; uint8_t inst = m_state.m_pages[context.pp][context.ip + 1]; - uint16_t arg = (static_cast(m_state.m_pages[context.pp][context.ip + 2]) << 8) + static_cast(m_state.m_pages[context.pp][context.ip + 3]); + auto arg = static_cast((m_state.m_pages[context.pp][context.ip + 2] << 8) + m_state.m_pages[context.pp][context.ip + 3]); context.ip += 4; switch (inst) @@ -311,7 +318,7 @@ namespace Ark case POP_JUMP_IF_TRUE: { if (*popAndResolveAsPtr(context) == Builtins::trueSym) - context.ip = static_cast(arg) * 4; // instructions are 4 bytes + context.ip = arg * 4; // instructions are 4 bytes break; } @@ -353,13 +360,13 @@ namespace Ark case POP_JUMP_IF_FALSE: { if (*popAndResolveAsPtr(context) == Builtins::falseSym) - context.ip = static_cast(arg) * 4; // instructions are 4 bytes + context.ip = arg * 4; // instructions are 4 bytes break; } case JUMP: { - context.ip = static_cast(arg) * 4; // instructions are 4 bytes + context.ip = arg * 4; // instructions are 4 bytes break; } @@ -477,11 +484,11 @@ namespace Ark fmt::format("`{}' is a {}, not a closure, can not get the field `{}' from it", m_state.m_symbols[context.last_symbol], types_to_str[static_cast(var->valueType())], m_state.m_symbols[arg])); - if (Value* field = (var->refClosure().refScope())[arg]; field != nullptr) + if (Value* field = var->refClosure().refScope()[arg]; field != nullptr) { // check for CALL instruction // doing a +1 on the IP to read the instruction because context.ip is already on the next instruction word (the padding) - if (static_cast(context.ip) + 1 < m_state.m_pages[context.pp].size() && m_state.m_pages[context.pp][context.ip + 1] == CALL) + if (context.ip + 1 < m_state.m_pages[context.pp].size() && m_state.m_pages[context.pp][context.ip + 1] == CALL) push(Value(Closure(var->refClosure().scopePtr(), field->pageAddr())), context); else push(field, context); @@ -519,7 +526,7 @@ namespace Ark { { types::Contract { { types::Typedef("list", ValueType::List) } } } }, { *list }); - const uint16_t size = list->constList().size(); + const auto size = static_cast(list->constList().size()); Value obj { *list }; obj.list().reserve(size + arg); @@ -620,8 +627,8 @@ namespace Ark { list, number }); long idx = static_cast(number.number()); - idx = (idx < 0 ? list.list().size() + idx : idx); - if (static_cast(idx) >= list.list().size()) + idx = idx < 0 ? static_cast(list.list().size()) + idx : idx; + if (std::cmp_greater_equal(idx, list.list().size())) throwVMError( ErrorKind::Index, fmt::format("pop index ({}) out of range (list size: {})", idx, list.list().size())); @@ -645,8 +652,8 @@ namespace Ark { *list, number }); long idx = static_cast(number.number()); - idx = (idx < 0 ? list->list().size() + idx : idx); - if (static_cast(idx) >= list->list().size()) + idx = idx < 0 ? static_cast(list->list().size()) + idx : idx; + if (std::cmp_greater_equal(idx, list->list().size())) throwVMError( ErrorKind::Index, fmt::format("pop! index ({}) out of range (list size: {})", idx, list->list().size())); @@ -935,8 +942,8 @@ namespace Ark if (a.valueType() == ValueType::List) { - if (static_cast(std::abs(idx)) < a.list().size()) - push(a.list()[idx < 0 ? a.list().size() + idx : idx], context); + if (std::cmp_less(std::abs(idx), a.list().size())) + push(a.list()[static_cast(idx < 0 ? static_cast(a.list().size()) + idx : idx)], context); else throwVMError( ErrorKind::Index, @@ -944,8 +951,8 @@ namespace Ark } else if (a.valueType() == ValueType::String) { - if (static_cast(std::abs(idx)) < a.string().size()) - push(Value(std::string(1, a.string()[idx < 0 ? a.string().size() + idx : idx])), context); + if (std::cmp_less(std::abs(idx), a.string().size())) + push(Value(std::string(1, a.string()[static_cast(idx < 0 ? static_cast(a.string().size()) + idx : idx)])), context); else throwVMError( ErrorKind::Index, @@ -1018,8 +1025,8 @@ namespace Ark break; } - auto id = static_cast(std::distance(m_state.m_symbols.begin(), it)); - push((closure->refClosure().refScope())[id] != nullptr ? Builtins::trueSym : Builtins::falseSym, context); + auto id = static_cast(std::distance(m_state.m_symbols.begin(), it)); + push(closure->refClosure().refScope()[id] != nullptr ? Builtins::trueSym : Builtins::falseSym, context); break; } @@ -1095,7 +1102,7 @@ namespace Ark void VM::backtrace(ExecutionContext& context) noexcept { - const int saved_ip = context.ip; + const std::size_t saved_ip = context.ip; const std::size_t saved_pp = context.pp; const uint16_t saved_sp = context.sp; @@ -1162,7 +1169,7 @@ namespace Ark } std::cerr << termcolor::reset - << "At IP: " << (saved_ip != -1 ? saved_ip / 4 : 0) // dividing by 4 because the instructions are actually on 4 bytes + << "At IP: " << (saved_ip / 4) // dividing by 4 because the instructions are actually on 4 bytes << ", PP: " << saved_pp << ", SP: " << saved_sp << "\n"; diff --git a/src/arkscript/REPL/Utils.cpp b/src/arkscript/REPL/Utils.cpp index d12b01556..f6eaa266e 100644 --- a/src/arkscript/REPL/Utils.cpp +++ b/src/arkscript/REPL/Utils.cpp @@ -31,12 +31,12 @@ namespace Ark::internal std::size_t contextLen(const std::string& prefix) { const std::string word_break = " \t\n\r\v\f=+*&^%$#@!,./?<>;`~'\"[]{}()\\|"; - int i = prefix.size() - 1; + long i = static_cast(prefix.size()) - 1; std::size_t count = 0; while (i >= 0) { - if (word_break.find(prefix[i]) != std::string::npos) + if (word_break.find(prefix[static_cast(i)]) != std::string::npos) break; ++count;