#ifndef DLANG_HELPERS_HPP #define DLANG_HELPERS_HPP #define _WINSOCK_DEPRECATED_NO_WARNINGS #ifdef _WIN32 #include #include #pragma comment(lib, "ws2_32.lib") #else #include #include #include #include #define SOCKET int #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define closesocket close #endif #include #include #include #include static bool isvalidnumber(char c) { return ::isdigit(c) || c == '.' || c == ','; } static bool IsStringNumber(const std::string& input) { return std::all_of( input.begin(), input.end(), ::isvalidnumber ); } static bool IsIdentifier(const std::string& input) { if (!::isdigit(input.at(0))) return true; return false; } static std::string DoubleToString(double val) { double intPart; double fracPart = std::modf(val, &intPart); if (fracPart == 0.0) { return std::to_string(static_cast(val)); } else { std::ostringstream oss; oss << val; return oss.str(); } } static std::string NoSpacesString(const std::string& input) { std::string output = ""; for (const auto& c : input) if (::isdigit(c) || ::isalpha(c) || c == '.') output += c; return output; } static std::string getLatestVersion(const std::string& host, const std::string& path) { #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return ""; #endif SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { #ifdef _WIN32 WSACleanup(); #endif return ""; } struct hostent* server = gethostbyname(host.c_str()); if (!server) { closesocket(sock); #ifdef _WIN32 WSACleanup(); #endif return ""; } struct sockaddr_in serv_addr; ::memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; ::memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); serv_addr.sin_port = htons(80); if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) { closesocket(sock); #ifdef _WIN32 WSACleanup(); #endif return ""; } std::string request = "GET " + path + " HTTP/1.0\r\nHost: " + host + "\r\nConnection: close\r\n\r\n"; send(sock, request.c_str(), (int)request.length(), 0); std::string response; char buffer[1024]; int bytesReceived; while ((bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0)) > 0) { buffer[bytesReceived] = '\0'; response += buffer; } closesocket(sock); #ifdef _WIN32 WSACleanup(); #endif size_t pos = response.find("\r\n\r\n"); if (pos != std::string::npos) { return NoSpacesString(response.substr(pos + 4)); } return ""; } #define dlang_pop(vm) vm->Pop() #define dlang_top(vm) (vm->stack.top()) #define dlang_tonumber(vm) std::get(vm->stack.pop().data) #define dlang_toboolean(vm) std::get(vm->stack.pop().data) #define dlang_tostring(vm) std::get(vm->stack.pop().data) #define dlang_totoken(vm) (vm->stack.pop()) #define dlang_totable(vm) std::get>(vm->stack.pop().data) #define dlang_tolist(vm) std::get>(vm->stack.pop().data) #define dlang_tocfunction(vm) std::get(vm->stack.pop().data) #define dlang_pushnumber(vm, number) vm->PushNumber(number) #define dlang_pushboolean(vm, boolean) vm->PushBoolean(boolean) #define dlang_pushstring(vm, stringv) vm->PushString(stringv) #define dlang_pushnil(vm) vm->stack.push(StackValue()) #define dlang_push(vm, stackval) vm->stack.push(stackval) #define dlang_isnumber(vm) (vm->stack.peek().type == StackValueType::Int) #define dlang_isstring(vm) (vm->stack.peek().type == StackValueType::String) #define dlang_isboolean(vm) (vm->stack.peek().type == StackValueType::Bool) #define dlang_istable(vm) (vm->stack.peek().type == StackValueType::Table) #define dlang_islist(vm) (vm->stack.peek().type == StackValueType::List) #define dlang_isfunction(vm) (vm->stack.peek().type == StackValueType::Function) #define dlang_isnil(vm) (vm->stack.peek().type == StackValueType::NIL) #define dlang_pushcfunction(vm, func) vm->PushCFunction(func) #define dlang_setglobal(vm, name) vm->globals.Set(name, vm->stack.pop()) #define dlang_getglobal(vm, name) vm->stack.push(vm->globals.Get(name)) #define dlang_call(vm, args) vm->CallFunc(args) #define dlang_newtable(vm) vm->stack.push(StackValue(StackValueType::Table, std::make_shared())) #define dlang_setfield(vm, keyName) vm->SetField(keyName) #define dlang_getfield(vm, keyName) vm->GetField(keyName) // dlang_getfieldp will pop the table from stack and not return it #define dlang_getfieldp(vm, keyName) vm->GetField(keyName, true) #define dlang_newlist(vm) vm->PushList(std::make_shared()); #define dlang_setindex(vm) vm->SetListIndex() #define dlang_getindex(vm) vm->GetListIndex() #define dlang_pushindex(vm) vm->PushListIndex(); #endif