#ifndef DLANG_LIBS_STRING_HPP #define DLANG_LIBS_STRING_HPP #include #include #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 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(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