#include "CrossLang.hpp" namespace Tesses::CrossLang { TObject TypeOf(GCList& ls, std::vector args) { if(args.size() < 1) return "Undefined"; if(std::holds_alternative(args[0])) return "Undefined"; if(std::holds_alternative(args[0])) return "Null"; if(std::holds_alternative(args[0])) return "Boolean"; if(std::holds_alternative(args[0])) return "Long"; if(std::holds_alternative(args[0])) return "Double"; if(std::holds_alternative(args[0])) return "Char"; if(std::holds_alternative(args[0])) return "MethodInvoker"; if(std::holds_alternative(args[0])) return "String"; if(std::holds_alternative(args[0])) return "Path"; if(std::holds_alternative(args[0])) { auto obj = std::get(args[0]).obj; auto dict = dynamic_cast(obj); auto list = dynamic_cast(obj); auto argWrapper = dynamic_cast(obj); auto closure = dynamic_cast(obj); auto externalMethod = dynamic_cast(obj); auto byteArray = dynamic_cast(obj); auto native = dynamic_cast(obj); auto vfs = dynamic_cast(obj); auto strm = dynamic_cast(obj); if(strm != nullptr) { auto netStrm = dynamic_cast(strm->stream); if(netStrm != nullptr) { return "NetworkStream"; } return "Stream"; } if(vfs != nullptr) { auto localVFS = dynamic_cast(vfs->vfs); auto mountableVFS = dynamic_cast(vfs->vfs); auto subFS = dynamic_cast(vfs->vfs); if(localVFS != nullptr) return "LocalFilesystem"; if(subFS != nullptr) return "SubdirFilesystem"; if(mountableVFS != nullptr) return "MountableFilesystem"; return "VFS"; } if(dict != nullptr) return "Dictionary"; if(list != nullptr) return "List"; if(argWrapper != nullptr) return "ArgWrapper"; if(closure != nullptr) return "Closure"; if(externalMethod != nullptr) return "ExternalMethod"; if(byteArray != nullptr) return "ByteArray"; if(native != nullptr) return "Native"; return "HeapObject"; } return "Object"; } TObject ByteArray(GCList& ls, std::vector args) { auto res= TByteArray::Create(ls); if(args.size() == 1){ if(std::holds_alternative(args[0])) res->data.resize((size_t)std::get(args[0])); else if(std::holds_alternative(args[0])) { std::string& txt = std::get(args[0]); res->data.insert(res->data.end(), txt.begin(),txt.end()); } } return res; } TObject ParseLong(GCList& ls, std::vector args) { if(args.size() >= 1) { int base = 10; if(args.size() == 2 && std::holds_alternative(args[1])) { base = (int)std::get(args[1]); } size_t pos; std::string str = ToString(ls.GetGC(),args[0]); try { int64_t v = std::stoll(str,&pos,base); if(pos < str.size()) return nullptr; return v; }catch(std::exception& ex) { return nullptr; } } return nullptr; } TObject ParseDouble(GCList& ls, std::vector args) { if(args.size() == 1) { size_t pos; std::string str = ToString(ls.GetGC(),args[0]); try { double v = std::stod(str,&pos); if(pos < str.size()) return nullptr; return v; }catch(std::exception& ex) { return nullptr; } } return nullptr; } static TObject Throw(GCList& ls, std::vector args) { if(!args.empty()) { VMByteCodeException bce(ls.GetGC(),args[0]); throw bce; } return nullptr; } static TObject Try(GCList& ls, std::vector args) { TCallable* tryPart; TCallable* catchPart; if(GetArgumentHeap(args,0,tryPart) && GetArgumentHeap(args,1,catchPart)) { try { tryPart->Call(ls,{}); } catch(VMByteCodeException& ex) { catchPart->Call(ls,{ex.exception}); } catch(std::exception& ex) { TDictionary* dict = TDictionary::Create(ls); auto gc = ls.GetGC(); gc->BarrierBegin(); dict->SetValue("Type","NativeException"); dict->SetValue("Text",ex.what()); gc->BarrierEnd(); catchPart->Call(ls,{dict}); } } return nullptr; } EnvironmentPermissions::EnvironmentPermissions() { this->canRegisterConsole=false; this->canRegisterCrypto=false; this->canRegisterDictionary=false; this->canRegisterEnv=false; this->canRegisterIO=false; this->canRegisterJSON=false; this->canRegisterLocalFS=false; this->canRegisterNet=false; this->canRegisterOGC=false; this->canRegisterPath=false; this->canRegisterRoot=false; this->canRegisterSDL2=false; this->canRegisterSqlite=false; this->canRegisterVM = false; this->locked=false; this->sqlite3Scoped=false; } void TStd::RegisterRoot(GC* gc, TRootEnvironment* env) { env->permissions.canRegisterRoot=true; env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong); env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble); env->DeclareFunction(gc, "TypeOf","Get type of object",{"object"},TypeOf); env->DeclareFunction(gc, "Throw", "Throw an exception",{"object"},Throw); env->DeclareFunction(gc, "Try", "Handle exceptions",{"callbackToTry","callbackToCatch"},Try); env->DeclareFunction(gc, "Thread","Create thread",{"callback"},[](GCList& ls, std::vector args)-> TObject { if(args.size() == 1 && std::holds_alternative(args[0])) { auto cb = dynamic_cast(std::get(args[0]).obj); if(cb != nullptr) { return CreateThread(ls,cb,false); } } return Undefined(); }); env->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray); } void TStd::RegisterStd(GC* gc, TRootEnvironment* env) { RegisterEnv(gc, env); RegisterRoot(gc,env); RegisterPath(gc,env); RegisterConsole(gc, env); RegisterIO(gc, env); RegisterNet(gc, env); RegisterSqlite(gc, env); RegisterVM(gc, env); RegisterJson(gc, env); RegisterDictionary(gc, env); RegisterCrypto(gc,env); RegisterSDL2(gc, env); RegisterOGC(gc, env); env->permissions.locked=true; } }