#ifndef DLANG_LIBS_TABLE_HPP #define DLANG_LIBS_TABLE_HPP #include #include #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(val.data); case StackValueType::Bool: return std::get(val.data); case StackValueType::String: return std::get(val.data); case StackValueType::NIL: return nullptr; case StackValueType::Table: { auto tablePtr = std::get>(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>(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()); } else if (j.is_boolean()) { dlang_pushboolean(vm, j.get()); } else if (j.is_string()) { dlang_pushstring(vm, j.get()); } 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