Skip to content

Commit

Permalink
fix: handling all conversions inside the code so that it doesn't thro…
Browse files Browse the repository at this point in the history
…w any warnings
  • Loading branch information
SuperFola committed Jul 12, 2024
1 parent 18c3a97 commit 3a5cbaf
Show file tree
Hide file tree
Showing 26 changed files with 278 additions and 235 deletions.
13 changes: 7 additions & 6 deletions include/Ark/Compiler/AST/Optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* @file Optimizer.hpp
* @author Alexandre Plateau ([email protected])
* @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
*
*/

Expand All @@ -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
Expand All @@ -51,7 +52,7 @@ namespace Ark::internal

private:
Node m_ast;
uint16_t m_options;
unsigned m_debug;
std::unordered_map<std::string, unsigned> m_sym_appearances;

/**
Expand All @@ -74,7 +75,7 @@ namespace Ark::internal
* @param node
* @param func
*/
void runOnGlobalScopeVars(Node& node, const std::function<void(Node&, Node&, int)>& func);
void runOnGlobalScopeVars(Node& node, const std::function<void(Node&, Node&, std::size_t)>& func);

/**
* @brief Count the occurrences of each symbol in the AST, recursively
Expand Down
46 changes: 26 additions & 20 deletions include/Ark/Compiler/Compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<internal::Node> m_symbols;
std::vector<std::string> m_defined_symbols;
Expand All @@ -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<internal::Word>&
*/
std::vector<internal::Word>& page(const int i) noexcept
std::vector<internal::Word>& 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<internal::Word>*
*/
std::vector<internal::Word>* page_ptr(const int i) noexcept
std::vector<internal::Word>* 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];
}

/**
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions include/Ark/Files.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file Files.hpp
* @author Alexandre Plateau ([email protected])
* @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
*
Expand Down Expand Up @@ -62,16 +62,16 @@ namespace Ark::Utils
if (!ifs.good())
return std::vector<uint8_t> {};

const std::size_t pos = ifs.tellg();
const auto pos = ifs.tellg();
// reserve appropriate number of bytes
std::vector<char> temp(pos);
std::vector<char> temp(static_cast<std::size_t>(pos));
ifs.seekg(0, std::ios::beg);
ifs.read(&temp[0], pos);
ifs.close();

auto bytecode = std::vector<uint8_t>(pos);
auto bytecode = std::vector<uint8_t>(static_cast<std::size_t>(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<std::size_t>(pos); ++i)
bytecode[i] = static_cast<uint8_t>(temp[i]);
return bytecode;
}
Expand Down
8 changes: 4 additions & 4 deletions include/Ark/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file Utils.hpp
* @author Alexandre Plateau ([email protected])
* @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
*
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion include/Ark/VM/ExecutionContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/Ark/VM/Plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#if defined(ARK_OS_WINDOWS)
// do not include winsock.h
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <Windows.h>
#elif defined(ARK_OS_LINUX)
# include <dlfcn.h>
Expand Down
5 changes: 3 additions & 2 deletions include/Ark/VM/VM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <array>
#include <vector>
#include <string>
#include <utility>
#include <cinttypes>
#include <unordered_map>
#include <algorithm>
Expand Down Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion include/Ark/VM/Value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
65 changes: 29 additions & 36 deletions include/Ark/VM/inline/VM.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint16_t>(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<uint16_t>::max()))
{
if (!var->isFunction())
throwVMError(ErrorKind::Type, "Can't call '" + name + "': it isn't a Function but a " + types_to_str[static_cast<std::size_t>(var->valueType())]);
const uint16_t id = static_cast<uint16_t>(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<std::size_t>(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
Expand Down Expand Up @@ -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
Expand All @@ -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<int16_t>(sizeof...(Args)));
call(context, static_cast<uint16_t>(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)
Expand All @@ -90,10 +93,10 @@ Value VM::resolve(const Value* val, Args&&... args)

inline Value VM::resolve(internal::ExecutionContext* context, std::vector<Value>& 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<std::size_t>(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
Expand All @@ -103,7 +106,7 @@ inline Value VM::resolve(internal::ExecutionContext* context, std::vector<Value>

const std::size_t frames_count = context->fc;
// call it
call(*context, static_cast<int16_t>(n.size() - 1));
call(*context, static_cast<uint16_t>(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)
Expand Down Expand Up @@ -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<int16_t>(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<std::size_t>(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<std::size_t>(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<std::size_t>(context.sp - x + 1)],
context.stack[static_cast<std::size_t>(first + x)]);
++x;
}
context.stack[first + 0] = Value(static_cast<PageAddr_t>(context.pp));
context.stack[first + 1] = Value(ValueType::InstPtr, static_cast<PageAddr_t>(context.ip));
context.stack[static_cast<std::size_t>(first + 0)] = Value(static_cast<PageAddr_t>(context.pp));
context.stack[static_cast<std::size_t>(first + 1)] = Value(ValueType::InstPtr, static_cast<PageAddr_t>(context.ip));
context.sp += 2;
break;
}
Expand Down Expand Up @@ -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
Expand All @@ -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<uint16_t>(m_state.m_pages[context.pp][context.ip]) << 8) + static_cast<uint16_t>(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);

Expand Down
2 changes: 1 addition & 1 deletion include/CLI/REPL/Repl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::filesystem::path> m_lib_env;
State m_state;
VM m_vm;
Expand Down
Loading

0 comments on commit 3a5cbaf

Please sign in to comment.