9# pragma warning(disable : 4996)
18 State::State(uint16_t options,
const std::vector<std::string>& libenv) noexcept :
23 if (libenv.size() > 0)
29 const char* arkpath = getenv(
"ARKSCRIPT_PATH");
36 if (m_debug_level >= 1)
37 std::cout << termcolor::yellow <<
"Warning" << termcolor::reset <<
" no std library was found and ARKSCRIPT_PATH was not supplied" << std::endl;
48 bcr.
feed(bytecode_filename);
53 catch (
const std::exception& e)
56 std::printf(
"%s\n", e.what());
70 catch (
const std::exception& e)
73 std::printf(
"%s\n", e.what());
93 compiler.
saveTo(file.substr(0, file.find_last_of(
'.')) +
".arkc");
95 catch (
const std::exception& e)
97 std::printf(
"%s\n", e.what());
102 std::printf(
"Unknown lexer-parser-or-compiler error (%s)\n", file.c_str());
113 std::cerr << termcolor::red <<
"Can not find file '" << file <<
"'\n"
125 catch (
const std::exception& e)
127 std::printf(
"%s\n", e.what());
135 std::string filename = short_filename.substr(0, short_filename.find_last_of(
'.')) +
".arkc";
136 std::filesystem::path directory = (std::filesystem::path(file)).parent_path() /
ARK_CACHE_DIRNAME;
137 std::string path = (directory / filename).
string();
139 if (!std::filesystem::exists(directory))
140 std::filesystem::create_directory(directory);
142 bool compiled_successfuly =
compile(file, path);
143 if (compiled_successfuly &&
feed(path))
162 catch (
const std::exception& e)
164 std::printf(
"%s\n", e.what());
169 std::printf(
"Unknown lexer-parser-or-compiler error\n");
178 m_binded[name] =
Value(std::move(function));
184 for (
const std::string& arg : args)
186 m_binded[
"sys:args"] = val;
193 m_debug_level = level;
203 using namespace internal;
208 auto readNumber = [&,
this](std::size_t& i) -> uint16_t {
209 uint16_t x = (
static_cast<uint16_t
>(
m_bytecode[i]) << 8);
211 uint16_t y =
static_cast<uint16_t
>(
m_bytecode[i]);
221 uint16_t major = readNumber(i);
223 uint16_t minor = readNumber(i);
225 uint16_t patch = readNumber(i);
230 std::string str_version = std::to_string(major) +
"." +
231 std::to_string(minor) +
"." +
232 std::to_string(patch);
236 using timestamp_t =
unsigned long long;
237 timestamp_t timestamp [[maybe_unused]] = 0;
238 auto aa = (
static_cast<timestamp_t
>(
m_bytecode[i]) << 56),
239 ba = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 48),
240 ca = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 40),
241 da = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 32),
242 ea = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 24),
243 fa = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 16),
244 ga = (
static_cast<timestamp_t
>(
m_bytecode[++i]) << 8),
245 ha = (
static_cast<timestamp_t
>(
m_bytecode[++i]));
247 timestamp = aa + ba + ca + da + ea + fa + ga + ha;
249 std::vector<unsigned char> hash(picosha2::k_digest_size);
252 for (std::size_t j = 0; j < picosha2::k_digest_size; ++j)
254#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
261 if (
m_bytecode[i] == Instruction::SYM_TABLE_START)
264 uint16_t size = readNumber(i);
268 for (uint16_t j = 0; j < size; ++j)
270 std::string symbol =
"";
281 if (
m_bytecode[i] == Instruction::VAL_TABLE_START)
284 uint16_t size = readNumber(i);
288 for (uint16_t j = 0; j < size; ++j)
293 if (type == Instruction::NUMBER_TYPE)
295 std::string val =
"";
302 else if (type == Instruction::STRING_TYPE)
304 std::string val =
"";
311 else if (type == Instruction::FUNC_TYPE)
313 uint16_t addr = readNumber(i);
325 while (
m_bytecode[i] == Instruction::CODE_SEGMENT_START)
328 uint16_t size = readNumber(i);
334 for (uint16_t j = 0; j < size; ++j)
Constants used by ArkScript.
#define ARK_PLATFORM_NAME
constexpr int ARK_VERSION_MAJOR
constexpr char ARK_VERSION_STR[4]
#define ARK_CACHE_DIRNAME
Lots of utilities about the filesystem.
State used by the virtual machine: it loads the bytecode, can compile it if needed,...
Lots of utilities about string, filesystem and more.
This class is just a helper to.
const bytecode_t & bytecode() noexcept
Return the bytecode object constructed.
unsigned long long timestamp()
Return the read timestamp from the bytecode file.
void feed(const std::string &file)
Construct needed data before displaying information about a given file.
The ArkScript bytecode compiler.
std::vector< std::string > m_defined_symbols
const bytecode_t & bytecode() noexcept
Return the constructed bytecode object.
void compile()
Start the compilation.
void feed(const std::string &code, const std::string &filename=ARK_NO_NAME_FILE)
Feed the differents variables with information taken from the given source code file.
void saveTo(const std::string &file)
Save generated bytecode to a file.
void configure()
Called to configure the state (set the bytecode, debug level, call the compiler......
State(uint16_t options=DefaultFeatures, const std::vector< std::string > &libpath={}) noexcept
Construct a new State object.
std::vector< Value > m_constants
void throwStateError(const std::string &message)
bool feed(const std::string &bytecode_filename)
Feed the state by giving it the path to an existing bytecode file.
void setLibDirs(const std::vector< std::string > &libenv) noexcept
Set the std search paths.
void reset() noexcept
Reset State (all member variables related to execution)
std::unordered_map< std::string, Value > m_binded
std::vector< std::string > m_symbols
void setArgs(const std::vector< std::string > &args) noexcept
Set the script arguments in sys:args.
std::vector< bytecode_t > m_pages
void loadFunction(const std::string &name, Value::ProcType function) noexcept
Register a function in the virtual machine.
bool compile(const std::string &file, const std::string &output)
Reads and compiles code of file.
void setDebug(unsigned level) noexcept
Set the debug level.
bool doFile(const std::string &filename)
Compile a file, and use the resulting bytecode.
bool doString(const std::string &code)
Compile a string (representing ArkScript code) and store resulting bytecode in m_bytecode.
std::vector< std::string > m_libenv
Value(*)(std::vector< Value > &, VM *) ProcType
void push_back(const Value &value)
Add an element to the list held by the value (if the value type is set to list)
std::string readFile(const std::string &name)
Helper to read a file.
bool fileExists(const std::string &name) noexcept
Checks if a file exists.
std::vector< std::string > splitString(const std::string &source, char sep)
Cut a string into pieces, given a character separator.
std::string canonicalRelPath(const std::string &path)
Get the canonical relative path from a path.
std::string getFilenameFromPath(const std::string &path)
Get the filename from a path.
std::vector< uint8_t > bytecode_t