diff --git a/src/runtime_methods/class.cpp b/src/runtime_methods/class.cpp new file mode 100644 index 0000000..83fadfc --- /dev/null +++ b/src/runtime_methods/class.cpp @@ -0,0 +1,143 @@ +#include "CrossLang.hpp" + + +namespace Tesses::CrossLang +{ + static TList* VectorOfStringToList(GCList& ls, std::vector& 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& 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; + } + 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_GetInfo(TRootEnvironment* env,GCList& ls, std::vector args) + { + + TList* list; + TClassObject* obj; + std::string str; + if(GetArgumentHeap(args,0,list)) + { + std::vector 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); + } + else + continue; + } + } + else if(GetArgument(args,0,str)) + { + std::vector 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(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 args)->TObject { + return Class_GetInfo(env,ls,args); + }); + ext->watch.push_back(env); + + cls->SetValue("GetInfo",ext); + gc->BarrierEnd(); + } +} \ No newline at end of file diff --git a/src/types/associativearray.cpp b/src/types/associativearray.cpp new file mode 100644 index 0000000..de45a9a --- /dev/null +++ b/src/types/associativearray.cpp @@ -0,0 +1,114 @@ +#include "CrossLang.hpp" + +namespace Tesses::CrossLang +{ + + TAssociativeArray* TAssociativeArray::Create(GCList& ls) + { + TAssociativeArray* list=new TAssociativeArray(); + GC* _gc = ls.GetGC(); + ls.Add(list); + _gc->Watch(list); + return list; + } + TAssociativeArray* TAssociativeArray::Create(GCList* ls) + { + TAssociativeArray* list=new TAssociativeArray(); + GC* _gc = ls->GetGC(); + ls->Add(list); + _gc->Watch(list); + return list; + } + void TAssociativeArray::Set(GC* gc, TObject key, TObject value) + { + if(std::holds_alternative(key)) return; + gc->BarrierBegin(); + for(auto index = this->items.begin(); index < this->items.end(); index++) + { + auto first= index->first; + gc->BarrierEnd(); + auto eq = Equals(gc,key,first); + gc->BarrierBegin(); + if(eq) + { + if(std::holds_alternative(value)) + { + this->items.erase(index); + } + else + { + index->second = value; + } + gc->BarrierEnd(); + return; + } + } + this->items.push_back(std::pair(key,value)); + gc->BarrierEnd(); + } + TObject TAssociativeArray::Get(GC* gc, TObject key) + { + if(std::holds_alternative(key)) return Undefined(); + gc->BarrierBegin(); + for(auto& item : this->items) + { + auto first= item.first; + gc->BarrierEnd(); + auto eq = Equals(gc,key,first); + gc->BarrierBegin(); + if(eq) + { + gc->BarrierEnd(); + return item.second; + } + } + gc->BarrierEnd(); + return Undefined(); + } + TObject TAssociativeArray::GetKey(int64_t index) + { + if(index >= 0 && index < (int64_t)this->items.size()) + { + return this->items[index].first; + } + return Undefined(); + } + TObject TAssociativeArray::GetValue(int64_t index) + { + if(index >= 0 && index < (int64_t)this->items.size()) + { + return this->items[index].second; + } + return Undefined(); + } + void TAssociativeArray::SetKey(int64_t index, TObject key) + { + + if(std::holds_alternative(key)) return; + if(index >= 0 && index < (int64_t)this->items.size()) + { + this->items[index].first=key; + } + + } + void TAssociativeArray::SetValue(int64_t index,TObject value) + { + if(std::holds_alternative(value)) return; + if(index >= 0 && index < (int64_t)this->items.size()) + { + this->items[index].first=value; + } + } + int64_t TAssociativeArray::Count() + { + return (int64_t)this->items.size(); + } + void TAssociativeArray::Mark() + { + for(auto& item : this->items) + { + GC::Mark(item.first); + GC::Mark(item.second); + } + } +} \ No newline at end of file