Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs

This commit is contained in:
2026-05-29 20:52:26 -05:00
parent d26e357448
commit abea319ea0
110 changed files with 25716 additions and 31016 deletions

View File

@@ -1,287 +1,255 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : strs)
list->Add(item);
ls.GetGC()->BarrierEnd();
return list;
}
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : ents) {
std::string modifier = "public";
switch (item.modifier) {
case TClassModifier::Public:
modifier = "public";
break;
case TClassModifier::Private:
modifier = "private";
break;
case TClassModifier::Protected:
modifier = "protected";
break;
case TClassModifier::Static:
modifier = "static";
break;
}
namespace Tesses::CrossLang
{
static TList* VectorOfStringToList(GCList& ls, std::vector<std::string>& strs)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : strs)
list->Add(item);
ls.GetGC()->BarrierEnd();
return list;
list->Add(TDictionary::Create(
ls,
{TDItem("Name", item.name), TDItem("IsAbstract", item.isAbstract),
TDItem("IsFunction", item.isFunction),
TDItem("Documentation", item.documentation),
TDItem("ChunkId", (int64_t)item.chunkId),
TDItem("Arguments", VectorOfStringToList(ls, item.args)),
TDItem("Modifier", modifier)}));
}
static TList* EntriesToList(GCList& ls, std::vector<TClassEntry>& ents)
{
TList* list=TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : ents)
{
std::string modifier = "public";
switch(item.modifier)
{
case TClassModifier::Public:
modifier = "public";
break;
case TClassModifier::Private:
modifier = "private";
break;
case TClassModifier::Protected:
modifier = "protected";
break;
case TClassModifier::Static:
modifier = "static";
break;
}
list->Add(TDictionary::Create(ls,{
TDItem("Name",item.name),
TDItem("IsAbstract",item.isAbstract),
TDItem("IsFunction",item.isFunction),
TDItem("Documentation",item.documentation),
TDItem("ChunkId",(int64_t)item.chunkId),
TDItem("Arguments",VectorOfStringToList(ls,item.args)),
TDItem("Modifier",modifier)
}));
ls.GetGC()->BarrierEnd();
return list;
}
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : co->entries) {
if (item.modifier == TClassModifier::Public) {
list->Add(TDictionary::Create(
ls,
{TDItem("Name", item.name), TDItem("IsFunction", !item.canSet),
TDItem("Owner", item.owner), TDItem("Value", item.value)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TList* ClassInstanceToList(GCList& ls, TClassObject* co)
{
TList* list=TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : co->entries)
{
if(item.modifier == TClassModifier::Public)
{
list->Add(TDictionary::Create(ls, {
TDItem(
"Name", item.name
),
TDItem(
"IsFunction", !item.canSet
),
TDItem(
"Owner", item.owner
),
TDItem(
"Value", item.value
)
}));
}
}
ls.GetGC()->BarrierEnd();
return list;
}
TObject GetClassInfo(GCList& ls,TFile* f, uint32_t index)
{
return TDictionary::Create(ls,{
TDItem("Name", JoinPeriod(f->classes.at(index).name)),
TDItem("NameParts",VectorOfStringToList(ls,f->classes.at(index).name)),
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
TDItem("InheritsParts",VectorOfStringToList(ls,f->classes.at(index).inherits)),
TDItem("Documentation",f->classes.at(index).documentation),
TDItem("Entries",EntriesToList(ls,f->classes.at(index).entry))
});
}
static TObject Class_CreateInstance(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* args_ls;
if(!GetArgumentHeap(args,1,args_ls)) return nullptr;
TList* list;
TClassObject* obj;
std::string str;
if(GetArgumentHeap(args,0,list))
{
std::vector<std::string> clsName;
for(int64_t i = 0; i < list->Count(); i++)
{
auto o = list->Get(i);
if(GetObject(o,str)) clsName.push_back(str);
}
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
}
else
continue;
}
}
else if(GetArgument(args,0,str))
{
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
}
else
continue;
}
}
ls.GetGC()->BarrierEnd();
return list;
}
TObject GetClassInfo(GCList &ls, TFile *f, uint32_t index) {
return TDictionary::Create(
ls, {TDItem("Name", JoinPeriod(f->classes.at(index).name)),
TDItem("NameParts",
VectorOfStringToList(ls, f->classes.at(index).name)),
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
TDItem("InheritsParts",
VectorOfStringToList(ls, f->classes.at(index).inherits)),
TDItem("Documentation", f->classes.at(index).documentation),
TDItem("Entries", EntriesToList(ls, f->classes.at(index).entry))});
}
static TObject Class_CreateInstance(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
TList *args_ls;
if (!GetArgumentHeap(args, 1, args_ls))
return nullptr;
}
static TObject Class_GetClassNames(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto& item : env->classes)
{
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
TList *list;
TClassObject *obj;
std::string str;
if (GetArgumentHeap(args, 0, list)) {
std::vector<std::string> clsName;
for (int64_t i = 0; i < list->Count(); i++) {
auto o = list->Get(i);
if (GetObject(o, str))
clsName.push_back(str);
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Class_GetInfo(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
{
TList* list;
TClassObject* obj;
std::string str;
if(GetArgumentHeap(args,0,list))
{
std::vector<std::string> clsName;
for(int64_t i = 0; i < list->Count(); i++)
{
auto o = list->Get(i);
if(GetObject(o,str)) clsName.push_back(str);
}
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return GetClassInfo(ls,item.first,item.second);
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
else
continue;
}
if (found) {
return TClassObject::Create(ls, item.first, item.second, env,
args_ls->items);
} else
continue;
}
else if(GetArgument(args,0,str))
{
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
for(auto& item : env->classes)
{
auto& f=item.first->classes.at(item.second);
if(f.name.size() != clsName.size()) continue;
bool found=true;
for(size_t i = 0; i < f.name.size(); i++)
if(f.name[i] != clsName[i])
{
found=false;
break;
}
if(found)
{
return GetClassInfo(ls,item.first,item.second);
} else if (GetArgument(args, 0, str)) {
std::vector<std::string> clsName =
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
else
continue;
}
}
else if(GetArgumentHeap(args,0,obj))
{
return GetClassInfo(ls,obj->file,obj->classIndex);
}
if (found) {
return TClassObject::Create(ls, item.first, item.second, env,
args_ls->items);
return nullptr;
} else
continue;
}
}
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
env->permissions.canRegisterClass=true;
TDictionary* cls= env->EnsureDictionary(gc, "Class");
gc->BarrierBegin();
TExternalMethod* ext = TExternalMethod::Create(ls ,"Get the class info",{"classInstanceOrClassName"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_GetInfo(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("GetInfo",ext);
return nullptr;
}
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto &item : env->classes) {
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
std::vector<TObject> args) {
ext = TExternalMethod::Create(ls ,"Get the class names",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_GetClassNames(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("GetClassNames",ext);
ext = TExternalMethod::Create(ls ,"Create an instance of class",{"name","args"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Class_CreateInstance(env,ls,args);
});
ext->watch.push_back(env);
cls->SetValue("CreateInstance",ext);
cls->DeclareFunction(gc,"Name","Get class name via instance",{"instance"},[](GCList& ls, std::vector<TObject> args)->TObject {
TClassObject* cls;
if(GetArgumentHeap(args,0,cls))
{
return cls->name;
}
return "";
});
TList *list;
TClassObject *obj;
std::string str;
if (GetArgumentHeap(args, 0, list)) {
std::vector<std::string> clsName;
for (int64_t i = 0; i < list->Count(); i++) {
auto o = list->Get(i);
if (GetObject(o, str))
clsName.push_back(str);
}
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
cls->DeclareFunction(gc, "GetInstanceInfo", "Get the instance specific info, including current values", {}, [](GCList& ls, std::vector<TObject> args)->TObject {
TClassObject* co;
if(GetArgumentHeap(args, 0, co))
{
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
if (found) {
return GetClassInfo(ls, item.first, item.second);
} else
continue;
}
} else if (GetArgument(args, 0, str)) {
std::vector<std::string> clsName =
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
for (auto &item : env->classes) {
auto &f = item.first->classes.at(item.second);
if (f.name.size() != clsName.size())
continue;
bool found = true;
for (size_t i = 0; i < f.name.size(); i++)
if (f.name[i] != clsName[i]) {
found = false;
break;
}
if (found) {
return GetClassInfo(ls, item.first, item.second);
} else
continue;
}
} else if (GetArgumentHeap(args, 0, obj)) {
return GetClassInfo(ls, obj->file, obj->classIndex);
}
return nullptr;
}
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
GCList ls(gc);
env->permissions.canRegisterClass = true;
TDictionary *cls = env->EnsureDictionary(gc, "Class");
gc->BarrierBegin();
TExternalMethod *ext = TExternalMethod::Create(
ls, "Get the class info", {"classInstanceOrClassName"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_GetInfo(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("GetInfo", ext);
ext = TExternalMethod::Create(
ls, "Get the class names", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_GetClassNames(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("GetClassNames", ext);
ext = TExternalMethod::Create(
ls, "Create an instance of class", {"name", "args"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Class_CreateInstance(env, ls, args);
});
ext->watch.push_back(env);
cls->SetValue("CreateInstance", ext);
cls->DeclareFunction(gc, "Name", "Get class name via instance",
{"instance"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TClassObject *cls;
if (GetArgumentHeap(args, 0, cls)) {
return cls->name;
}
return "";
});
cls->DeclareFunction(
gc, "GetInstanceInfo",
"Get the instance specific info, including current values", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TClassObject *co;
if (GetArgumentHeap(args, 0, co)) {
ls.GetGC()->BarrierBegin();
auto res= TDictionary::Create(ls,
{
TDItem("Name", co->name),
TDItem("File", co->file),
TDItem("ClassIndex", (int64_t)co->classIndex),
TDItem("InheritList", VectorOfStringToList(ls, co->inherit_tree)),
TDItem("Entries", ClassInstanceToList(ls,co))
}
);
auto res = TDictionary::Create(
ls, {TDItem("Name", co->name), TDItem("File", co->file),
TDItem("ClassIndex", (int64_t)co->classIndex),
TDItem("InheritList",
VectorOfStringToList(ls, co->inherit_tree)),
TDItem("Entries", ClassInstanceToList(ls, co))});
ls.GetGC()->BarrierEnd();
return res;
}
return nullptr;
});
gc->BarrierEnd();
}
}
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -2,334 +2,237 @@
#include "CrossLang.hpp"
#include <iostream>
#if defined(GEKKO) || defined(__SWITCH__) || defined(_WIN32)
#undef CROSSLANG_ENABLE_TERMIOS
#endif
#ifdef CROSSLANG_ENABLE_TERMIOS
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#endif
namespace Tesses::CrossLang {
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios orig_termios;
static void disableRawMode()
{
tcsetattr(0, TCSAFLUSH, &orig_termios);
}
#endif
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ECHO) > 0;
#endif
return false;
}
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ECHO;
}
else
{
raw.c_lflag &= ~(ECHO);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
}
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::IsTTY();
}
TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetEcho();
}
TObject Console_setEcho(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetEcho(cooked);
return cooked;
}
return Undefined();
}
TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetCanonical();
}
TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetCanonical(cooked);
return cooked;
}
return Undefined();
}
TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::GetSignals();
}
TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
bool cooked = std::get<bool>(args[0]);
Tesses::Framework::Console::SetSignals(cooked);
return cooked;
}
return Undefined();
}
TObject Console_Read(GCList &ls, std::vector<TObject> args) {
return (int64_t)Tesses::Framework::Console::Read();
}
TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::ReadLine();
}
TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Console::ReadPassword();
}
TObject Console_Write(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
return Undefined();
}
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ICANON) > 0;
#endif
return false;
}
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ICANON;
}
else
{
raw.c_lflag &= ~(ICANON);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
}
return Undefined();
}
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
return (raw.c_lflag & ISIG) > 0;
#endif
return false;
}
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
{
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
{
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ISIG;
}
else
{
raw.c_lflag &= ~(ISIG);
}
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
}
return Undefined();
}
TObject Console_Read(GCList& ls, std::vector<TObject> args)
{
uint8_t byte;
std::cin.read((char*)&byte,1);
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
}
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
{
std::string str;
std::getline(std::cin,str);
return str;
}
TObject Console_Write(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
return Undefined();
}
std::cout << ToString(ls.GetGC(),args[0]);
return Undefined();
}
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
exit(1);
}
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
exit(1);
}
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "\n";
return Undefined();
}
std::cout << ToString(ls.GetGC(),args[0]) << "\n";
return Undefined();
}
TObject Console_Error(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
return Undefined();
}
std::cerr << ToString(ls.GetGC(),args[0]);
return Undefined();
}
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args)
{
if(args.size() < 1)
{
std::cout << "\n";
return Undefined();
}
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
return Undefined();
}
TObject Console_getIn(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false);
}
TObject Console_getOut(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdout,false,"w",false);
}
TObject Console_getError(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Streams::FileStream>(stderr,false,"w",false);
}
TObject Console_Clear(GCList& ls, std::vector<TObject> args)
{
//because I just really want a clear function
#if defined(_WIN32)
system("cls");
#else
std::cout << "\x1b[2J\x1b[H" << std::flush; //because of wii and stuff (dont want to rely on clear command)
#endif
return Undefined();
}
static void con_sz(int& w, int& h)
{
w = 0;
h = 0;
#if defined(_WIN32)
#elif defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO))
return;
struct winsize ws;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
{
w = ws.ws_col;
h = ws.ws_row;
}
#endif
}
TObject Console_ProgressBar(GCList& ls, std::vector<TObject> args)
{
//[=== ] 50%
bool showBar = true;
#if defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO)) showBar=false;
#endif
int64_t progress = 0;
double pdbl = 0;
GetArgument(args,0,pdbl);
if(GetArgument(args,0,progress)) pdbl = progress / 100.0;
if(pdbl < 0) pdbl=0;
if(pdbl > 1) pdbl=1;
std::cout << "\r";
if(showBar)
{
int w,h;
con_sz(w,h);
int totalBlocks = w - 10;
if(totalBlocks > 0)
{
std::cout << "[\033[0;32m";
int i;
int off = pdbl * totalBlocks;
for(int i = 0; i < totalBlocks; i++)
{
if(i < off)
std::cout << "=";
else
std::cout << " ";
}
std::cout << "\033[0m] ";
}
}
std::cout << std::setw(3) << (int)(pdbl*100) << "%" << std::flush;
return Undefined();
}
TObject Console_getSize(GCList& ls, std::vector<TObject> args)
{
#if defined(CROSSLANG_ENABLE_TERMIOS)
if(!isatty(STDOUT_FILENO)) return nullptr;
#endif
int w, h;
con_sz(w,h);
TDictionary* dict = TDictionary::Create(ls,{
TDItem("Width", (int64_t)w),
TDItem("Height",(int64_t)h)
});
return dict;
}
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterConsole=true;
if(env->permissions.customConsole != nullptr)
{
gc->BarrierBegin();
env->DeclareVariable("Console", env->permissions.customConsole );
gc->BarrierEnd();
return;
}
#ifdef CROSSLANG_ENABLE_TERMIOS
tcgetattr(0, &orig_termios);
atexit(disableRawMode);
#endif
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear);
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine);
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error);
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine);
dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar);
if(env->permissions.canRegisterEverything)
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn);
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut);
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError);
dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize);
gc->BarrierBegin();
env->DeclareVariable("Console", dict);
auto _new = env->EnsureDictionary(gc,"New");
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>();
});
_new->DeclareFunction(gc,"ConsoleWriter","Write to console",{"$isStderr"},[](GCList& ls,std::vector<TObject> args)->TObject {
bool err;
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err);
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>();
});
gc->BarrierEnd();
}
Tesses::Framework::Console::ErrorLine("FATAL: " +
ToString(ls.GetGC(), args[0]));
exit(1);
}
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::WriteLineView("");
return Undefined();
}
Tesses::Framework::Console::WriteLine(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_Error(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
return Undefined();
}
Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
if (args.size() < 1) {
Tesses::Framework::Console::ErrorLine("");
return Undefined();
}
Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
return Undefined();
}
TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stdin, false, "r", false);
}
TObject Console_getOut(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stdout, false, "w", false);
}
TObject Console_getError(GCList &ls, std::vector<TObject> args) {
return std::make_shared<Tesses::Framework::Streams::FileStream>(
stderr, false, "w", false);
}
TObject Console_Clear(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Console::Clear();
return Undefined();
}
TObject Console_ProgressBar(GCList &ls, std::vector<TObject> args) {
double dbl;
int64_t i64;
if (GetArgument(args, 0, i64)) {
Tesses::Framework::Console::ProgressBar((int)i64);
} else if (GetArgument(args, 0, dbl)) {
Tesses::Framework::Console::ProgressBar(dbl);
}
return Undefined();
}
TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
auto sz = Tesses::Framework::Console::GetSize();
TDictionary *dict =
TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
TDItem("Height", (int64_t)sz.second)});
return dict;
}
TObject Console_List(GCList &ls, std::vector<TObject> args) {
if (!args.empty()) {
GCList ls2(ls.GetGC());
auto enumerator = TEnumerator::CreateFromObject(ls2, args[0]);
std::vector<std::string> items;
while (enumerator->MoveNext(ls2.GetGC())) {
auto item = enumerator->GetCurrent(ls2);
items.push_back(ToString(ls2.GetGC(), item));
}
return (int64_t)Tesses::Framework::Console::List(items);
}
return 0;
}
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterConsole = true;
if (env->permissions.customConsole != nullptr) {
gc->BarrierBegin();
env->DeclareVariable("Console", env->permissions.customConsole);
gc->BarrierEnd();
return;
}
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(
gc, "getIsTTY",
"Get whether terminal is a terminal or just piped to file", {},
Console_getIsTTY);
dict->DeclareFunction(gc, "getEcho",
"Get whether terminal is echoing characters read", {},
Console_getEcho);
dict->DeclareFunction(gc, "setEcho",
"Set whether terminal is echoing characters read",
{"flag"}, Console_setEcho);
dict->DeclareFunction(gc, "getCanonical",
"Get whether terminal is buffering line by line "
"(true) or byte by byte (false)",
{}, Console_getCanonical);
dict->DeclareFunction(gc, "setCanonical",
"Set whether terminal is buffering line by line "
"(true) or byte by byte (false)",
{"flag"}, Console_setCanonical);
dict->DeclareFunction(gc, "getSignals",
"Get whether terminal is sending signals for CTRL+C "
"(true) or via read (false)",
{}, Console_getSignals);
dict->DeclareFunction(gc, "setSignals",
"Set whether terminal is sending signals for CTRL+C "
"(true) or via read (false)",
{"flag"}, Console_setSignals);
dict->DeclareFunction(gc, "Clear", "Clear the console", {}, Console_Clear);
dict->DeclareFunction(gc, "Read", "Reads a byte from stdin", {},
Console_Read);
dict->DeclareFunction(gc, "ReadLine", "Reads line from stdin", {},
Console_ReadLine);
dict->DeclareFunction(gc, "ReadPassword", "Reads password from stdin", {},
Console_ReadPassword);
dict->DeclareFunction(gc, "Write", "Write text \"text\" to stdout",
{"text"}, Console_Write);
dict->DeclareFunction(gc, "WriteLine",
"Write text \"text\" to stdout with new line",
{"$text"}, Console_WriteLine);
dict->DeclareFunction(gc, "Error", "Write text \"error\" to stderr",
{"error"}, Console_Error);
dict->DeclareFunction(gc, "ErrorLine", "Write text \"error\" to stderr",
{"$error"}, Console_ErrorLine);
dict->DeclareFunction(gc, "ProgressBar", "Draw progressbar", {},
Console_ProgressBar);
dict->DeclareFunction(gc, "List", "Draw list", {"itemsitterator"},
Console_List);
if (env->permissions.canRegisterEverything)
dict->DeclareFunction(gc, "Fatal",
"Stop the program with an optional error message",
{"$text"}, Console_Fatal);
dict->DeclareFunction(gc, "getIn", "Get stdin Stream", {}, Console_getIn);
dict->DeclareFunction(gc, "getOut", "Get stdout Stream", {},
Console_getOut);
dict->DeclareFunction(gc, "getError", "Get stderr Stream", {},
Console_getError);
dict->DeclareFunction(gc, "getSize", "Get console size", {},
Console_getSize);
gc->BarrierBegin();
env->DeclareVariable("Console", dict);
auto _new = env->EnsureDictionary(gc, "New");
_new->DeclareFunction(
gc, "ConsoleReader", "Read from console", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleReader>();
});
_new->DeclareFunction(
gc, "ConsoleWriter", "Write to console", {"$isStderr"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
bool err;
if (GetArgument(args, 0, err))
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>(err);
return std::make_shared<
Tesses::Framework::TextStreams::ConsoleWriter>();
});
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang
#endif

View File

@@ -2,183 +2,173 @@
using namespace Tesses::Framework::Crypto;
namespace Tesses::CrossLang
{
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
{
int64_t size;
std::string personalStr;
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
{
namespace Tesses::CrossLang {
static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
std::vector<uint8_t> bytes;
bytes.resize((size_t)size);
if(RandomBytes(bytes,personalStr))
{
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return nullptr;
int64_t size;
std::string personalStr;
if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
std::vector<uint8_t> bytes;
bytes.resize((size_t)size);
if (RandomBytes(bytes, personalStr)) {
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return nullptr;
}
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args)
{
std::string pass;
TByteArray* bArraySalt;
int64_t itterations;
int64_t keylength;
int64_t shanum;
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
{
ShaVersion version = VERSION_SHA384;
switch(shanum)
{
case 1:
version = VERSION_SHA1;
break;
case 224:
version = VERSION_SHA224;
break;
case 256:
version = VERSION_SHA256;
break;
default:
case 384:
version = VERSION_SHA384;
break;
case 512:
version = VERSION_SHA512;
break;
}
return nullptr;
}
static TObject Crypto_PBKDF2(GCList &ls, std::vector<TObject> args) {
std::string pass;
TByteArray *bArraySalt;
int64_t itterations;
int64_t keylength;
int64_t shanum;
if (GetArgument(args, 0, pass) && GetArgumentHeap(args, 1, bArraySalt) &&
GetArgument(args, 2, itterations) && GetArgument(args, 3, keylength) &&
GetArgument(args, 4, shanum)) {
ShaVersion version = VERSION_SHA384;
std::vector<uint8_t> key;
key.resize((size_t)keylength);
if(PBKDF2(key,pass,bArraySalt->data,(long)itterations,version))
{
TByteArray* ba = TByteArray::Create(ls);
ba->data = key;
return ba;
}
switch (shanum) {
case 1:
version = VERSION_SHA1;
break;
case 224:
version = VERSION_SHA224;
break;
case 256:
version = VERSION_SHA256;
break;
default:
case 384:
version = VERSION_SHA384;
break;
case 512:
version = VERSION_SHA512;
break;
}
std::vector<uint8_t> key;
key.resize((size_t)keylength);
if (PBKDF2(key, pass, bArraySalt->data, (long)itterations, version)) {
TByteArray *ba = TByteArray::Create(ls);
ba->data = key;
return ba;
}
return nullptr;
}
return nullptr;
}
static TObject Crypto_Base64Encode(GCList &ls, std::vector<TObject> args) {
TByteArray *byteArray;
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
{
TByteArray* byteArray;
if(GetArgumentHeap(args,0,byteArray))
{
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
if (GetArgumentHeap(args, 0, byteArray)) {
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
}
return "";
}
static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
TByteArray *bArray = TByteArray::Create(ls);
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
}
return "";
}
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
TByteArray* bArray = TByteArray::Create(ls);
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
return bArray;
}
return nullptr;
}
void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
return bArray;
}
return nullptr;
}
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterCrypto = true;
if (!HaveCrypto())
return;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with PBKDF2",
{"pass", "salt", "itterations", "keylen", "shanum"},
Crypto_PBKDF2);
dict->DeclareFunction(gc, "RandomBytes",
"Create bytearray but with random bytes in it "
"instead of zeros (this uses mbedtls by the way)",
{"byteCount", "personalString"}, Crypto_RandomBytes);
env->permissions.canRegisterCrypto=true;
if(!HaveCrypto()) return;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(gc, "Base64Encode", "Base64 encode", {"data"},
Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
Crypto_Base64Decode);
dict->DeclareFunction(
gc, "Sha1",
"Hash with sha1 algorithm (please don't use sha1 unless you need to)",
{"strm"}, [](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
if(GetArgument(args, 0, sho))
{
if (GetArgument(args, 0, sho)) {
auto bytes = Sha1::ComputeHash(sho);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes =
Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(
gc, "Sha256", "Hash with sha256 algorithm", {"strm", "$is224"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is224=false;
GetArgument(args,1,is224);
bool is224 = false;
GetArgument(args, 1, is224);
if(GetArgument(args, 0, sho))
{
auto bytes = Sha256::ComputeHash(sho,is224);
if (GetArgument(args, 0, sho)) {
auto bytes = Sha256::ComputeHash(sho, is224);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224);
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes = Sha256::ComputeHash(baSrc->data.data(),
baSrc->data.size(), is224);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject {
TByteArray* baSrc;
dict->DeclareFunction(
gc, "Sha512", "Hash with sha512 algorithm", {"strm", "$is384"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
TByteArray *baSrc;
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
bool is384=false;
GetArgument(args,1,is384);
bool is384 = false;
GetArgument(args, 1, is384);
if(GetArgument(args, 0, sho))
{
auto bytes = Sha512::ComputeHash(sho,is384);
if (GetArgument(args, 0, sho)) {
auto bytes = Sha512::ComputeHash(sho, is384);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
if(GetArgumentHeap(args,0,baSrc))
{
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384);
if (GetArgumentHeap(args, 0, baSrc)) {
auto bytes = Sha512::ComputeHash(baSrc->data.data(),
baSrc->data.size(), is384);
auto ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("Crypto", dict);
gc->BarrierEnd();
}
gc->BarrierBegin();
env->DeclareVariable("Crypto", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,149 +1,137 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TObject Dictionary_FindByKey(GCList& ls, std::vector<TObject> args)
{
TList* dest = TList::Create(ls);
ls.GetGC()->BarrierBegin();
std::string key;
if(GetArgument(args,1,key))
{
namespace Tesses::CrossLang {
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
TList *dest = TList::Create(ls);
ls.GetGC()->BarrierBegin();
std::string key;
if (GetArgument(args, 1, key)) {
std::function<void(TObject)> crawl;
crawl = [&](TObject o) -> void {
TDictionary* dict;
TList* list;
TAssociativeArray* aa;
if(GetObjectHeap(o,aa))
{
std::string k0;
for(auto& item : aa->items)
{
if(GetObject(item.first,k0) && k0 == key) dest->Add(item.second);
crawl(item.second);
}
std::function<void(TObject)> crawl;
crawl = [&](TObject o) -> void {
TDictionary *dict;
TList *list;
TAssociativeArray *aa;
if (GetObjectHeap(o, aa)) {
std::string k0;
for (auto &item : aa->items) {
if (GetObject(item.first, k0) && k0 == key)
dest->Add(item.second);
crawl(item.second);
}
if(GetObjectHeap(o,dict))
{
for(auto& item : dict->items)
{
if(item.first == key) dest->Add(item.second);
crawl(item.second);
}
}
if (GetObjectHeap(o, dict)) {
for (auto &item : dict->items) {
if (item.first == key)
dest->Add(item.second);
crawl(item.second);
}
if(GetObjectHeap(o,list))
{
for(auto& item : list->items)
{
crawl(item);
}
}
if (GetObjectHeap(o, list)) {
for (auto &item : list->items) {
crawl(item);
}
};
crawl(args[0]);
}
ls.GetGC()->BarrierEnd();
return dest;
}
};
crawl(args[0]);
}
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
if(GetArgumentHeap(args,0,dynDict))
{
TDictionary* enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
ls.GetGC()->BarrierEnd();
return dest;
}
TObject Dictionary_Items(GCList &ls, std::vector<TObject> args) {
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
TDictionary *dict;
TDynamicDictionary *dynDict;
if (GetArgumentHeap(args, 0, dynDict)) {
TDictionary *enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
auto fn = TExternalMethod::Create(
ls, "Get Enumerator for Dictionary", {},
[dynDict](GCList &ls2, std::vector<TObject> args) -> TObject {
return dynDict->GetEnumerator(ls2);
});
fn->watch.push_back(dynDict);
enumerableItem->SetValue("GetEnumerator", fn);
ls.GetGC()->BarrierEnd();
fn->watch.push_back(dynDict);
return enumerableItem;
}
if(GetArgumentHeap(args,0,dict))
{
TDictionary* enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
enumerableItem->SetValue("GetEnumerator", fn);
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
return TDictionaryEnumerator::Create(ls2,dict);
ls.GetGC()->BarrierEnd();
return enumerableItem;
}
if (GetArgumentHeap(args, 0, dict)) {
TDictionary *enumerableItem = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
auto fn = TExternalMethod::Create(
ls, "Get Enumerator for Dictionary", {"dict"},
[dict](GCList &ls2, std::vector<TObject> args) -> TObject {
return TDictionaryEnumerator::Create(ls2, dict);
});
fn->watch.push_back(dict);
enumerableItem->SetValue("GetEnumerator", fn);
fn->watch.push_back(dict);
enumerableItem->SetValue("GetEnumerator", fn);
ls.GetGC()->BarrierEnd();
return enumerableItem;
}
return Undefined();
}
TObject Dictionary_GetField(GCList &ls, std::vector<TObject> args) {
TDictionary *dict;
TDynamicDictionary *dynDict;
std::string key;
if (GetArgument(args, 1, key)) {
if (GetArgumentHeap(args, 0, dict)) {
ls.GetGC()->BarrierBegin();
auto res = dict->GetValue(key);
ls.GetGC()->BarrierEnd();
return enumerableItem;
return res;
} else if (GetArgumentHeap(args, 0, dynDict)) {
return dynDict->GetField(ls, key);
}
return Undefined();
}
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
std::string key;
if(GetArgument(args,1,key))
{
if(GetArgumentHeap(args,0,dict))
{
ls.GetGC()->BarrierBegin();
auto res = dict->GetValue(key);
ls.GetGC()->BarrierEnd();
return res;
}
else if(GetArgumentHeap(args,0,dynDict))
{
return dynDict->GetField(ls,key);
}
return nullptr;
}
TObject Dictionary_SetField(GCList &ls, std::vector<TObject> args) {
TDictionary *dict;
TDynamicDictionary *dynDict;
std::string key;
if (args.size() == 3 && GetArgument(args, 1, key)) {
if (GetArgumentHeap(args, 0, dict)) {
ls.GetGC()->BarrierBegin();
dict->SetValue(key, args[2]);
ls.GetGC()->BarrierEnd();
} else if (GetArgumentHeap(args, 0, dynDict)) {
dynDict->SetField(ls, key, args[2]);
}
return nullptr;
}
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
{
TDictionary* dict;
TDynamicDictionary* dynDict;
std::string key;
if(args.size() == 3 && GetArgument(args,1,key))
{
if(GetArgumentHeap(args,0,dict))
{
ls.GetGC()->BarrierBegin();
dict->SetValue(key,args[2]);
ls.GetGC()->BarrierEnd();
}
else if(GetArgumentHeap(args,0,dynDict))
{
dynDict->SetField(ls,key,args[2]);
}
}
return nullptr;
}
void TStd::RegisterDictionary(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
void TStd::RegisterDictionary(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterDictionary=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
env->permissions.canRegisterDictionary = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc, "FindByKey","Scan object recursively, return list of items with key",{"obj","key"}, Dictionary_FindByKey);
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
gc->BarrierBegin();
dict->DeclareFunction(
gc, "FindByKey",
"Scan object recursively, return list of items with key",
{"obj", "key"}, Dictionary_FindByKey);
dict->DeclareFunction(gc, "Items",
"Get Dictionary Item Enumerable, for the each(item : "
"Dictionary.Items(myDict)){item.Key; item.Value;}",
{"dictionary"}, Dictionary_Items);
dict->DeclareFunction(gc, "SetField", "Set a field in dictionary",
{"dict", "key", "value"}, Dictionary_SetField);
dict->DeclareFunction(gc, "GetField", "Get a field in dictionary",
{"dict", "key"}, Dictionary_GetField);
env->DeclareVariable("Dictionary", dict);
gc->BarrierEnd();
}
}
env->DeclareVariable("Dictionary", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -5,165 +5,152 @@
#include <windows.h>
#endif
namespace Tesses::CrossLang
{
using namespace Tesses::Framework::Platform::Environment;
#if defined(_WIN32)
static char EnvPathSeperator=';';
#else
static char EnvPathSeperator=':';
#endif
namespace Tesses::CrossLang {
using namespace Tesses::Framework::Platform::Environment;
#if defined(_WIN32)
static char EnvPathSeperator = ';';
#else
static char EnvPathSeperator = ':';
#endif
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir()
{
if(!CrossLangConfigPath.path.empty())
return CrossLangConfigPath;
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
}
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir() {
if (!CrossLangConfigPath.path.empty())
return CrossLangConfigPath;
static TObject Env_getCrossLangConfig(GCList& ls, std::vector<TObject> args)
{
return GetCrossLangConfigDir();
}
static TObject Env_getPlatform(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Platform::Environment::GetPlatform();
}
static TObject Env_GetAt(GCList& ls, std::vector<TObject> args)
{
std::string key;
if(GetArgument(args,0,key))
{
auto v = GetVariable(key);
if(v) return v.value();
}
return nullptr;
}
static TObject Env_SetAt(GCList& ls, std::vector<TObject> args)
{
std::string key;
std::string value;
if(GetArgument(args,0,key))
{
if(GetArgument(args,1,value))
{
SetVariable(key,value);
return value;
}
else
{
SetVariable(key,std::nullopt);
}
}
return nullptr;
}
static TObject Env_getDownloads(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDownloads();
}
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetMusic();
}
static TObject Env_getPictures(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetPictures();
}
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetVideos();
}
static TObject Env_getDocuments(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDocuments();
}
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetConfig();
}
static TObject Env_getDesktop(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetDesktop();
}
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetState();
}
static TObject Env_getCache(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetCache();
}
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetData();
}
static TObject Env_getUser(GCList& ls, std::vector<TObject> args)
{
return SpecialFolders::GetHomeFolder();
}
static TObject Env_GetRealExecutablePath(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p))
{
return GetRealExecutablePath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
}
static TObject Env_GetAll(GCList& ls, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
TList* list = TList::Create(ls);
std::vector<std::pair<std::string, std::string>> env;
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
for(auto& item : env)
{
list->Add(TDictionary::Create(ls,{TDItem("Key",item.first),TDItem("Value",item.second)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Env_getLittleEndian(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
}
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
env->permissions.canRegisterEnv=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"GetAt","Get environment variable", {"key"}, Env_GetAt);
dict->DeclareFunction(gc,"SetAt","Set environment variable", {"key","value"}, Env_SetAt);
dict->DeclareFunction(gc,"GetAll","Get all of the environment variables",{},Env_GetAll);
dict->DeclareFunction(gc,"getDesktop","Get desktop folder",{},Env_getDesktop);
dict->DeclareFunction(gc,"getDownloads","Get downloads folder",{},Env_getDownloads);
dict->DeclareFunction(gc,"getDocuments","Get documents folder",{},Env_getDocuments);
dict->DeclareFunction(gc,"getMusic","Get music folder",{},Env_getMusic);
dict->DeclareFunction(gc,"getPictures","Get pictures folder",{},Env_getPictures);
dict->DeclareFunction(gc,"getVideos","Get videos folder",{},Env_getVideos);
dict->DeclareFunction(gc,"getState","Get state folder",{},Env_getState);
dict->DeclareFunction(gc,"getCache","Get cache folder",{},Env_getCache);
dict->DeclareFunction(gc,"getConfig","Get config folder",{},Env_getConfig);
dict->DeclareFunction(gc,"getCrossLangConfig","Get crosslang configuration folder",{}, Env_getCrossLangConfig);
dict->DeclareFunction(gc,"getData","Get data folder",{},Env_getData);
dict->DeclareFunction(gc,"getUser","Get user folder",{},Env_getUser);
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
dict->DeclareFunction(gc, "getLittleEndian", "Is the platform little endian", {},Env_getLittleEndian);
gc->BarrierBegin();
dict->SetValue("EnvPathSeperator",EnvPathSeperator);
env->SetVariable("Env", dict);
gc->BarrierEnd();
}
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
}
static TObject Env_getCrossLangConfig(GCList &ls, std::vector<TObject> args) {
return GetCrossLangConfigDir();
}
static TObject Env_getPlatform(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Platform::Environment::GetPlatform();
}
static TObject Env_GetAt(GCList &ls, std::vector<TObject> args) {
std::string key;
if (GetArgument(args, 0, key)) {
auto v = GetVariable(key);
if (v)
return v.value();
}
return nullptr;
}
static TObject Env_SetAt(GCList &ls, std::vector<TObject> args) {
std::string key;
std::string value;
if (GetArgument(args, 0, key)) {
if (GetArgument(args, 1, value)) {
SetVariable(key, value);
return value;
} else {
SetVariable(key, std::nullopt);
}
}
return nullptr;
}
static TObject Env_getDownloads(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDownloads();
}
static TObject Env_getMusic(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetMusic();
}
static TObject Env_getPictures(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetPictures();
}
static TObject Env_getVideos(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetVideos();
}
static TObject Env_getDocuments(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDocuments();
}
static TObject Env_getConfig(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetConfig();
}
static TObject Env_getDesktop(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetDesktop();
}
static TObject Env_getState(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetState();
}
static TObject Env_getCache(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetCache();
}
static TObject Env_getData(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetData();
}
static TObject Env_getUser(GCList &ls, std::vector<TObject> args) {
return SpecialFolders::GetHomeFolder();
}
static TObject Env_GetRealExecutablePath(GCList &ls,
std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath p;
if (GetArgumentAsPath(args, 0, p)) {
return GetRealExecutablePath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
}
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
ls.GetGC()->BarrierBegin();
TList *list = TList::Create(ls);
std::vector<std::pair<std::string, std::string>> env;
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
for (auto &item : env) {
list->Add(TDictionary::Create(
ls, {TDItem("Key", item.first), TDItem("Value", item.second)}));
}
ls.GetGC()->BarrierEnd();
return list;
}
static TObject Env_getLittleEndian(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
}
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterEnv = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetAt", "Get environment variable", {"key"},
Env_GetAt);
dict->DeclareFunction(gc, "SetAt", "Set environment variable",
{"key", "value"}, Env_SetAt);
dict->DeclareFunction(gc, "GetAll", "Get all of the environment variables",
{}, Env_GetAll);
dict->DeclareFunction(gc, "getDesktop", "Get desktop folder", {},
Env_getDesktop);
dict->DeclareFunction(gc, "getDownloads", "Get downloads folder", {},
Env_getDownloads);
dict->DeclareFunction(gc, "getDocuments", "Get documents folder", {},
Env_getDocuments);
dict->DeclareFunction(gc, "getMusic", "Get music folder", {}, Env_getMusic);
dict->DeclareFunction(gc, "getPictures", "Get pictures folder", {},
Env_getPictures);
dict->DeclareFunction(gc, "getVideos", "Get videos folder", {},
Env_getVideos);
dict->DeclareFunction(gc, "getState", "Get state folder", {}, Env_getState);
dict->DeclareFunction(gc, "getCache", "Get cache folder", {}, Env_getCache);
dict->DeclareFunction(gc, "getConfig", "Get config folder", {},
Env_getConfig);
dict->DeclareFunction(gc, "getCrossLangConfig",
"Get crosslang configuration folder", {},
Env_getCrossLangConfig);
dict->DeclareFunction(gc, "getData", "Get data folder", {}, Env_getData);
dict->DeclareFunction(gc, "getUser", "Get user folder", {}, Env_getUser);
dict->DeclareFunction(gc, "getPlatform", "Get platform name", {},
Env_getPlatform);
dict->DeclareFunction(gc, "GetRealExecutablePath",
"Get the absolute path for executable", {"path"},
Env_GetRealExecutablePath);
dict->DeclareFunction(gc, "getLittleEndian",
"Is the platform little endian", {},
Env_getLittleEndian);
gc->BarrierBegin();
dict->SetValue("EnvPathSeperator", EnvPathSeperator);
env->SetVariable("Env", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,57 +1,53 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TObject Helpers_CopyToProgress(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
double precision=1000.0;
TCallable* callable;
if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable))
{
GetArgument(args,3,precision);
auto len = src->GetLength();
callable->Call(ls,{0.0});
if(len > 0)
{
std::vector<uint8_t> buff(1024);
int64_t pos=0;
int curPercent=0;
int lastPercent=0;
size_t read = 0;
do {
read = src->ReadBlock(buff.data(),buff.size());
dest->WriteBlock(buff.data(),read);
static TObject Helpers_CopyToProgress(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
double precision = 1000.0;
TCallable *callable;
if (GetArgument(args, 0, src) && GetArgument(args, 1, dest) &&
GetArgumentHeap(args, 2, callable)) {
GetArgument(args, 3, precision);
auto len = src->GetLength();
callable->Call(ls, {0.0});
if (len > 0) {
std::vector<uint8_t> buff(1024);
int64_t pos = 0;
int curPercent = 0;
int lastPercent = 0;
size_t read = 0;
do {
read = src->ReadBlock(buff.data(), buff.size());
dest->WriteBlock(buff.data(), read);
if(read == 0) break;
pos += (int64_t)read;
if (read == 0)
break;
pos += (int64_t)read;
double percent = ((double)pos / len);
percent *= precision;
curPercent = (int)percent;
double percent = ((double)pos / len);
percent *= precision;
if(curPercent > lastPercent)
{
lastPercent = curPercent;
callable->Call(ls,{curPercent/precision});
}
curPercent = (int)percent;
if (curPercent > lastPercent) {
lastPercent = curPercent;
callable->Call(ls, {curPercent / precision});
}
} while(read != 0);
}
else {
src->CopyTo(dest);
}
callable->Call(ls,{1.0});
} while (read != 0);
} else {
src->CopyTo(dest);
}
return Undefined();
callable->Call(ls, {1.0});
}
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
auto helpers=env->EnsureDictionary(gc,"Helpers");
helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB","$precision"},Helpers_CopyToProgress);
}
}
return Undefined();
}
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment *env) {
auto helpers = env->EnsureDictionary(gc, "Helpers");
helpers->DeclareFunction(gc, "CopyToProgress",
"Copy Stream to another (but with progress event)",
{"src", "dest", "progressCB", "$precision"},
Helpers_CopyToProgress);
}
} // namespace Tesses::CrossLang

View File

@@ -1,322 +1,341 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
static TObject FS_CreateArchive(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
namespace Tesses::CrossLang
{
static TObject FS_CreateArchive(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::string name;
std::string version;
std::string info;
std::string icon="";
TVMVersion version2;
std::string name;
std::string version;
std::string info;
std::string icon = "";
TVMVersion version2;
if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2)))
{
GetArgument(args,5,icon);
CrossArchiveCreate(vfs,strm,name,version2,info,icon);
}
return nullptr;
if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
((GetArgument(args, 3, version) &&
TVMVersion::TryParse(version, version2)) ||
GetArgument(args, 3, version2))) {
GetArgument(args, 5, icon);
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
}
static TObject FS_ExtractArchive(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs))
{
auto res = CrossArchiveExtract(strm,vfs);
return nullptr;
}
static TObject FS_ExtractArchive(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Name",res.first.first);
dict->SetValue("Version",res.first.second.ToString());
dict->SetValue("Info",res.second);
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
auto res = CrossArchiveExtract(strm, vfs);
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Name", res.first.first);
dict->SetValue("Version", res.first.second.ToString());
dict->SetValue("Info", res.second);
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
}
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
static TObject FS_ReadAllText(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
}
return "";
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs, path);
}
return "";
}
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
static TObject FS_ReadAllLines(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
std::vector<std::string> lines;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines);
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
std::vector<std::string> lines;
ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls);
for(auto& l : lines) { items->Add(l);}
ls.GetGC()->BarrierEnd();
return items;
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
ls.GetGC()->BarrierBegin();
auto items = TList::Create(ls);
for (auto &l : lines) {
items->Add(l);
}
return nullptr;
ls.GetGC()->BarrierEnd();
return items;
}
return nullptr;
}
static TObject FS_ReadAllBytes(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
auto res = TByteArray::Create(ls);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
return res;
}
return nullptr;
static TObject FS_ReadAllBytes(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
auto res = TByteArray::Create(ls);
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
res->data);
return res;
}
return nullptr;
}
static TObject FS_WriteAllLines(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
static TObject FS_WriteAllLines(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TList* lines;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines))
{
std::vector<std::string> content;
ls.GetGC()->BarrierBegin();
for(auto& item : lines->items)
{
if(std::holds_alternative<std::string>(item))
TList *lines;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
GetArgumentHeap(args, 2, lines)) {
std::vector<std::string> content;
ls.GetGC()->BarrierBegin();
for (auto &item : lines->items) {
if (std::holds_alternative<std::string>(item))
content.push_back(std::get<std::string>(item));
}
ls.GetGC()->BarrierEnd();
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs, path,
content);
}
return nullptr;
}
static TObject FS_WriteAllText(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::string content;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
GetArgument(args, 2, content)) {
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
content);
}
return nullptr;
}
static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TByteArray *bArray;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
GetArgumentHeap(args, 2, bArray)) {
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
bArray->data);
}
return nullptr;
}
class FS_Watcher : public TNativeObject {
public:
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
FS_Watcher(
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
: watcher(watcher) {}
TObject CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
if (name == "getPath") {
return watcher->GetPath();
}
if (name == "getFilesystem") {
return watcher->GetFilesystem();
}
if (name == "setEnabled") {
bool enabled;
if (GetArgument(args, 0, enabled)) {
watcher->SetEnabled(enabled);
return enabled;
}
ls.GetGC()->BarrierEnd();
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content);
}
return nullptr;
}
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::string content;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
{
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
if (name == "getEnabled") {
return watcher->GetEnabled();
}
return nullptr;
}
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
TByteArray* bArray;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
{
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
if (name == "setEvents") {
int64_t evts;
if (GetArgument(args, 0, evts)) {
watcher->events =
(Tesses::Framework::Filesystem::FSWatcherEventType)evts;
return evts;
}
}
return nullptr;
}
class FS_Watcher : public TNativeObject {
public:
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher)
{}
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
{
if(name == "getPath")
{
return watcher->GetPath();
}
if(name == "getFilesystem")
{
return watcher->GetFilesystem();
}
if(name == "setEnabled")
{
bool enabled;
if(GetArgument(args,0,enabled))
{
watcher->SetEnabled(enabled);
return enabled;
}
}
if(name == "getEnabled")
{
return watcher->GetEnabled();
}
if(name == "setEvents")
{
int64_t evts;
if(GetArgument(args,0,evts))
{
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
return evts;
}
}
if(name == "getEvents")
{
return (int64_t)watcher->events;
}
if(name == "setCallback")
{
TCallable* callable=nullptr;
if(GetArgumentHeap(args,0,callable))
{
auto markedT = CreateMarkedTObject(ls,callable);
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void {
GCList ls(markedT->GetGC());
TObject o = markedT->GetObject();
TCallable* callable;
if(GetObjectHeap(o,callable))
{
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
{
if (name == "getEvents") {
return (int64_t)watcher->events;
}
if (name == "setCallback") {
TCallable *callable = nullptr;
if (GetArgumentHeap(args, 0, callable)) {
auto markedT = CreateMarkedTObject(ls, callable);
watcher->event =
[markedT](
Tesses::Framework::Filesystem::FSWatcherEvent &evt)
-> void {
GCList ls(markedT->GetGC());
TObject o = markedT->GetObject();
TCallable *callable;
if (GetObjectHeap(o, callable)) {
auto isEvent = TExternalMethod::Create(
ls, "", {},
[evt](GCList &ls,
std::vector<TObject> args) -> TObject {
int64_t n;
if(GetArgument(args,0,n))
{
if (GetArgument(args, 0, n)) {
auto myevt = evt;
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n);
return myevt.IsEvent(
(Tesses::Framework::Filesystem::
FSWatcherEventType)n);
}
return false;
});
auto toString = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
{
auto toString = TExternalMethod::Create(
ls, "", {},
[evt](GCList &ls,
std::vector<TObject> args) -> TObject {
auto myevt = evt;
return myevt.ToString();
});
auto dict = TDictionary::Create(ls, {TDItem("IsDirectory",evt.isDir),TDItem("Type",(int64_t)evt.type),TDItem("Source",evt.src), TDItem("Destination",evt.dest),TDItem("ToString",toString),TDItem("IsEvent",isEvent)});
callable->Call(ls,{dict});
}
};
auto dict = TDictionary::Create(
ls, {TDItem("IsDirectory", evt.isDir),
TDItem("Type", (int64_t)evt.type),
TDItem("Source", evt.src),
TDItem("Destination", evt.dest),
TDItem("ToString", toString),
TDItem("IsEvent", isEvent)});
callable->Call(ls, {dict});
}
else {
watcher->event=nullptr;
}
return nullptr;
}
if(name == "Start")
{
watcher->SetEnabled(true);
}
if(name == "Stop")
{
watcher->SetEnabled(false);
}
if(name == "ToString")
{
return "FSWatcher";
}
return Undefined();
};
} else {
watcher->event = nullptr;
}
std::string TypeName() {
return "FSWatcher";
}
};
TObject New_FSWatcher(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path));
return nullptr;
}
return nullptr;
if (name == "Start") {
watcher->SetEnabled(true);
}
if (name == "Stop") {
watcher->SetEnabled(false);
}
if (name == "ToString") {
return "FSWatcher";
}
return Undefined();
}
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env, bool enable)
{
if(enable)
{
RegisterIO(gc,env,std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else
{
RegisterIO(gc,env,nullptr);
}
std::string TypeName() { return "FSWatcher"; }
};
TObject New_FSWatcher(GCList &ls, std::vector<TObject> args) {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
return TNativeObject::Create<FS_Watcher>(
ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
}
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env,std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs)
{
return nullptr;
}
void TStd::RegisterIO(std::shared_ptr<GC> gc, TRootEnvironment *env,
bool enable) {
if (enable) {
RegisterIO(
gc, env,
std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(
Tesses::Framework::Filesystem::LocalFS,
Tesses::Framework::Filesystem::VFSPath::
GetAbsoluteCurrentDirectory()));
} else {
RegisterIO(gc, env, nullptr);
}
}
void TStd::RegisterIO(
std::shared_ptr<GC> gc, TRootEnvironment *env,
std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
env->permissions.canRegisterIO=true;
env->permissions.localfs = fs;
GCList ls(gc);
gc->BarrierBegin();
auto newDict = env->EnsureDictionary(gc, "New");
newDict->DeclareFunction(gc,"FSWatcher","Watch a file/directory",{"vfs","path"}, New_FSWatcher);
auto dict = env->EnsureDictionary(gc,"FS");
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls,
{
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None),
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed),
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged),
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read),
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created),
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted),
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted),
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified),
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved),
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld),
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew),
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All)
}
));
env->permissions.canRegisterIO = true;
env->permissions.localfs = fs;
GCList ls(gc);
if(fs)
{
dict->SetValue("Local", fs);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{
gc->BarrierBegin();
auto newDict = env->EnsureDictionary(gc, "New");
newDict->DeclareFunction(gc, "FSWatcher", "Watch a file/directory",
{"vfs", "path"}, New_FSWatcher);
auto dict = env->EnsureDictionary(gc, "FS");
dict->SetValue("SEEK_SET",
(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
dict->SetValue("SEEK_CUR",
(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
dict->SetValue("SEEK_END",
(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
dict->SetValue(
"FSWatcherEvents",
TDictionary::Create(
ls,
{TDItem(
"None",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::None),
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Accessed),
TDItem("AttributeChanged",
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
AttributeChanged),
TDItem(
"Writen",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
TDItem(
"Read",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Read),
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Created),
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Deleted),
TDItem("WatchEntryDeleted",
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
WatchEntryDeleted),
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::Modified),
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::WatchEntryMoved),
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::MoveOld),
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::
FSWatcherEventType::MoveNew),
TDItem(
"Opened",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
TDItem(
"Closed",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
TDItem(
"Moved",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
TDItem(
"All",
(int64_t)
Tesses::Framework::Filesystem::FSWatcherEventType::All)}));
if (fs) {
dict->SetValue("Local", fs);
dict->DeclareFunction(
gc, "MakeFull", "Make absolute path from relative path", {"path"},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
if (GetArgumentAsPath(args, 0, path)) {
if (path.relative) {
auto myPath = fs->GetWorking() / path;
myPath = myPath.CollapseRelativeParents();
return myPath;
@@ -325,37 +344,47 @@ namespace Tesses::CrossLang
}
return nullptr;
});
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},[fs](GCList& ls, std::vector<TObject> args)->TObject{
dict->DeclareFunction(
gc, "getCurrentPath", "Get current path", {},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
return fs->GetWorking();
});
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"}, [fs](GCList& ls, std::vector<TObject> args)->TObject {
dict->DeclareFunction(
gc, "setCurrentPath", "Set the current path", {"path"},
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
}
else {
fs->SetWorking(path);
}
if (GetArgumentAsPath(args, 0, path)) {
if (path.relative) {
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
} else {
fs->SetWorking(path);
}
}
return path;
});
}
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
dict->DeclareFunction(gc, "ReadAllLines","Read all lines from file", {"fs","filename"},FS_ReadAllLines);
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines);
dict->DeclareFunction(gc, "ReadAllBytes","Read all bytes from file", {"fs","filename"},FS_ReadAllBytes);
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes);
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",{"fs","strm","name","version","info"},FS_CreateArchive);
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive);
gc->BarrierEnd();
}
}
dict->DeclareFunction(gc, "ReadAllText", "Read all text from file",
{"fs", "filename"}, FS_ReadAllText);
dict->DeclareFunction(gc, "WriteAllText", "Write all text to file",
{"fs", "filename", "content"}, FS_WriteAllText);
dict->DeclareFunction(gc, "ReadAllLines", "Read all lines from file",
{"fs", "filename"}, FS_ReadAllLines);
dict->DeclareFunction(gc, "WriteAllLines", "Write all lines to file",
{"fs", "filename", "lines"}, FS_WriteAllLines);
dict->DeclareFunction(gc, "ReadAllBytes", "Read all bytes from file",
{"fs", "filename"}, FS_ReadAllBytes);
dict->DeclareFunction(gc, "WriteAllBytes", "Write all bytes to file",
{"fs", "filename", "content"}, FS_WriteAllBytes);
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",
{"fs", "strm", "name", "version", "info"},
FS_CreateArchive);
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
{"strm", "vfs"}, FS_ExtractArchive);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -2,206 +2,193 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework::Serialization::Json;
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
static bool IsValidForJson(TObject v)
{
if(std::holds_alternative<std::nullptr_t>(v)) return true;
static bool IsValidForJson(TObject v) {
if (std::holds_alternative<std::nullptr_t>(v))
return true;
if(std::holds_alternative<int64_t>(v)) return true;
if (std::holds_alternative<int64_t>(v))
return true;
if(std::holds_alternative<double>(v)) return true;
if (std::holds_alternative<double>(v))
return true;
if (std::holds_alternative<bool>(v))
return true;
if(std::holds_alternative<bool>(v)) return true;
if (std::holds_alternative<std::string>(v))
return true;
if(std::holds_alternative<std::string>(v)) return true;
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto res = std::get<THeapObjectHolder>(v);
auto ls = dynamic_cast<TList*>(res.obj);
auto dict = dynamic_cast<TDictionary*>(res.obj);
if(ls != nullptr) return true;
if(dict != nullptr) return true;
}
return false;
if (std::holds_alternative<THeapObjectHolder>(v)) {
auto res = std::get<THeapObjectHolder>(v);
auto ls = dynamic_cast<TList *>(res.obj);
auto dict = dynamic_cast<TDictionary *>(res.obj);
if (ls != nullptr)
return true;
if (dict != nullptr)
return true;
}
static JToken JsonSerialize(TObject v)
{
if(std::holds_alternative<std::nullptr_t>(v)) return nullptr;
if(std::holds_alternative<int64_t>(v)) return std::get<int64_t>(v);
if(std::holds_alternative<double>(v)) return std::get<double>(v);
if(std::holds_alternative<bool>(v)) return std::get<bool>(v);
if(std::holds_alternative<std::string>(v)) return std::get<std::string>(v);
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto obj = std::get<THeapObjectHolder>(v).obj;
auto ls = dynamic_cast<TList*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
if(ls != nullptr)
{
JArray items;
for(int64_t i = 0; i < ls->Count(); i++)
{
auto val = ls->Get(i);
if(IsValidForJson(val))
items.Add(JsonSerialize(val));
}
return items;
}
if(dict != nullptr)
{
JObject obj;
for(auto item : dict->items)
{
if(IsValidForJson(item.second))
obj.SetValue(item.first,JsonSerialize(item.second));
}
return obj;
}
}
return false;
}
static JToken JsonSerialize(TObject v) {
if (std::holds_alternative<std::nullptr_t>(v))
return nullptr;
}
static TObject JsonEncode(GCList& ls2, std::vector<TObject> args)
{
if(args.size() >= 1)
{
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
if (std::holds_alternative<int64_t>(v))
return std::get<int64_t>(v);
if (std::holds_alternative<double>(v))
return std::get<double>(v);
if (std::holds_alternative<bool>(v))
return std::get<bool>(v);
if (std::holds_alternative<std::string>(v))
return std::get<std::string>(v);
if (std::holds_alternative<THeapObjectHolder>(v)) {
auto obj = std::get<THeapObjectHolder>(v).obj;
auto ls = dynamic_cast<TList *>(obj);
auto dict = dynamic_cast<TDictionary *>(obj);
return Json::Encode(json,indent);
}
return "null";
}
static TObject JsonDocEncode(GCList& ls2, std::vector<TObject> args)
{
if(args.size() >= 1)
{
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
JArray ar;
if(TryGetJToken(json,ar))
return Json::DocEncode(ar,indent);
}
return "";
}
static TObject JsonDeserialize(GCList& ls2,JToken json)
{
if(std::holds_alternative<JUndefined>(json)) return nullptr;
if(std::holds_alternative<std::nullptr_t>(json)) return nullptr;
bool b;
int64_t _i64;
double _f64;
std::string str;
JArray arr;
JObject obj;
if(TryGetJToken(json,b)) return b;
if(TryGetJToken(json,_i64)) return _i64;
if(TryGetJToken(json,_f64)) return _f64;
if(TryGetJToken(json,str)) return str;
if(TryGetJToken(json,arr))
{
TList* ls = TList::Create(ls2);
for(auto& item : arr)
{
auto itemRes = JsonDeserialize(ls2,item);
ls2.GetGC()->BarrierBegin();
ls->Add(itemRes);
ls2.GetGC()->BarrierEnd();
if (ls != nullptr) {
JArray items;
for (int64_t i = 0; i < ls->Count(); i++) {
auto val = ls->Get(i);
if (IsValidForJson(val))
items.Add(JsonSerialize(val));
}
return ls;
return items;
}
if(TryGetJToken(json,obj))
{
TDictionary* dict = TDictionary::Create(ls2);
for(auto& item : obj)
{
auto itemRes = JsonDeserialize(ls2,item.second);
ls2.GetGC()->BarrierBegin();
dict->SetValue(item.first,itemRes);
ls2.GetGC()->BarrierEnd();
if (dict != nullptr) {
JObject obj;
for (auto item : dict->items) {
if (IsValidForJson(item.second))
obj.SetValue(item.first, JsonSerialize(item.second));
}
return dict;
return obj;
}
return Undefined();
}
static TObject JsonDecode(GCList& ls2,std::vector<TObject> args)
{
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
{
return JsonDeserialize(ls2, Json::Decode(std::get<std::string>(args[0])));
}
return Undefined();
}
static TObject JsonDocDecode(GCList& ls2,std::vector<TObject> args)
{
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
{
return JsonDeserialize(ls2, Json::DocDecode(std::get<std::string>(args[0])));
}
return Undefined();
}
std::string Json_Encode(TObject o,bool indent)
{
return Json::Encode(JsonSerialize(o),indent);
}
TObject Json_Decode(GCList ls,std::string str)
{
return JsonDeserialize(ls,Json::Decode(str));
}
std::string Json_DocEncode(TObject o,bool indent)
{
auto obj = JsonSerialize(o);
JArray ls;
if(TryGetJToken(obj,ls))
return Json::DocEncode(ls,indent);
return "";
}
TObject Json_DocDecode(GCList ls,std::string str)
{
return JsonDeserialize(ls,Json::DocDecode(str));
}
void TStd::RegisterJson(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
static TObject JsonEncode(GCList &ls2, std::vector<TObject> args) {
if (args.size() >= 1) {
bool indent =
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
std::get<bool>(args[1]));
env->permissions.canRegisterJSON=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "Decode","Deserialize Json",{"jsonString"},JsonDecode);
dict->DeclareFunction(gc, "Encode","Serialize Json",{"any","$indent"},JsonEncode);
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc", {"jsonDocString"},JsonDocDecode);
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc", {"ls","$indent"},JsonDocEncode);
gc->BarrierBegin();
env->DeclareVariable("Json", dict);
gc->BarrierEnd();
auto json = JsonSerialize(args[0]);
return Json::Encode(json, indent);
}
}
return "null";
}
static TObject JsonDocEncode(GCList &ls2, std::vector<TObject> args) {
if (args.size() >= 1) {
bool indent =
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
std::get<bool>(args[1]));
auto json = JsonSerialize(args[0]);
JArray ar;
if (TryGetJToken(json, ar))
return Json::DocEncode(ar, indent);
}
return "";
}
static TObject JsonDeserialize(GCList &ls2, JToken json) {
if (std::holds_alternative<JUndefined>(json))
return nullptr;
if (std::holds_alternative<std::nullptr_t>(json))
return nullptr;
bool b;
int64_t _i64;
double _f64;
std::string str;
JArray arr;
JObject obj;
if (TryGetJToken(json, b))
return b;
if (TryGetJToken(json, _i64))
return _i64;
if (TryGetJToken(json, _f64))
return _f64;
if (TryGetJToken(json, str))
return str;
if (TryGetJToken(json, arr)) {
TList *ls = TList::Create(ls2);
for (auto &item : arr) {
auto itemRes = JsonDeserialize(ls2, item);
ls2.GetGC()->BarrierBegin();
ls->Add(itemRes);
ls2.GetGC()->BarrierEnd();
}
return ls;
}
if (TryGetJToken(json, obj)) {
TDictionary *dict = TDictionary::Create(ls2);
for (auto &item : obj) {
auto itemRes = JsonDeserialize(ls2, item.second);
ls2.GetGC()->BarrierBegin();
dict->SetValue(item.first, itemRes);
ls2.GetGC()->BarrierEnd();
}
return dict;
}
return Undefined();
}
static TObject JsonDecode(GCList &ls2, std::vector<TObject> args) {
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
return JsonDeserialize(ls2,
Json::Decode(std::get<std::string>(args[0])));
}
return Undefined();
}
static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
return JsonDeserialize(ls2,
Json::DocDecode(std::get<std::string>(args[0])));
}
return Undefined();
}
std::string Json_Encode(TObject o, bool indent) {
return Json::Encode(JsonSerialize(o), indent);
}
TObject Json_Decode(GCList ls, std::string str) {
return JsonDeserialize(ls, Json::Decode(str));
}
std::string Json_DocEncode(TObject o, bool indent) {
auto obj = JsonSerialize(o);
JArray ls;
if (TryGetJToken(obj, ls))
return Json::DocEncode(ls, indent);
return "";
}
TObject Json_DocDecode(GCList ls, std::string str) {
return JsonDeserialize(ls, Json::DocDecode(str));
}
void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterJSON = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "Decode", "Deserialize Json", {"jsonString"},
JsonDecode);
dict->DeclareFunction(gc, "Encode", "Serialize Json", {"any", "$indent"},
JsonEncode);
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc",
{"jsonDocString"}, JsonDocDecode);
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc",
{"ls", "$indent"}, JsonDocEncode);
gc->BarrierBegin();
env->DeclareVariable("Json", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,84 +1,75 @@
#include "CrossLang.hpp"
#if defined(GEKKO)
#include <ogcsys.h>
#include <gccore.h>
#include <ogc/pad.h>
#include <ogcsys.h>
#if defined(HW_RVL)
#include <wiiuse/wpad.h>
#endif
#endif
namespace Tesses::CrossLang
{
#if defined(GEKKO)
#if defined(HW_RVL)
static TObject OGC_WPAD_ScanPads(GCList& ls, std::vector<TObject> args)
{
return (int64_t)WPAD_ScanPads();
}
static TObject OGC_WPAD_ButtonsUp(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
namespace Tesses::CrossLang {
#if defined(GEKKO)
#if defined(HW_RVL)
static TObject OGC_WPAD_ScanPads(GCList &ls, std::vector<TObject> args) {
return (int64_t)WPAD_ScanPads();
}
static TObject OGC_WPAD_ButtonsUp(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsUp((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_ButtonsDown(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_ButtonsHeld(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return 0;
}
static TObject OGC_WPAD_BatteryLevel(GCList &ls, std::vector<TObject> args) {
int64_t chan;
if (GetArgument(args, 0, chan))
return (int64_t)WPAD_BatteryLevel((int)chan);
return 0;
}
#endif
#endif
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
#if defined(GEKKO)
gc->BarrierBegin();
return 0;
}
#endif
#endif
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env) {
GCList ls(gc);
#if defined(GEKKO)
TDictionary* dict_ogc_pad = TDictionary::Create(ls);
#if defined(HW_RVL)
TDictionary* dict_rvl_wpad = TDictionary::Create(ls);
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown","Is button down",{"pad"},OGC_WPAD_ButtonsDown);
dict_rvl_wpad->SetValue("BUTTON_A",(int64_t)WPAD_BUTTON_A);
dict_rvl_wpad->SetValue("BUTTON_B",(int64_t)WPAD_BUTTON_B);
dict_rvl_wpad->SetValue("BUTTON_HOME",(int64_t)WPAD_BUTTON_HOME);
dict_rvl_wpad->SetValue("BUTTON_UP",(int64_t)WPAD_BUTTON_UP);
dict_rvl_wpad->SetValue("BUTTON_DOWN",(int64_t)WPAD_BUTTON_DOWN);
dict_rvl_wpad->SetValue("BUTTON_LEFT",(int64_t)WPAD_BUTTON_LEFT);
dict_rvl_wpad->SetValue("BUTTON_RIGHT",(int64_t)WPAD_BUTTON_RIGHT);
dict_rvl_wpad->SetValue("BUTTON_1",(int64_t)WPAD_BUTTON_1);
dict_rvl_wpad->SetValue("BUTTON_2",(int64_t)WPAD_BUTTON_2);
dict_rvl_wpad->SetValue("BUTTON_PLUS",(int64_t)WPAD_BUTTON_PLUS);
dict_rvl_wpad->SetValue("BUTTON_MINUS",(int64_t)WPAD_BUTTON_MINUS);
env->DeclareVariable("WPAD", dict_rvl_wpad);
#endif
env->DeclareVariable("PAD", dict_ogc_pad);
gc->BarrierEnd();
#endif
env->permissions.canRegisterOGC=true;
gc->BarrierBegin();
}
}
TDictionary *dict_ogc_pad = TDictionary::Create(ls);
#if defined(HW_RVL)
TDictionary *dict_rvl_wpad = TDictionary::Create(ls);
dict_rvl_wpad->DeclareFunction(gc, "ScanPads", "Scan wiimotes", {},
OGC_WPAD_ScanPads);
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown", "Is button down", {"pad"},
OGC_WPAD_ButtonsDown);
dict_rvl_wpad->SetValue("BUTTON_A", (int64_t)WPAD_BUTTON_A);
dict_rvl_wpad->SetValue("BUTTON_B", (int64_t)WPAD_BUTTON_B);
dict_rvl_wpad->SetValue("BUTTON_HOME", (int64_t)WPAD_BUTTON_HOME);
dict_rvl_wpad->SetValue("BUTTON_UP", (int64_t)WPAD_BUTTON_UP);
dict_rvl_wpad->SetValue("BUTTON_DOWN", (int64_t)WPAD_BUTTON_DOWN);
dict_rvl_wpad->SetValue("BUTTON_LEFT", (int64_t)WPAD_BUTTON_LEFT);
dict_rvl_wpad->SetValue("BUTTON_RIGHT", (int64_t)WPAD_BUTTON_RIGHT);
dict_rvl_wpad->SetValue("BUTTON_1", (int64_t)WPAD_BUTTON_1);
dict_rvl_wpad->SetValue("BUTTON_2", (int64_t)WPAD_BUTTON_2);
dict_rvl_wpad->SetValue("BUTTON_PLUS", (int64_t)WPAD_BUTTON_PLUS);
dict_rvl_wpad->SetValue("BUTTON_MINUS", (int64_t)WPAD_BUTTON_MINUS);
env->DeclareVariable("WPAD", dict_rvl_wpad);
#endif
env->DeclareVariable("PAD", dict_ogc_pad);
gc->BarrierEnd();
#endif
env->permissions.canRegisterOGC = true;
}
} // namespace Tesses::CrossLang

View File

@@ -1,83 +1,76 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString)
{
if(GetObject(obj,path)) return true;
std::string str;
if(allowString && GetObject<std::string>(obj,str))
{
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
return false;
namespace Tesses::CrossLang {
bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
bool allowString) {
if (GetObject(obj, path))
return true;
std::string str;
if (allowString && GetObject<std::string>(obj, str)) {
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString)
{
if(GetArgument(args,index,path)) return true;
std::string str;
if(allowString && GetArgument<std::string>(args,index,str))
{
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
return false;
return false;
}
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
Tesses::Framework::Filesystem::VFSPath &path,
bool allowString) {
if (GetArgument(args, index, path))
return true;
std::string str;
if (allowString && GetArgument<std::string>(args, index, str)) {
path = Tesses::Framework::Filesystem::VFSPath(str);
return true;
}
static TObject Path_Root(GCList& ls, std::vector<TObject> args)
{
auto res = Tesses::Framework::Filesystem::VFSPath();\
res.relative=false;
return false;
}
static TObject Path_Root(GCList &ls, std::vector<TObject> args) {
auto res = Tesses::Framework::Filesystem::VFSPath();
res.relative = false;
return res;
}
static TObject Path_FromString(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
return Tesses::Framework::Filesystem::VFSPath(str);
}
return nullptr;
}
static TObject Path_Create(GCList &ls, std::vector<TObject> args) {
TList *myls;
bool relative;
if (GetArgument(args, 0, relative) && GetArgumentHeap(args, 1, myls)) {
std::vector<std::string> items;
for (int64_t i = 0; i < myls->Count(); i++) {
std::string str;
TObject o = myls->Get(i);
if (GetObject<std::string>(o, str)) {
items.push_back(str);
}
}
auto res = Tesses::Framework::Filesystem::VFSPath(items);
res.relative = relative;
return res;
}
static TObject Path_FromString(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
return Tesses::Framework::Filesystem::VFSPath(str);
}
return nullptr;
}
static TObject Path_Create(GCList& ls, std::vector<TObject> args)
{
TList* myls;
bool relative;
if(GetArgument(args,0,relative) && GetArgumentHeap(args,1,myls))
{
std::vector<std::string> items;
for(int64_t i = 0; i < myls->Count(); i++)
{
std::string str;
TObject o =myls->Get(i);
if(GetObject<std::string>(o,str))
{
items.push_back(str);
}
}
auto res = Tesses::Framework::Filesystem::VFSPath(items);
res.relative = relative;
return res;
}
return nullptr;
}
void TStd::RegisterPath(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
return nullptr;
}
void TStd::RegisterPath(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterPath=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc,"FromString","Create a Path from string",{"path"},Path_FromString);
dict->DeclareFunction(gc,"Create","Create a Path from parts",{"relative","parts"},Path_Create);
dict->DeclareFunction(gc,"Root","Create Absolute Root Path",{}, Path_Root);
env->DeclareVariable("Path", dict);
gc->BarrierEnd();
}
}
env->permissions.canRegisterPath = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
dict->DeclareFunction(gc, "FromString", "Create a Path from string",
{"path"}, Path_FromString);
dict->DeclareFunction(gc, "Create", "Create a Path from parts",
{"relative", "parts"}, Path_Create);
dict->DeclareFunction(gc, "Root", "Create Absolute Root Path", {},
Path_Root);
env->DeclareVariable("Path", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,321 +1,285 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
class ProcessObject : public TNativeObject {
public:
ProcessObject() {
arguments = nullptr;
environment = nullptr;
}
ProcessObject(GCList &ls) {
arguments = TList::Create(ls);
environment = TList::Create(ls);
process.includeThisEnv = true;
process.redirectStdIn = false;
process.redirectStdOut = false;
namespace Tesses::CrossLang
{
class ProcessObject : public TNativeObject {
public:
ProcessObject()
{
arguments=nullptr;
environment=nullptr;
}
ProcessObject(GCList& ls)
{
arguments = TList::Create(ls);
environment = TList::Create(ls);
process.includeThisEnv=true;
process.redirectStdIn=false;
process.redirectStdOut=false;
process.redirectStdErr=false;
}
TList* arguments;
TList* environment;
Tesses::Framework::Platform::Process process;
std::string TypeName()
{
return "Process";
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(arguments != nullptr) arguments->Mark();
if(environment != nullptr) environment->Mark();
}
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
if(key == "setFileName" && GetArgument(args,0,process.name))
{
return process.name;
}
if(key == "getFileName")
{
return process.name;
}
if(key == "setRedirectStandardInput" && GetArgument(args,0,process.redirectStdIn))
{
return process.redirectStdIn;
}
if(key == "getRedirectStandardInput")
{
return process.redirectStdIn;
}
if(key == "setRedirectStandardOutput" && GetArgument(args,0,process.redirectStdOut))
{
return process.redirectStdOut;
}
if(key == "getRedirectStandardOutput")
{
return process.redirectStdOut;
}
if(key == "setRedirectStandardError" && GetArgument(args,0,process.redirectStdErr))
{
return process.redirectStdErr;
}
if(key == "getRedirectStandardError")
{
return process.redirectStdErr;
}
if(key == "setWorkingDirectory" && GetArgument(args,0,process.workingDirectory))
{
return process.workingDirectory;
}
if(key == "getWorkingDirectory")
{
return process.workingDirectory;
}
if(key == "setInheritParentEnvironment" && GetArgument(args,0,process.includeThisEnv))
{
return process.includeThisEnv;
}
if(key == "getInheritParentEnvironment")
{
return process.includeThisEnv;
}
if(key == "getArguments")
{
if(arguments == nullptr) return nullptr;
return arguments;
}
if(key == "setArguments")
{
if(GetArgumentHeap(args,0,arguments))
{
return arguments;
}
}
if(key == "getEnvironment")
{
if(environment == nullptr) return nullptr;
return environment;
}
if(key == "getEnvironment")
{
if(GetArgumentHeap(args,0,environment))
{
return environment;
}
}
if(key == "Start")
{
this->process.args.push_back(process.name);
if(arguments != nullptr)
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject argVal=arguments->Get(i);
std::string argValStr;
if(GetObject(argVal,argValStr))
this->process.args.push_back(argValStr);
}
}
if(environment != nullptr)
{
for(int64_t i = 0; i < environment->Count(); i++)
{
TObject arg = environment->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
if(kvp.size()==2)
{
process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
}
else if(kvp.size()==1)
{
process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
}
}
}
}
return process.Start();
}
if(key == "Join" || key == "WaitForExit")
{
return (int64_t)process.WaitForExit();
}
if(key == "getHasExited")
{
return process.HasExited();
}
if(key == "Terminate")
{
process.Kill(SIGTERM);
}
if(key == "CloseStdInNow")
{
process.CloseStdInNow();
}
int64_t k;
if(key == "Kill" && GetArgument(args,0,k))
{
process.Kill((int)k);
}
if(key == "getStandardInput")
{
return process.GetStdinStream();
}
if(key == "getStandardOutput")
{
return process.GetStdoutStream();
}
if(key == "getStandardError")
{
return process.GetStderrStream();
}
return Undefined();
}
};
static TObject Process_Start(GCList& ls, std::vector<TObject> args, TRootEnvironment* env)
{
//Process.Start({
// FileName = "git",
// Arguments = ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
// Environment = [],
// InheritParentEnvironment=true
//})
TDictionary* dict;
if(GetArgumentHeap(args,0,dict))
{
auto process = TNativeObject::Create<ProcessObject>(ls);
auto name = dict->GetValue("FileName");
auto inh = dict->GetValue("InheritParentEnvironment");
auto rStdIn = dict->GetValue("RedirectStandardInput");
auto rStdOut = dict->GetValue("RedirectStandardOutput");
auto rStdErr = dict->GetValue("RedirectStandardError");
auto workingDirectory = dict->GetValue("WorkingDirectory");
process->process.includeThisEnv=true;
process->process.redirectStdIn=false;
process->process.redirectStdOut=false;
process->process.redirectStdErr=false;
GetObject(inh,process->process.includeThisEnv);
GetObject(rStdIn,process->process.redirectStdIn);
GetObject(rStdOut,process->process.redirectStdOut);
GetObject(rStdErr,process->process.redirectStdErr);
GetObject(name,process->process.name);
Tesses::Framework::Filesystem::VFSPath wdPath;
if(env->permissions.localfs)
{
process->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
}
if(GetObject(workingDirectory,wdPath))
{
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
}
GetObject(workingDirectory,process->process.workingDirectory);
process->process.args.push_back(process->process.name);
auto argumentsO = dict->GetValue("Arguments");
TList* arguments;
if(GetObjectHeap(argumentsO,arguments))
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject arg = arguments->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
process->process.args.push_back(argstr);
}
}
}
argumentsO = dict->GetValue("Environment");
if(GetObjectHeap(argumentsO,arguments))
{
for(int64_t i = 0; i < arguments->Count(); i++)
{
TObject arg = arguments->Get(i);
std::string argstr;
if(GetObject(arg,argstr))
{
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
if(kvp.size()==2)
{
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
}
else if(kvp.size()==1)
{
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
}
}
}
}
if(process->process.Start())
{
return process;
}
process.redirectStdErr = false;
}
TList *arguments;
TList *environment;
Tesses::Framework::Platform::Process process;
std::string TypeName() { return "Process"; }
void Mark() {
if (this->marked)
return;
this->marked = true;
if (arguments != nullptr)
arguments->Mark();
if (environment != nullptr)
environment->Mark();
}
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
if (key == "setFileName" && GetArgument(args, 0, process.name)) {
return process.name;
}
if (key == "getFileName") {
return process.name;
}
return nullptr;
}
void TStd::RegisterProcess(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterProcess=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
gc->BarrierBegin();
auto processStart = TExternalMethod::Create(ls,"Start a process",{"process_object"},[env](GCList& ls, std::vector<TObject> args)->TObject{
return Process_Start(ls,args,env);
});
processStart->watch.push_back(env);
dict->SetValue("Start",processStart);
env->SetVariable("Process",dict);
auto process = env->EnsureDictionary(gc,"New");
auto newProcess = TExternalMethod::Create(ls, "Create process",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
auto obj= TNativeObject::Create<ProcessObject>(ls,ls);
if(env->permissions.localfs)
{
obj->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
if (key == "setRedirectStandardInput" &&
GetArgument(args, 0, process.redirectStdIn)) {
return process.redirectStdIn;
}
if (key == "getRedirectStandardInput") {
return process.redirectStdIn;
}
if (key == "setRedirectStandardOutput" &&
GetArgument(args, 0, process.redirectStdOut)) {
return process.redirectStdOut;
}
if (key == "getRedirectStandardOutput") {
return process.redirectStdOut;
}
if (key == "setRedirectStandardError" &&
GetArgument(args, 0, process.redirectStdErr)) {
return process.redirectStdErr;
}
if (key == "getRedirectStandardError") {
return process.redirectStdErr;
}
if (key == "setWorkingDirectory" &&
GetArgument(args, 0, process.workingDirectory)) {
return process.workingDirectory;
}
if (key == "getWorkingDirectory") {
return process.workingDirectory;
}
if (key == "setInheritParentEnvironment" &&
GetArgument(args, 0, process.includeThisEnv)) {
return process.includeThisEnv;
}
if (key == "getInheritParentEnvironment") {
return process.includeThisEnv;
}
if (key == "getArguments") {
if (arguments == nullptr)
return nullptr;
return arguments;
}
if (key == "setArguments") {
if (GetArgumentHeap(args, 0, arguments)) {
return arguments;
}
return obj;
}
if (key == "getEnvironment") {
if (environment == nullptr)
return nullptr;
return environment;
}
if (key == "getEnvironment") {
if (GetArgumentHeap(args, 0, environment)) {
return environment;
}
}
if (key == "Start") {
this->process.args.push_back(process.name);
if (arguments != nullptr) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject argVal = arguments->Get(i);
std::string argValStr;
if (GetObject(argVal, argValStr))
this->process.args.push_back(argValStr);
}
}
if (environment != nullptr) {
for (int64_t i = 0; i < environment->Count(); i++) {
TObject arg = environment->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
auto kvp =
Tesses::Framework::Http::HttpUtils::SplitString(
argstr, "=", 2);
if (kvp.size() == 2) {
process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
kvp[1]));
} else if (kvp.size() == 1) {
process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
""));
}
}
}
}
return process.Start();
}
if (key == "Join" || key == "WaitForExit") {
return (int64_t)process.WaitForExit();
}
if (key == "getHasExited") {
return process.HasExited();
}
if (key == "Terminate") {
process.Kill(SIGTERM);
}
if (key == "CloseStdInNow") {
process.CloseStdInNow();
}
int64_t k;
if (key == "Kill" && GetArgument(args, 0, k)) {
process.Kill((int)k);
}
if (key == "getStandardInput") {
return process.GetStdinStream();
}
if (key == "getStandardOutput") {
return process.GetStdoutStream();
}
if (key == "getStandardError") {
return process.GetStderrStream();
}
return Undefined();
}
};
static TObject Process_Start(GCList &ls, std::vector<TObject> args,
TRootEnvironment *env) {
// Process.Start({
// FileName = "git",
// Arguments =
// ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
// Environment = [],
// InheritParentEnvironment=true
// })
TDictionary *dict;
if (GetArgumentHeap(args, 0, dict)) {
auto process = TNativeObject::Create<ProcessObject>(ls);
auto name = dict->GetValue("FileName");
auto inh = dict->GetValue("InheritParentEnvironment");
auto rStdIn = dict->GetValue("RedirectStandardInput");
auto rStdOut = dict->GetValue("RedirectStandardOutput");
auto rStdErr = dict->GetValue("RedirectStandardError");
auto workingDirectory = dict->GetValue("WorkingDirectory");
process->process.includeThisEnv = true;
process->process.redirectStdIn = false;
process->process.redirectStdOut = false;
process->process.redirectStdErr = false;
GetObject(inh, process->process.includeThisEnv);
GetObject(rStdIn, process->process.redirectStdIn);
GetObject(rStdOut, process->process.redirectStdOut);
GetObject(rStdErr, process->process.redirectStdErr);
GetObject(name, process->process.name);
Tesses::Framework::Filesystem::VFSPath wdPath;
if (env->permissions.localfs) {
process->process.workingDirectory =
env->permissions.localfs->GetWorking().ToString();
}
if (GetObject(workingDirectory, wdPath)) {
process->process.workingDirectory =
wdPath.MakeAbsolute().ToString();
}
GetObject(workingDirectory, process->process.workingDirectory);
process->process.args.push_back(process->process.name);
auto argumentsO = dict->GetValue("Arguments");
TList *arguments;
if (GetObjectHeap(argumentsO, arguments)) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject arg = arguments->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
process->process.args.push_back(argstr);
}
}
}
argumentsO = dict->GetValue("Environment");
if (GetObjectHeap(argumentsO, arguments)) {
for (int64_t i = 0; i < arguments->Count(); i++) {
TObject arg = arguments->Get(i);
std::string argstr;
if (GetObject(arg, argstr)) {
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(
argstr, "=", 2);
if (kvp.size() == 2) {
process->process.env.push_back(
std::pair<std::string, std::string>(kvp[0],
kvp[1]));
} else if (kvp.size() == 1) {
process->process.env.push_back(
std::pair<std::string, std::string>(kvp[0], ""));
}
}
}
}
if (process->process.Start()) {
return process;
}
}
return nullptr;
}
void TStd::RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterProcess = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
gc->BarrierBegin();
auto processStart = TExternalMethod::Create(
ls, "Start a process", {"process_object"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return Process_Start(ls, args, env);
});
newProcess->watch.push_back(env);
process->SetValue("Process",newProcess);
//process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
processStart->watch.push_back(env);
dict->SetValue("Start", processStart);
env->SetVariable("Process", dict);
auto process = env->EnsureDictionary(gc, "New");
auto newProcess = TExternalMethod::Create(
ls, "Create process", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
auto obj = TNativeObject::Create<ProcessObject>(ls, ls);
if (env->permissions.localfs) {
obj->process.workingDirectory =
env->permissions.localfs->GetWorking().ToString();
}
return obj;
});
newProcess->watch.push_back(env);
process->SetValue("Process", newProcess);
// process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
process->DeclareFunction(
gc, "CGIServer", "Create a CGI Server", {"path"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
return std::make_shared<Tesses::Framework::Http::CGIServer>(path);
if (GetArgumentAsPath(args, 0, path)) {
return std::make_shared<Tesses::Framework::Http::CGIServer>(
path);
}
return Undefined();
});
gc->BarrierEnd();
}
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -3,228 +3,192 @@
#include <iostream>
namespace Tesses::CrossLang {
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
using namespace Tesses::Framework::Serialization;
TObject Sqlite_Escape(GCList& ls, std::vector<TObject> args)
{
int64_t n;
double d;
bool b;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
using namespace Tesses::Framework::Serialization;
TObject Sqlite_Escape(GCList &ls, std::vector<TObject> args) {
int64_t n;
double d;
bool b;
std::string str;
if(GetArgument(args,0,str))
{
return SQLiteDatabase::Escape(str);
}
if(GetArgument(args,0,n))
{
return std::to_string(n);
}
if(GetArgument(args,0,b))
{
return b ? "1" : "0";
}
if(GetArgument(args,0,d))
{
return std::to_string(d);
}
return "NULL";
std::string str;
if (GetArgument(args, 0, str)) {
return SQLiteDatabase::Escape(str);
}
TObject Sqlite_Prepare(GCList& ls, std::vector<TObject> args)
{
std::string str;
TList* list;
std::string newStr = "";
if(GetArgument(args,0,str) && GetArgumentHeap(args,1,list))
{
int64_t item = 0;
for(size_t i = 0; i < str.size(); i++)
{
if(str[i] == '@' && (i+1>=str.size() || str[i+1] != '@'))
{
auto v = list->Get(item);
int64_t n;
double d;
bool b;
std::string str;
if(GetObject(v,str))
{
newStr+= SQLiteDatabase::Escape(str);
}
else if(GetObject(v,n))
{
newStr+= std::to_string(n);
}
else if(GetObject(v,b))
{
newStr+= (b ? "1" : "0");
}
else if(GetObject(v,d))
{
newStr+= std::to_string(d);
}
else {
newStr+= "NULL";
}
}
else {
newStr+=str[i];
}
}
}
return newStr;
if (GetArgument(args, 0, n)) {
return std::to_string(n);
}
class SQLiteObject : public TNativeObject
{
public:
SQLiteDatabase* db;
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path)
{
db=new SQLiteDatabase(path);
}
std::string TypeName()
{
return "SQLiteDatabase";
}
void Close()
{
if(this->db == nullptr) return;
delete this->db;
this->db = nullptr;
}
bool ToBool()
{
return this->db != nullptr;
}
TObject CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
{
if(name == "Close") this->Close();
if(name == "Escape") {
return Sqlite_Escape(ls,args);
}
if(name == "Prepare") {
return Sqlite_Prepare(ls,args);
}
if(name == "Exec")
{
std::string arg;
if(GetArgument(args,0,arg))
{
if(this->db == nullptr) return nullptr;
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res;
this->db->Exec(arg,res);
TList* list = TList::Create(ls);
for(auto& item : res)
{
TDictionary* dict = TDictionary::Create(ls);
for(auto& item2 : item)
{
if(item2.second)
dict->SetValue(item2.first,item2.second.value());
else
dict->SetValue(item2.first,nullptr);
}
list->Add(dict);
}
return list;
}
}
return Undefined();
}
~SQLiteObject()
{
if(this->db != nullptr)
delete this->db;
}
};
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env)
{
Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p))
{
if(env->permissions.sqlite3Scoped)
{
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
}
return TNativeObject::Create<SQLiteObject>(ls,p);
}
return Undefined();
if (GetArgument(args, 0, b)) {
return b ? "1" : "0";
}
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args)
{
SQLiteObject* sql;
std::string cmd;
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd))
{
try {
return sql->CallMethod(ls,"Exec",{cmd});
} catch(std::runtime_error& ex)
{
return (std::string)ex.what();
}
}
return Undefined();
if (GetArgument(args, 0, d)) {
return std::to_string(d);
}
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args)
{
SQLiteObject* sql;
if(GetArgumentHeap(args,0,sql))
{
sql->Close();
}
return Undefined();
}
#endif
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterSqlite=true;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"Open","Opens the database (returns database handle or an error message as string or undefined)",{"filename"},[env](GCList& ls, std::vector<TObject> args)->TObject {
return Sqlite_Open(ls,args,env);
});
dict->DeclareFunction(gc,"Exec","Execute sql (returns dictionary of columns key=value, an error message as string or undefined)",{"handle","sql"},Sqlite_Exec);
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close);
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape);
dict->DeclareFunction(gc,"Prepare", "Prepare sql",{"sql","items"}, Sqlite_Prepare);
gc->BarrierBegin();
env->DeclareVariable("Sqlite", dict);
gc->BarrierEnd();
#endif
}
return "NULL";
}
TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
std::string str;
TList *list;
std::string newStr = "";
if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
int64_t item = 0;
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
auto v = list->Get(item);
int64_t n;
double d;
bool b;
std::string str;
if (GetObject(v, str)) {
newStr += SQLiteDatabase::Escape(str);
} else if (GetObject(v, n)) {
newStr += std::to_string(n);
} else if (GetObject(v, b)) {
newStr += (b ? "1" : "0");
} else if (GetObject(v, d)) {
newStr += std::to_string(d);
} else {
newStr += "NULL";
}
} else {
newStr += str[i];
}
}
}
return newStr;
}
class SQLiteObject : public TNativeObject {
public:
SQLiteDatabase *db;
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
db = new SQLiteDatabase(path);
}
std::string TypeName() { return "SQLiteDatabase"; }
void Close() {
if (this->db == nullptr)
return;
delete this->db;
this->db = nullptr;
}
bool ToBool() { return this->db != nullptr; }
TObject CallMethod(GCList &ls, std::string name,
std::vector<TObject> args) {
if (name == "Close")
this->Close();
if (name == "Escape") {
return Sqlite_Escape(ls, args);
}
if (name == "Prepare") {
return Sqlite_Prepare(ls, args);
}
if (name == "Exec") {
std::string arg;
if (GetArgument(args, 0, arg)) {
if (this->db == nullptr)
return nullptr;
std::vector<std::vector<
std::pair<std::string, std::optional<std::string>>>>
res;
this->db->Exec(arg, res);
TList *list = TList::Create(ls);
for (auto &item : res) {
TDictionary *dict = TDictionary::Create(ls);
for (auto &item2 : item) {
if (item2.second)
dict->SetValue(item2.first, item2.second.value());
else
dict->SetValue(item2.first, nullptr);
}
list->Add(dict);
}
return list;
}
}
return Undefined();
}
~SQLiteObject() {
if (this->db != nullptr)
delete this->db;
}
};
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
TRootEnvironment *env) {
Tesses::Framework::Filesystem::VFSPath p;
if (GetArgumentAsPath(args, 0, p)) {
if (env->permissions.sqlite3Scoped) {
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
}
return TNativeObject::Create<SQLiteObject>(ls, p);
}
return Undefined();
}
TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
SQLiteObject *sql;
std::string cmd;
if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
try {
return sql->CallMethod(ls, "Exec", {cmd});
} catch (std::runtime_error &ex) {
return (std::string)ex.what();
}
}
return Undefined();
}
TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
SQLiteObject *sql;
if (GetArgumentHeap(args, 0, sql)) {
sql->Close();
}
return Undefined();
}
#endif
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterSqlite = true;
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(
gc, "Open",
"Opens the database (returns database handle or an error message as "
"string or undefined)",
{"filename"}, [env](GCList &ls, std::vector<TObject> args) -> TObject {
return Sqlite_Open(ls, args, env);
});
dict->DeclareFunction(gc, "Exec",
"Execute sql (returns dictionary of columns "
"key=value, an error message as string or undefined)",
{"handle", "sql"}, Sqlite_Exec);
dict->DeclareFunction(gc, "Close", "Close sql database", {"handle"},
Sqlite_Close);
dict->DeclareFunction(gc, "Escape", "Escape sql text", {"text"},
Sqlite_Escape);
dict->DeclareFunction(gc, "Prepare", "Prepare sql", {"sql", "items"},
Sqlite_Prepare);
gc->BarrierBegin();
env->DeclareVariable("Sqlite", dict);
gc->BarrierEnd();
#endif
}
} // namespace Tesses::CrossLang

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,42 @@
#include "TessesFramework/Uuid.hpp"
#include "CrossLang.hpp"
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Uuid.hpp"
namespace Tesses::CrossLang {
static TObject Uuid_NewUuid(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Uuid::Generate();
static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
return Tesses::Framework::Uuid::Generate();
}
static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
std::string str;
Tesses::Framework::Uuid uuid;
if (GetArgument(args, 0, str) &&
Tesses::Framework::Uuid::TryParse(str, uuid))
return uuid;
return nullptr;
}
static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
TByteArray *ba;
int64_t index;
if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
(size_t)index < ba->data.size() &&
(size_t)index + 16 <= ba->data.size()) {
return Tesses::Framework::Serialization::BitConverter::ToUuid(
ba->data[(size_t)index]);
}
static TObject Uuid_TryParse(GCList& ls, std::vector<TObject> args)
{
std::string str;
Tesses::Framework::Uuid uuid;
if(GetArgument(args, 0, str) && Tesses::Framework::Uuid::TryParse(str,uuid))
return uuid;
return nullptr;
}
static TObject Uuid_FromBytes(GCList& ls, std::vector<TObject> args)
{
TByteArray* ba;
int64_t index;
if(GetArgumentHeap(args,0,ba) && GetArgument(args, 1, index) && (size_t)index < ba->data.size() && (size_t)index + 16 <= ba->data.size())
{
return Tesses::Framework::Serialization::BitConverter::ToUuid(ba->data[(size_t)index]);
}
return nullptr;
}
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
gc->BarrierBegin();
TDictionary* guid = env->EnsureDictionary(gc, "Uuid");
guid->DeclareFunction(gc,"NewUuid","Create random uuid",{},Uuid_NewUuid);
guid->DeclareFunction(gc, "TryParse","Try to parse",{"str"}, Uuid_TryParse);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",{"byteArray","offset"}, Uuid_FromBytes);
gc->BarrierEnd();
}
}
return nullptr;
}
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
gc->BarrierBegin();
TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
Uuid_NewUuid);
guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
Uuid_TryParse);
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
{"byteArray", "offset"}, Uuid_FromBytes);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang

View File

@@ -1,123 +1,104 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
#include <sstream>
namespace Tesses::CrossLang
{
namespace Tesses::CrossLang {
static TObject AstToTObject(GCList& ls,SyntaxNode node)
{
if(std::holds_alternative<std::nullptr_t>(node))
static TObject AstToTObject(GCList &ls, SyntaxNode node) {
if (std::holds_alternative<std::nullptr_t>(node))
return nullptr;
if(std::holds_alternative<int64_t>(node))
{
if (std::holds_alternative<int64_t>(node)) {
return std::get<int64_t>(node);
}
if(std::holds_alternative<double>(node))
{
if (std::holds_alternative<double>(node)) {
return std::get<double>(node);
}
if(std::holds_alternative<bool>(node))
{
if (std::holds_alternative<bool>(node)) {
return std::get<bool>(node);
}
if(std::holds_alternative<std::string>(node))
{
if (std::holds_alternative<std::string>(node)) {
std::string str = std::get<std::string>(node);
return str;
}
if(std::holds_alternative<char>(node))
{
if (std::holds_alternative<char>(node)) {
char c = std::get<char>(node);
return c;
}
if(std::holds_alternative<Undefined>(node))
{
if (std::holds_alternative<Undefined>(node)) {
auto r = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
r->SetValue("Type",std::string(UndefinedExpression));
r->SetValue("Type", std::string(UndefinedExpression));
ls.GetGC()->BarrierEnd();
return r;
}
if(std::holds_alternative<AdvancedSyntaxNode>(node))
{
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
auto asn = std::get<AdvancedSyntaxNode>(node);
auto r = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
r->SetValue("Type",asn.nodeName);
r->SetValue("IsExpression",asn.isExpression);
TList* ls2 = TList::Create(ls);
for(auto item : asn.nodes)
{
ls2->Add(AstToTObject(ls,item));
r->SetValue("Type", asn.nodeName);
r->SetValue("IsExpression", asn.isExpression);
TList *ls2 = TList::Create(ls);
for (auto item : asn.nodes) {
ls2->Add(AstToTObject(ls, item));
}
r->SetValue("Arguments", ls2);
ls.GetGC()->BarrierEnd();
return r;
}
return nullptr;
}
static TObject VM_SourceToAst(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
std::stringstream strm(str);
std::vector<LexToken> tokens;
int res = Lex("memory.tcross",strm,tokens);
if(res != 0)
{
throw VMException("Lex error at line: " + std::to_string(res));
}
Parser p(tokens);
auto res2 =p.ParseRoot();
return AstToTObject(ls,res2);
return nullptr;
}
static TObject VM_SourceToAst(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
std::stringstream strm(str);
std::vector<LexToken> tokens;
int res = Lex("memory.tcross", strm, tokens);
if (res != 0) {
throw VMException("Lex error at line: " + std::to_string(res));
}
return nullptr;
Parser p(tokens);
auto res2 = p.ParseRoot();
return AstToTObject(ls, res2);
}
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
{
std::string str;
if(GetArgument(args,0,str))
{
if(current_function != nullptr)
{
return current_function->env->Eval(ls,str);
}
return nullptr;
}
static TObject VM_Eval(GCList &ls, std::vector<TObject> args) {
std::string str;
if (GetArgument(args, 0, str)) {
if (current_function != nullptr) {
return current_function->env->Eval(ls, str);
}
return nullptr;
}
static TObject Failure(GCList& ls, std::string reason)
{
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success",false);
dict->SetValue("Reason", reason);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject Success(GCList& ls)
{
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success",true);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject VM_getCurrentEnvironment(GCList& ls2,std::vector<TObject> args)
{
if(current_function != nullptr) return current_function->env;
return Undefined();
}
static TObject VM_Compile(GCList& ls, std::vector<TObject> args)
{
try {
TDictionary* dict;
if(!GetArgumentHeap<TDictionary*>(args,0,dict)) return Undefined();
return nullptr;
}
static TObject Failure(GCList &ls, std::string reason) {
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success", false);
dict->SetValue("Reason", reason);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject Success(GCList &ls) {
TDictionary *dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Success", true);
ls.GetGC()->BarrierEnd();
return dict;
}
static TObject VM_getCurrentEnvironment(GCList &ls2,
std::vector<TObject> args) {
if (current_function != nullptr)
return current_function->env;
return Undefined();
}
static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
try {
TDictionary *dict;
if (!GetArgumentHeap<TDictionary *>(args, 0, dict))
return Undefined();
/*
VM.Compile
{
@@ -127,18 +108,20 @@ namespace Tesses::CrossLang
Version = "",
Dependencies = [{Name="Name", Version}],
ResourceDirectory = "",
}
}
*/
std::string name = "Out";
std::vector<std::pair<std::string,std::string>> sources;
TVMVersion version(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
std::vector<std::pair<std::string,TVMVersion>> dependencies;
std::vector<std::pair<std::string,TVMVersion>> tools;
std::vector<std::pair<std::string, std::string>> sources;
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
CROSSLANG_BYTECODE_VERSIONSTAGE);
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string info;
std::string icon;
bool debug=false;
bool debug = false;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
ls.GetGC()->BarrierBegin();
@@ -151,116 +134,110 @@ namespace Tesses::CrossLang
TObject _icon = dict->GetValue("Icon");
TObject _comptime = dict->GetValue("CompTime");
TObject _resourceFileSystem = dict->GetValue("ResourceFileSystem");
TObject _out = dict->GetValue("Output");
TObject _dbg = dict->GetValue("Debug");
TList* _toolList;
TList* _depList; TList* srcLst;
TRootEnvironment* comptimeEnv=nullptr;
GetObject<std::string>(_name,name);
GetObject<std::string>(_info,info);
GetObject<std::string>(_icon,icon);
TList *_toolList;
TList *_depList;
TList *srcLst;
TRootEnvironment *comptimeEnv = nullptr;
GetObject<std::string>(_name, name);
GetObject<std::string>(_info, info);
GetObject<std::string>(_icon, icon);
GetObject(_resourceFileSystem, vfs);
GetObjectHeap(_comptime,comptimeEnv);
GetObject(_dbg,debug);
GetObjectHeap(_comptime, comptimeEnv);
GetObject(_dbg, debug);
std::string v2;
if(GetObject<std::string>(_version,v2))
if (GetObject<std::string>(_version, v2))
TVMVersion::TryParse(v2, version);
else
GetObject(_version,version);
GetObject(_version, version);
if(GetObjectHeap<TList*>(_dependencies,_depList))
{
for(int64_t i = 0; i < _depList->Count(); i++)
{
if (GetObjectHeap<TList *>(_dependencies, _depList)) {
for (int64_t i = 0; i < _depList->Count(); i++) {
TObject _dep = _depList->Get(i);
TDictionary* _depD;
if(GetObjectHeap<TDictionary*>(_dep, _depD))
{
TDictionary *_depD;
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
TObject _name2 = _depD->GetValue("Name");
TObject _version2 = _depD->GetValue("Version");
std::string name2;
std::string version2;
TVMVersion version02;
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
{
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
}
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
{
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
if (GetObject<std::string>(_name2, name2) &&
GetObject<std::string>(_version2, version2) &&
TVMVersion::TryParse(version2, version02)) {
dependencies.push_back(
std::pair<std::string, TVMVersion>(name2,
version02));
} else if (GetObject<std::string>(_name2, name2) &&
GetObject(_version2, version02)) {
dependencies.push_back(
std::pair<std::string, TVMVersion>(name2,
version02));
}
}
}
}
if(GetObjectHeap<TList*>(_tools,_toolList))
{
for(int64_t i = 0; i < _toolList->Count(); i++)
{
if (GetObjectHeap<TList *>(_tools, _toolList)) {
for (int64_t i = 0; i < _toolList->Count(); i++) {
TObject _dep = _toolList->Get(i);
TDictionary* _depD;
if(GetObjectHeap<TDictionary*>(_dep, _depD))
{
TDictionary *_depD;
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
TObject _name2 = _depD->GetValue("Name");
TObject _version2 = _depD->GetValue("Version");
std::string name2;
std::string version2;
TVMVersion version02;
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
{
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
}
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
{
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
if (GetObject<std::string>(_name2, name2) &&
GetObject<std::string>(_version2, version2) &&
TVMVersion::TryParse(version2, version02)) {
tools.push_back(std::pair<std::string, TVMVersion>(
name2, version02));
} else if (GetObject<std::string>(_name2, name2) &&
GetObject(_version2, version02)) {
tools.push_back(std::pair<std::string, TVMVersion>(
name2, version02));
}
}
}
}
if(GetObjectHeap<TList*>(_sources,srcLst))
{
for(int64_t i = 0; i < srcLst->Count(); i++)
{
if (GetObjectHeap<TList *>(_sources, srcLst)) {
for (int64_t i = 0; i < srcLst->Count(); i++) {
TObject _src = srcLst->Get(i);
TDictionary* _srcD;
if(GetObjectHeap<TDictionary*>(_src, _srcD))
{
TDictionary *_srcD;
if (GetObjectHeap<TDictionary *>(_src, _srcD)) {
TObject _sourceTxt = _srcD->GetValue("Source");
TObject _filename = _srcD->GetValue("FileName");
std::string srctxt = "";
std::string filename = "memory_" + std::to_string(i) + ".tcross";
std::string filename =
"memory_" + std::to_string(i) + ".tcross";
bool fromFile = false;
GetObject<std::string>(_sourceTxt,srctxt);
GetObject<std::string>(_filename,filename);
sources.push_back(std::pair<std::string,std::string>(srctxt,filename));
GetObject<std::string>(_sourceTxt, srctxt);
GetObject<std::string>(_filename, filename);
sources.push_back(
std::pair<std::string, std::string>(srctxt, filename));
}
}
}
ls.GetGC()->BarrierEnd();
std::vector<LexToken> tokens;
for(auto source : sources)
{
for (auto source : sources) {
std::stringstream strm(source.first);
int res = Lex(source.second, strm, tokens);
if(res != 0)
{
return Failure(ls, "Lex error in file \"" + source.second + "\":" + std::to_string(res));
if (res != 0) {
return Failure(ls, "Lex error in file \"" + source.second +
"\":" + std::to_string(res));
}
}
Parser parser(tokens,ls.GetGC(),comptimeEnv);
Parser parser(tokens, ls.GetGC(), comptimeEnv);
parser.debug = debug;
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
@@ -274,147 +251,136 @@ namespace Tesses::CrossLang
gen.icon = icon;
std::string outpath;
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
if(GetObject(_out, stream))
{
if (GetObject(_out, stream)) {
gen.Save(stream);
}
return Success(ls);
} catch(std::exception& ex)
{
return Failure(ls, ex.what());
}
} catch (std::exception &ex) {
return Failure(ls, ex.what());
}
static TObject VM_GetStacktrace(GCList& ls, std::vector<TObject> args)
{
if(current_function != nullptr)
{
if(current_function->thread != nullptr)
{
TList* list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for(auto item : current_function->thread->call_stack_entries)
{
auto dict = TDictionary::Create(ls);
if(item->callable->closure->name)
dict->SetValue("Name", *item->callable->closure->name);
dict->SetValue("Closure", item->callable->closure);
dict->SetValue("FileName", item->callable->file->name + "-" + item->callable->file->version.ToString() + ".crvm");
dict->SetValue("IP",(int64_t)item->ip);
if(item->srcline >= 1)
{
dict->SetValue("SourceFile", item->srcfile);
dict->SetValue("SourceLine",item->srcline);
}
list->Add(dict);
}
ls.GetGC()->BarrierEnd();
return list;
}
}
return nullptr;
}
void TStd::RegisterVM(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterVM=true;
GCList ls(gc);
}
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
if (current_function != nullptr) {
if (current_function->thread != nullptr) {
TList *list = TList::Create(ls);
ls.GetGC()->BarrierBegin();
for (auto item : current_function->thread->call_stack_entries) {
auto dict = TDictionary::Create(ls);
if (item->callable->closure->name)
dict->SetValue("Name", *item->callable->closure->name);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetStacktrace","Get the current stack trace", {}, VM_GetStacktrace);
dict->DeclareFunction(gc, "getRootEnvironmentAsDictionary","Get root environment as a dictionary",{},[env](GCList& ls, std::vector<TObject> args)-> TObject{
dict->SetValue("Closure", item->callable->closure);
dict->SetValue("FileName",
item->callable->file->name + "-" +
item->callable->file->version.ToString() +
".crvm");
dict->SetValue("IP", (int64_t)item->ip);
if (item->srcline >= 1) {
dict->SetValue("SourceFile", item->srcfile);
dict->SetValue("SourceLine", item->srcline);
}
list->Add(dict);
}
ls.GetGC()->BarrierEnd();
return list;
}
}
return nullptr;
}
void TStd::RegisterVM(std::shared_ptr<GC> gc, TRootEnvironment *env) {
env->permissions.canRegisterVM = true;
GCList ls(gc);
TDictionary *dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetStacktrace", "Get the current stack trace",
{}, VM_GetStacktrace);
dict->DeclareFunction(
gc, "getRootEnvironmentAsDictionary",
"Get root environment as a dictionary", {},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
return env->GetDictionary();
});
dict->DeclareFunction(gc, "getRootEnvironment","Get root environment, for reflection purposes",{},[env](GCList& ls2,std::vector<TObject> args)->TObject {return env;});
dict->DeclareFunction(gc, "getCurrentEnvironment","Get current environment, for reflection purposes",{},VM_getCurrentEnvironment);
dict->DeclareFunction(gc, "CreateEnvironment","Create root environment",{"$dict"},[env](GCList& ls,std::vector<TObject> args)->TObject{
TDictionary* dict;
if(GetArgumentHeap(args,0,dict))
{
auto renv = TRootEnvironment::Create(ls,dict);
renv->permissions.customConsole = env->permissions.customConsole;
dict->DeclareFunction(
gc, "getRootEnvironment",
"Get root environment, for reflection purposes", {},
[env](GCList &ls2, std::vector<TObject> args) -> TObject {
return env;
});
dict->DeclareFunction(gc, "getCurrentEnvironment",
"Get current environment, for reflection purposes",
{}, VM_getCurrentEnvironment);
dict->DeclareFunction(
gc, "CreateEnvironment", "Create root environment", {"$dict"},
[env](GCList &ls, std::vector<TObject> args) -> TObject {
TDictionary *dict;
if (GetArgumentHeap(args, 0, dict)) {
auto renv = TRootEnvironment::Create(ls, dict);
renv->permissions.customConsole =
env->permissions.customConsole;
return renv;
}
else
{
auto renv = TRootEnvironment::Create(ls,TDictionary::Create(ls));
renv->permissions.customConsole = env->permissions.customConsole;
} else {
auto renv =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
renv->permissions.customConsole =
env->permissions.customConsole;
return renv;
}
});
dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector<TObject> args)->TObject{
dict->DeclareFunction(
gc, "LoadExecutable", "Load a crossvm executable", {"stream"},
[](GCList &ls, std::vector<TObject> args) -> TObject {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
if(GetArgument(args,0,strm))
{
TFile* f =TFile::Create(ls);
f->Load(ls.GetGC(),strm);
if (GetArgument(args, 0, strm)) {
TFile *f = TFile::Create(ls);
f->Load(ls.GetGC(), strm);
return f;
}
return nullptr;
});
#if defined(CROSSLANG_ENABLE_SUPERSLIM)
dict->SetValue("SuperSlim", true);
#else
dict->SetValue("SuperSlim", false);
#endif
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
dict->DeclareFunction(gc, "getRuntimeVersion","Get the runtime version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return TVMVersion(CROSSLANG_MAJOR,CROSSLANG_MINOR,CROSSLANG_PATCH,0,TVMVersionStage::DevVersion);
});
dict->DeclareFunction(gc, "getBytecodeVersion","Get the bytecode version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
return TVMVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
});
dict->DeclareFunction(gc, "getIsRunning","Is the program still running",{},[](GCList& ls, std::vector<TObject> args)->TObject {
return Tesses::Framework::TF_IsRunning();
});
dict->DeclareFunction(gc, "RunEventLoopItteration","Run Event Loop Itteration",{},[](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::TF_RunEventLoopItteration();
return Undefined();
});
dict->DeclareFunction(gc, "RunEventLoop","Run Event Loop",{},[](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::TF_RunEventLoop();
return Undefined();
});
dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcVFS;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> destVFS;
Tesses::Framework::Filesystem::VFSPath sourcePath;
if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS))
return Merge(srcVFS, sourcePath, destVFS);
return Undefined();
});
dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
bool generateJSON=true;
bool extractResources=true;
if(GetArgument(args,0,strm) && GetArgument(args,1, vfs))
{
GetArgument(args,2,generateJSON);
GetArgument(args,3,extractResources);
Disassemble(strm,vfs, generateJSON, extractResources);
}
return Undefined();
});
dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector<TObject> args)->TObject {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
if(GetArgument(args,0, vfs))
return Assemble(vfs);
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("VM", dict);
gc->BarrierEnd();
}
}
dict->DeclareFunction(gc, "Eval", "Eval source code", {"source"}, VM_Eval);
dict->DeclareFunction(gc, "Compile", "Compile Source", {"dict"},
VM_Compile);
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast",
{"source"}, VM_SourceToAst);
dict->DeclareFunction(
gc, "getRuntimeVersion", "Get the runtime version", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return TVMVersion(CROSSLANG_MAJOR, CROSSLANG_MINOR, CROSSLANG_PATCH,
0, TVMVersionStage::DevVersion);
});
dict->DeclareFunction(
gc, "getBytecodeVersion", "Get the bytecode version", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return TVMVersion(
CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
CROSSLANG_BYTECODE_VERSIONSTAGE);
});
dict->DeclareFunction(gc, "getIsRunning", "Is the program still running",
{},
[](GCList &ls, std::vector<TObject> args) -> TObject {
return Tesses::Framework::TF_IsRunning();
});
dict->DeclareFunction(gc, "RunEventLoopItteration",
"Run Event Loop Itteration", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::TF_RunEventLoopItteration();
return Undefined();
});
dict->DeclareFunction(gc, "RunEventLoop", "Run Event Loop", {},
[](GCList &ls, std::vector<TObject> args) -> TObject {
Tesses::Framework::TF_RunEventLoop();
return Undefined();
});
gc->BarrierBegin();
env->DeclareVariable("VM", dict);
gc->BarrierEnd();
}
} // namespace Tesses::CrossLang