Files
2026-10-12 23:34:28 +02:00

171 lines
5.2 KiB
C++

#ifndef DLANG_HELPERS_HPP
#define DLANG_HELPERS_HPP
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstring>
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
#endif
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
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<long long>(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<double>(vm->stack.pop().data)
#define dlang_toboolean(vm) std::get<bool>(vm->stack.pop().data)
#define dlang_tostring(vm) std::get<std::string>(vm->stack.pop().data)
#define dlang_totoken(vm) (vm->stack.pop())
#define dlang_totable(vm) std::get<std::shared_ptr<DlangTable>>(vm->stack.pop().data)
#define dlang_tolist(vm) std::get<std::shared_ptr<DlangList>>(vm->stack.pop().data)
#define dlang_tocfunction(vm) std::get<NativeFunctionPtr>(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<DlangTable>()))
#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<DlangList>());
#define dlang_setindex(vm) vm->SetListIndex()
#define dlang_getindex(vm) vm->GetListIndex()
#define dlang_pushindex(vm) vm->PushListIndex();
#endif