dlang-sqlite inital
This commit is contained in:
commit
ce0a6c08e4
160 files changed
+362540
No files matched your search
@@ -0,0 +1,98 @@
|
||||
#ifndef DLANG_LIBS_DEBUG_HPP
|
||||
#define DLANG_LIBS_DEBUG_HPP
|
||||
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeStackDump(DlangVM* vm)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (int i = 0; i < dlang_top(vm); i++)
|
||||
{
|
||||
auto value = vm->stack[i];
|
||||
|
||||
if (value.type == StackValueType::NIL)
|
||||
printf("%i\t%s\n");
|
||||
else if (value.type == StackValueType::Int)
|
||||
printf("%i\t%s\n", i, std::to_string(std::get<double>(value.data)).c_str());
|
||||
else if (value.type == StackValueType::Bool)
|
||||
printf("%i\t%s\n", i, std::get<bool>(value.data) ? "True" : "False");
|
||||
else if (value.type == StackValueType::String)
|
||||
printf("%i\t%s\n", i, std::get<std::string>(value.data).c_str());
|
||||
else if (value.type == StackValueType::Function)
|
||||
{
|
||||
auto func = std::get<std::shared_ptr<DlangFunction>>(value.data);
|
||||
|
||||
if (func->isNative)
|
||||
printf("%i\tfunction\tnative\t0x%llX\n", i, func->nativeFunction);
|
||||
else
|
||||
{
|
||||
printf("%i\tfunction\tnon-native\tlocation: %i\n", i, static_cast<int64_t>(func->bodyAddress));
|
||||
printf("\tParameters:\n");
|
||||
|
||||
for (const auto& param : func->parameters)
|
||||
printf("\t\t%s\n", param.c_str());
|
||||
}
|
||||
}
|
||||
else if (value.type == StackValueType::Table)
|
||||
printf("%i\ttable\t0x%llX\n", i, std::get<std::shared_ptr<DlangTable>>(value.data).get());
|
||||
else
|
||||
printf("%i\tunknown\n", i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void NativeGlobalsDump(DlangVM* vm)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (int i = 0; i < vm->globals.top(); i++)
|
||||
{
|
||||
auto value = vm->globals.Get(i);
|
||||
|
||||
if (value.type == StackValueType::NIL)
|
||||
printf("%i\t%s\n");
|
||||
else if (value.type == StackValueType::Int)
|
||||
printf("%i\t%s\n", i, std::to_string(std::get<double>(value.data)).c_str());
|
||||
else if (value.type == StackValueType::Bool)
|
||||
printf("%i\t%s\n", i, std::get<bool>(value.data) ? "True" : "False");
|
||||
else if (value.type == StackValueType::String)
|
||||
printf("%i\t%s\n", i, std::get<std::string>(value.data).c_str());
|
||||
else if (value.type == StackValueType::Function)
|
||||
{
|
||||
auto func = std::get<std::shared_ptr<DlangFunction>>(value.data);
|
||||
|
||||
if (func->isNative)
|
||||
printf("%i\tfunction\tnative\t0x%llX\n", i, func->nativeFunction);
|
||||
else
|
||||
{
|
||||
printf("%i\tfunction\tnon-native\tlocation: %i\n", i, static_cast<int64_t>(func->bodyAddress));
|
||||
printf("\tParameters:\n");
|
||||
|
||||
for (const auto& param : func->parameters)
|
||||
printf("\t\t%s\n", param.c_str());
|
||||
}
|
||||
}
|
||||
else if (value.type == StackValueType::Table)
|
||||
printf("%i\ttable\t0x%llX\n", i, std::get<std::shared_ptr<DlangTable>>(value.data).get());
|
||||
else
|
||||
printf("%i\tunknown\n", i);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline void openlib_debug(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeStackDump);
|
||||
dlang_setfield(vm, "stackDump");
|
||||
|
||||
dlang_pushcfunction(vm, NativeGlobalsDump);
|
||||
dlang_setfield(vm, "globalsDump");
|
||||
|
||||
dlang_setglobal(vm, "debug");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef DLANG_LIBS_DEV_HPP
|
||||
#define DLANG_LIBS_DEV_HPP
|
||||
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativePrint(DlangVM* vm)
|
||||
{
|
||||
std::stringstream ss;
|
||||
auto argCount = dlang_top(vm);
|
||||
|
||||
std::vector<StackValue> values;
|
||||
for (int i = 0; i < argCount; ++i)
|
||||
values.push_back(dlang_totoken(vm));
|
||||
|
||||
for (auto it = values.rbegin(); it != values.rend(); ++it)
|
||||
{
|
||||
if (it->type == StackValueType::NIL)
|
||||
{
|
||||
printf("nil");
|
||||
}
|
||||
else {
|
||||
std::visit([&ss](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
ss << (arg ? "true" : "false") << " ";
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>) {
|
||||
ss << DoubleToString(arg) << " ";
|
||||
}
|
||||
else {
|
||||
ss << arg << " ";
|
||||
}
|
||||
}, it->data);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << ss.str() << '\n';
|
||||
}
|
||||
|
||||
static void NativeToNumber(DlangVM* vm)
|
||||
{
|
||||
auto content = dlang_tostring(vm);
|
||||
try {
|
||||
dlang_pushnumber(vm, std::stod(content));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
dlang_pushnumber(vm, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void NativeIsNil(DlangVM* vm)
|
||||
{
|
||||
dlang_pushboolean(vm, dlang_isnil(vm));
|
||||
}
|
||||
|
||||
static void NativeIsString(DlangVM* vm)
|
||||
{
|
||||
dlang_pushboolean(vm, dlang_isstring(vm));
|
||||
}
|
||||
|
||||
static void NativeIsNumber(DlangVM* vm)
|
||||
{
|
||||
dlang_pushboolean(vm, dlang_isnumber(vm));
|
||||
}
|
||||
|
||||
static void NativeIsBoolean(DlangVM* vm)
|
||||
{
|
||||
dlang_pushboolean(vm, dlang_isboolean(vm));
|
||||
}
|
||||
|
||||
static void NativeRequire(DlangVM* vm)
|
||||
{
|
||||
auto name = dlang_tostring(vm);
|
||||
|
||||
if (vm->loadedPlugins.Contains(name))
|
||||
{
|
||||
dlang_pushstring(vm, "plugin already loaded!");
|
||||
return;
|
||||
}
|
||||
|
||||
void* rawPtr = pluginManager->GetOrLoadInitFunc("./plugins/" + name);
|
||||
if (rawPtr)
|
||||
{
|
||||
vm->loadedPlugins.push(name);
|
||||
|
||||
using InitFunc = void(*)(DlangVM*);
|
||||
auto init = reinterpret_cast<InitFunc>(rawPtr);
|
||||
init(vm);
|
||||
|
||||
dlang_pushstring(vm, "plugin loaded!");
|
||||
return;
|
||||
}
|
||||
|
||||
dlang_pushstring(vm, "Failed to load plugin!");
|
||||
return;
|
||||
}
|
||||
|
||||
inline void openlib_dev(DlangVM* vm)
|
||||
{
|
||||
dlang_pushcfunction(vm, NativePrint);
|
||||
dlang_setglobal(vm, "print");
|
||||
|
||||
dlang_pushcfunction(vm, NativeToNumber);
|
||||
dlang_setglobal(vm, "tonumber");
|
||||
|
||||
dlang_pushcfunction(vm, NativeIsNil);
|
||||
dlang_setglobal(vm, "isnil");
|
||||
|
||||
dlang_pushcfunction(vm, NativeIsString);
|
||||
dlang_setglobal(vm, "isstring");
|
||||
|
||||
dlang_pushcfunction(vm, NativeIsNumber);
|
||||
dlang_setglobal(vm, "isnumber");
|
||||
|
||||
dlang_pushcfunction(vm, NativeIsBoolean);
|
||||
dlang_setglobal(vm, "isbool");
|
||||
|
||||
dlang_pushcfunction(vm, NativeRequire);
|
||||
dlang_setglobal(vm, "require");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef DLANG_LIBS_IO_HPP
|
||||
#define DLANG_LIBS_IO_HPP
|
||||
|
||||
#include <fstream>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeRead(DlangVM* vm)
|
||||
{
|
||||
bool binary = false;
|
||||
if (dlang_isboolean(vm))
|
||||
binary = dlang_toboolean(vm);
|
||||
std::string path = dlang_tostring(vm);
|
||||
|
||||
std::ifstream stream(path, (binary ? std::ios::binary : std::ios::in));
|
||||
if (!stream.is_open())
|
||||
{
|
||||
dlang_pushstring(vm, "Failed to open file!");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string content(
|
||||
(std::istreambuf_iterator<char>(stream)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
stream.close();
|
||||
|
||||
dlang_pushstring(vm, content);
|
||||
}
|
||||
|
||||
static void NativeWrite(DlangVM* vm)
|
||||
{
|
||||
bool binary = false;
|
||||
if (dlang_isboolean(vm))
|
||||
binary = dlang_toboolean(vm);
|
||||
|
||||
std::string content = dlang_tostring(vm);
|
||||
std::string path = dlang_tostring(vm);
|
||||
|
||||
std::ofstream stream(path, (binary ? std::ios::binary : std::ios::out));
|
||||
if (!stream.is_open())
|
||||
{
|
||||
dlang_pushboolean(vm, false);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.write(reinterpret_cast<const char*>(content.data()), content.size());
|
||||
stream.close();
|
||||
|
||||
dlang_pushboolean(vm, true);
|
||||
}
|
||||
|
||||
static void NativeInput(DlangVM* vm)
|
||||
{
|
||||
if (dlang_isstring(vm))
|
||||
{
|
||||
auto promp = dlang_tostring(vm);
|
||||
printf("%s", promp.c_str());
|
||||
}
|
||||
|
||||
std::string inputLine;
|
||||
if (std::getline(std::cin, inputLine))
|
||||
dlang_pushstring(vm, inputLine);
|
||||
else
|
||||
dlang_pushstring(vm, "");
|
||||
}
|
||||
|
||||
inline void openlib_io(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeRead);
|
||||
dlang_setfield(vm, "read");
|
||||
|
||||
dlang_pushcfunction(vm, NativeWrite);
|
||||
dlang_setfield(vm, "write");
|
||||
|
||||
dlang_pushcfunction(vm, NativeInput);
|
||||
dlang_setfield(vm, "input");
|
||||
|
||||
dlang_setglobal(vm, "io");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef DLANG_LIBS_LIST_HPP
|
||||
#define DLANG_LIBS_LIST_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
void NativeListInsert(DlangVM* vm)
|
||||
{
|
||||
auto newListOrValue = dlang_pop(vm);
|
||||
auto insertList = dlang_tolist(vm);
|
||||
|
||||
if (newListOrValue.type == StackValueType::List)
|
||||
{
|
||||
auto list = std::get<std::shared_ptr<DlangList>>(newListOrValue.data);
|
||||
|
||||
for (const auto& val : list->values)
|
||||
insertList->values.push_back(val);
|
||||
}
|
||||
else if (newListOrValue.type == StackValueType::Int ||
|
||||
newListOrValue.type == StackValueType::Bool ||
|
||||
newListOrValue.type == StackValueType::String)
|
||||
insertList->values.push_back(newListOrValue);
|
||||
|
||||
dlang_push(vm, StackValue(StackValueType::List, insertList));
|
||||
}
|
||||
|
||||
void NativeListRemove(DlangVM* vm)
|
||||
{
|
||||
auto idx = dlang_tonumber(vm);
|
||||
auto list = dlang_tolist(vm);
|
||||
|
||||
list->values.erase(list->values.begin() + idx);
|
||||
|
||||
dlang_push(vm, StackValue(StackValueType::List, list));
|
||||
}
|
||||
|
||||
void NativeListConcat(DlangVM* vm)
|
||||
{
|
||||
std::string seperator = "";
|
||||
if (dlang_isstring(vm))
|
||||
seperator = dlang_tostring(vm);
|
||||
|
||||
auto list = dlang_tolist(vm);
|
||||
|
||||
std::stringstream ss;
|
||||
for (const auto& item : list->values)
|
||||
{
|
||||
switch (item.type)
|
||||
{
|
||||
case StackValueType::Int:
|
||||
ss << std::get<double>(item.data);
|
||||
break;
|
||||
case StackValueType::Bool:
|
||||
ss << std::get<bool>(item.data) ? "True" : "False";
|
||||
break;
|
||||
case StackValueType::String:
|
||||
ss << std::get<std::string>(item.data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!seperator.empty())
|
||||
ss << seperator;
|
||||
}
|
||||
|
||||
dlang_pushstring(vm, ss.str().substr(0, ss.str().size() - seperator.size()));
|
||||
}
|
||||
|
||||
inline void openlib_list(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeListInsert);
|
||||
dlang_setfield(vm, "insert");
|
||||
|
||||
dlang_pushcfunction(vm, NativeListRemove);
|
||||
dlang_setfield(vm, "remove");
|
||||
|
||||
dlang_pushcfunction(vm, NativeListConcat);
|
||||
dlang_setfield(vm, "concat");
|
||||
|
||||
dlang_setglobal(vm, "list");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef DLANG_LIBS_MATH_HPP
|
||||
#define DLANG_LIBS_MATH_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <random>
|
||||
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeMathAbs(DlangVM* vm)
|
||||
{
|
||||
auto val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::fabs(val));
|
||||
}
|
||||
|
||||
static void NativeMathFloor(DlangVM* vm)
|
||||
{
|
||||
double val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::floor(val));
|
||||
}
|
||||
|
||||
static void NativeMathCeil(DlangVM* vm)
|
||||
{
|
||||
double val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::ceil(val));
|
||||
}
|
||||
|
||||
static void NativeMathSqrt(DlangVM* vm)
|
||||
{
|
||||
double val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::sqrt(val));
|
||||
}
|
||||
|
||||
static void NativeMathPow(DlangVM* vm)
|
||||
{
|
||||
double exp = dlang_tonumber(vm);
|
||||
double base = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::pow(base, exp));
|
||||
}
|
||||
|
||||
static void NativeMathSin(DlangVM* vm)
|
||||
{
|
||||
double val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::sin(val));
|
||||
}
|
||||
|
||||
static void NativeMathCos(DlangVM* vm)
|
||||
{
|
||||
double val = dlang_tonumber(vm);
|
||||
dlang_pushnumber(vm, std::cos(val));
|
||||
}
|
||||
|
||||
thread_local static std::random_device rd;
|
||||
thread_local static std::mt19937 gen(rd());
|
||||
|
||||
static void NativeMathSeed(DlangVM* vm)
|
||||
{
|
||||
double seedVal = dlang_tonumber(vm);
|
||||
gen.seed(static_cast<unsigned int>(seedVal));
|
||||
}
|
||||
|
||||
static void NativeMathRandom(DlangVM* vm)
|
||||
{
|
||||
double max = dlang_tonumber(vm);
|
||||
double min = dlang_tonumber(vm);
|
||||
|
||||
std::uniform_real_distribution<double> dis(min, max);
|
||||
dlang_pushnumber(vm, dis(gen));
|
||||
}
|
||||
|
||||
inline void openlib_math(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathAbs);
|
||||
dlang_setfield(vm, "abs");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathFloor);
|
||||
dlang_setfield(vm, "floor");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathCeil);
|
||||
dlang_setfield(vm, "ceil");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathSqrt);
|
||||
dlang_setfield(vm, "sqrt");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathPow);
|
||||
dlang_setfield(vm, "pow");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathSin);
|
||||
dlang_setfield(vm, "sin");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathCos);
|
||||
dlang_setfield(vm, "cos");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathSeed);
|
||||
dlang_setfield(vm, "seed");
|
||||
|
||||
dlang_pushcfunction(vm, NativeMathRandom);
|
||||
dlang_setfield(vm, "random");
|
||||
|
||||
dlang_setglobal(vm, "math");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef DLANG_LIBS_OS_HPP
|
||||
#define DLANG_LIBS_OS_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeOsTime(DlangVM* vm)
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
|
||||
dlang_pushnumber(vm, duration);
|
||||
}
|
||||
|
||||
static void NativeSleep(DlangVM* vm) {
|
||||
double ms = dlang_tonumber(vm);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int64_t>(ms)));
|
||||
}
|
||||
|
||||
static void NativeClock(DlangVM* vm)
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
|
||||
dlang_pushnumber(vm, duration);
|
||||
}
|
||||
|
||||
static void NativeCreateDir(DlangVM* vm)
|
||||
{
|
||||
auto dir = dlang_tostring(vm);
|
||||
std::filesystem::create_directories(dir);
|
||||
}
|
||||
|
||||
static void NativeRemove(DlangVM* vm)
|
||||
{
|
||||
auto path = dlang_tostring(vm);
|
||||
std::filesystem::remove_all(path);
|
||||
}
|
||||
|
||||
static void NativeListDir(DlangVM* vm)
|
||||
{
|
||||
auto dir = dlang_tostring(vm);
|
||||
|
||||
dlang_newlist(vm);
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir))
|
||||
{
|
||||
dlang_pushstring(vm, entry.path().string());
|
||||
dlang_pushindex(vm);
|
||||
}
|
||||
}
|
||||
|
||||
inline void openlib_os(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeOsTime);
|
||||
dlang_setfield(vm, "time");
|
||||
|
||||
dlang_pushcfunction(vm, NativeSleep);
|
||||
dlang_setfield(vm, "sleep");
|
||||
|
||||
dlang_pushcfunction(vm, NativeClock);
|
||||
dlang_setfield(vm, "clock");
|
||||
|
||||
dlang_pushcfunction(vm, NativeCreateDir);
|
||||
dlang_setfield(vm, "createdir");
|
||||
|
||||
dlang_pushcfunction(vm, NativeRemove);
|
||||
dlang_setfield(vm, "remove");
|
||||
|
||||
dlang_pushcfunction(vm, NativeListDir);
|
||||
dlang_setfield(vm, "listdir");
|
||||
|
||||
dlang_setglobal(vm, "os");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef DLANG_LIBS_REGEX_HPP
|
||||
#define DLANG_LIBS_REGEX_HPP
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeRegexMatch(DlangVM* vm)
|
||||
{
|
||||
auto pattern = dlang_tostring(vm);
|
||||
auto text = dlang_tostring(vm);
|
||||
|
||||
try {
|
||||
std::regex rx(pattern);
|
||||
bool matched = std::regex_match(text, rx);
|
||||
dlang_pushnumber(vm, matched ? 1.0 : 0.0);
|
||||
}
|
||||
catch (...) {
|
||||
dlang_pushnumber(vm, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void NativeRegexSearch(DlangVM* vm)
|
||||
{
|
||||
auto pattern = dlang_tostring(vm);
|
||||
auto text = dlang_tostring(vm);
|
||||
|
||||
try {
|
||||
std::regex rx(pattern);
|
||||
bool found = std::regex_search(text, rx);
|
||||
dlang_pushnumber(vm, found ? 1.0 : 0.0);
|
||||
}
|
||||
catch (...) {
|
||||
dlang_pushnumber(vm, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void NativeRegexReplace(DlangVM* vm)
|
||||
{
|
||||
auto fmt = dlang_tostring(vm);
|
||||
auto pattern = dlang_tostring(vm);
|
||||
auto text = dlang_tostring(vm);
|
||||
|
||||
try {
|
||||
std::regex rx(pattern);
|
||||
std::string result = std::regex_replace(text, rx, fmt);
|
||||
dlang_pushstring(vm, result);
|
||||
dlang_pushindex(vm);
|
||||
}
|
||||
catch (...) {
|
||||
dlang_pushstring(vm, text);
|
||||
dlang_pushindex(vm);
|
||||
}
|
||||
}
|
||||
|
||||
inline void openlib_regex(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeRegexMatch);
|
||||
dlang_setfield(vm, "match");
|
||||
|
||||
dlang_pushcfunction(vm, NativeRegexSearch);
|
||||
dlang_setfield(vm, "search");
|
||||
|
||||
dlang_pushcfunction(vm, NativeRegexReplace);
|
||||
dlang_setfield(vm, "replace");
|
||||
|
||||
dlang_setglobal(vm, "regex");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
#ifndef DLANG_LIBS_STRING_HPP
|
||||
#define DLANG_LIBS_STRING_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
|
||||
static void NativeSubString(DlangVM* vm)
|
||||
{
|
||||
double to = -1;
|
||||
if (dlang_top(vm) > 2)
|
||||
to = dlang_tonumber(vm);
|
||||
|
||||
auto from = dlang_tonumber(vm);
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
if (to == -1)
|
||||
dlang_pushstring(vm, str.substr(from));
|
||||
else
|
||||
dlang_pushstring(vm, str.substr(from, to));
|
||||
}
|
||||
|
||||
static void NativeContains(DlangVM* vm)
|
||||
{
|
||||
auto needle = dlang_tostring(vm);
|
||||
auto haystack = dlang_tostring(vm);
|
||||
|
||||
auto found = haystack.find(needle);
|
||||
dlang_pushboolean(vm, found != std::string::npos);
|
||||
}
|
||||
|
||||
static void NativeReplace(DlangVM* vm)
|
||||
{
|
||||
auto to = dlang_tostring(vm);
|
||||
auto from = dlang_tostring(vm);
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
size_t startPos = 0;
|
||||
if (!from.empty())
|
||||
{
|
||||
while ((startPos = str.find(from, startPos)) != std::string::npos)
|
||||
{
|
||||
str.replace(startPos, from.length(), to);
|
||||
startPos += to.length();
|
||||
}
|
||||
}
|
||||
|
||||
dlang_pushstring(vm, str);
|
||||
}
|
||||
|
||||
static void NativeLower(DlangVM* vm)
|
||||
{
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
std::transform(
|
||||
str.begin(), str.end(),
|
||||
str.begin(), ::tolower
|
||||
);
|
||||
|
||||
dlang_pushstring(vm, str);
|
||||
}
|
||||
|
||||
static void NativeUpper(DlangVM* vm)
|
||||
{
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
std::transform(
|
||||
str.begin(), str.end(),
|
||||
str.begin(), ::toupper
|
||||
);
|
||||
|
||||
dlang_pushstring(vm, str);
|
||||
}
|
||||
|
||||
static void NativeSplit(DlangVM* vm)
|
||||
{
|
||||
auto delimiter = dlang_tostring(vm);
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
std::vector<std::string> parts;
|
||||
|
||||
if (delimiter.empty()) {
|
||||
for (char c : str) {
|
||||
parts.push_back(std::string(1, c));
|
||||
}
|
||||
}
|
||||
else {
|
||||
size_t pos = 0;
|
||||
size_t delimSize = delimiter.size();
|
||||
|
||||
while ((pos = str.find(delimiter)) != std::string::npos) {
|
||||
parts.push_back(str.substr(0, pos));
|
||||
str.erase(0, pos + delimSize);
|
||||
}
|
||||
|
||||
parts.push_back(str);
|
||||
}
|
||||
|
||||
dlang_newlist(vm);
|
||||
for (size_t i = 0; i < parts.size(); ++i)
|
||||
{
|
||||
dlang_pushstring(vm, parts[i]);
|
||||
dlang_pushindex(vm);
|
||||
}
|
||||
}
|
||||
|
||||
static void NativeFind(DlangVM* vm)
|
||||
{
|
||||
auto needle = dlang_tostring(vm);
|
||||
auto str = dlang_tostring(vm);
|
||||
|
||||
size_t pos = str.find(needle);
|
||||
|
||||
dlang_pushnumber(vm, static_cast<double>(pos));
|
||||
}
|
||||
|
||||
inline void openlib_string(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeSubString);
|
||||
dlang_setfield(vm, "substr");
|
||||
|
||||
dlang_pushcfunction(vm, NativeContains);
|
||||
dlang_setfield(vm, "contains");
|
||||
|
||||
dlang_pushcfunction(vm, NativeReplace);
|
||||
dlang_setfield(vm, "replace");
|
||||
|
||||
dlang_pushcfunction(vm, NativeLower);
|
||||
dlang_setfield(vm, "lower");
|
||||
|
||||
dlang_pushcfunction(vm, NativeUpper);
|
||||
dlang_setfield(vm, "upper");
|
||||
|
||||
dlang_pushcfunction(vm, NativeSplit);
|
||||
dlang_setfield(vm, "split");
|
||||
|
||||
dlang_pushcfunction(vm, NativeFind);
|
||||
dlang_setfield(vm, "find");
|
||||
|
||||
dlang_setglobal(vm, "string");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
#ifndef DLANG_LIBS_TABLE_HPP
|
||||
#define DLANG_LIBS_TABLE_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "../vm.hpp"
|
||||
#include "../helpers.hpp"
|
||||
#include "../json.hpp"
|
||||
|
||||
void NativeTableInsert(DlangVM* vm)
|
||||
{
|
||||
auto newTable = dlang_totable(vm);
|
||||
auto insertTable = dlang_totable(vm);
|
||||
|
||||
for (const auto [key, val] : newTable->fields)
|
||||
insertTable->fields[key] = val;
|
||||
|
||||
dlang_push(vm, StackValue(StackValueType::Table, insertTable));
|
||||
}
|
||||
|
||||
void NativeTableRemove(DlangVM* vm)
|
||||
{
|
||||
auto key = dlang_tostring(vm);
|
||||
auto table = dlang_totable(vm);
|
||||
|
||||
auto it = table->fields.find(key);
|
||||
if (it != table->fields.end())
|
||||
table->fields.erase(it);
|
||||
|
||||
dlang_push(vm, StackValue(StackValueType::Table, table));
|
||||
}
|
||||
|
||||
nlohmann::json DlangValueToJson(const StackValue& val)
|
||||
{
|
||||
switch (val.type)
|
||||
{
|
||||
case StackValueType::Int: return std::get<double>(val.data);
|
||||
case StackValueType::Bool: return std::get<bool>(val.data);
|
||||
case StackValueType::String: return std::get<std::string>(val.data);
|
||||
case StackValueType::NIL: return nullptr;
|
||||
|
||||
case StackValueType::Table:
|
||||
{
|
||||
auto tablePtr = std::get<std::shared_ptr<DlangTable>>(val.data);
|
||||
nlohmann::json jObj = nlohmann::json::object();
|
||||
|
||||
for (const auto& [key, fieldVal] : tablePtr->fields)
|
||||
jObj[key] = DlangValueToJson(fieldVal);
|
||||
|
||||
return jObj;
|
||||
}
|
||||
|
||||
case StackValueType::List:
|
||||
{
|
||||
auto listPtr = std::get<std::shared_ptr<DlangList>>(val.data);
|
||||
nlohmann::json jArr = nlohmann::json::array();
|
||||
|
||||
for (const auto& elemVal : listPtr->values)
|
||||
jArr.push_back(DlangValueToJson(elemVal));
|
||||
|
||||
return jArr;
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PushJsonToVM(DlangVM* vm, const nlohmann::json& j)
|
||||
{
|
||||
if (j.is_number())
|
||||
{
|
||||
dlang_pushnumber(vm, j.get<double>());
|
||||
}
|
||||
else if (j.is_boolean())
|
||||
{
|
||||
dlang_pushboolean(vm, j.get<bool>());
|
||||
}
|
||||
else if (j.is_string())
|
||||
{
|
||||
dlang_pushstring(vm, j.get<std::string>());
|
||||
}
|
||||
else if (j.is_array())
|
||||
{
|
||||
dlang_newlist(vm);
|
||||
auto listPtr = dlang_tolist(vm);
|
||||
|
||||
for (const auto& element : j)
|
||||
{
|
||||
PushJsonToVM(vm, element);
|
||||
listPtr->values.push_back(vm->stack.pop());
|
||||
}
|
||||
|
||||
vm->stack.push(StackValue(StackValueType::List, listPtr));
|
||||
}
|
||||
else if (j.is_object())
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
auto tablePtr = dlang_totable(vm);
|
||||
|
||||
for (auto it = j.begin(); it != j.end(); ++it)
|
||||
{
|
||||
PushJsonToVM(vm, it.value());
|
||||
tablePtr->fields[it.key()] = vm->stack.pop();
|
||||
}
|
||||
|
||||
vm->stack.push(StackValue(StackValueType::Table, tablePtr));
|
||||
}
|
||||
else
|
||||
{
|
||||
dlang_pushnil(vm);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeJsonEncode(DlangVM* vm)
|
||||
{
|
||||
int indent = 0;
|
||||
if (dlang_isnumber(vm))
|
||||
indent = dlang_tonumber(vm);
|
||||
|
||||
if (!dlang_istable(vm))
|
||||
{
|
||||
dlang_pushnil(vm);
|
||||
return;
|
||||
}
|
||||
|
||||
nlohmann::json j = DlangValueToJson(dlang_pop(vm));
|
||||
|
||||
dlang_pushstring(vm, j.dump(indent));
|
||||
}
|
||||
|
||||
void NativeJsonDecode(DlangVM* vm)
|
||||
{
|
||||
std::string jsonStr = dlang_tostring(vm);
|
||||
|
||||
try
|
||||
{
|
||||
nlohmann::json j = nlohmann::json::parse(jsonStr);
|
||||
PushJsonToVM(vm, j);
|
||||
}
|
||||
catch (const nlohmann::json::parse_error& e)
|
||||
{
|
||||
throw std::runtime_error("JSON Parse Error: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
inline void openlib_table(DlangVM* vm)
|
||||
{
|
||||
dlang_newtable(vm);
|
||||
|
||||
dlang_pushcfunction(vm, NativeTableInsert);
|
||||
dlang_setfield(vm, "insert");
|
||||
|
||||
dlang_pushcfunction(vm, NativeTableRemove);
|
||||
dlang_setfield(vm, "remove");
|
||||
|
||||
dlang_pushcfunction(vm, NativeJsonEncode);
|
||||
dlang_setfield(vm, "json_encode");
|
||||
|
||||
dlang_pushcfunction(vm, NativeJsonDecode);
|
||||
dlang_setfield(vm, "json_decode");
|
||||
|
||||
dlang_setglobal(vm, "table");
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user