Add reflective variables and fields

This commit is contained in:
2025-05-17 18:28:19 -05:00
parent a684c9ba45
commit bb19d2444c
8 changed files with 451 additions and 27 deletions

View File

@ -9,7 +9,7 @@
#include <variant>
namespace Tesses::CrossLang {
thread_local CallStackEntry* current_function=nullptr;
thread_local CallStackEntry* current_function=nullptr;
bool ToBool(TObject obj)
{
@ -2535,8 +2535,10 @@ namespace Tesses::CrossLang {
{
auto obj = std::get<THeapObjectHolder>(instance).obj;
auto list = dynamic_cast<TList*>(obj);
auto dynList = dynamic_cast<TDynamicList*>(obj);
auto bArray = dynamic_cast<TByteArray*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto ittr = dynamic_cast<TEnumerator*>(obj);
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
@ -3996,6 +3998,139 @@ namespace Tesses::CrossLang {
cse.back()->Push(gc, Undefined());
return false;
}
else if(dynList != nullptr)
{
if(key == "GetEnumerator")
{
cse.back()->Push(gc, TDynamicListEnumerator::Create(ls, dynList));
return false;
}
else if(key == "ToString")
{
cse.back()->Push(gc, dynList->ToString(ls));
return false;
}
else if(key == "Insert")
{
if(args.size() != 2)
{
throw VMException("List.Insert must only accept two arguments");
}
int64_t index;
if(!GetArgument(args,0,index))
{
throw VMException("List.Insert first argument must be Long");
}
cse.back()->Push(gc, dynList->Insert(ls,index,args[0]));
return false;
}
if(key == "Add")
{
if(args.size() != 1)
{
throw VMException("List.Add must only accept one argument");
}
cse.back()->Push(gc,dynList->Add(ls,args[0]));
return false;
}
if(key == "RemoveAllEqual")
{
if(args.size() != 1)
{
throw VMException("List.RemoveAllEqual must only accept one argument");
}
cse.back()->Push(gc,dynList->RemoveAllEqual(ls, args[0]));
return false;
}
if(key == "Remove")
{
if(args.size() != 1)
{
throw VMException("List.Remove must only accept one argument");
}
cse.back()->Push(gc,dynList->Remove(ls, args[0]));
return false;
}
if(key == "RemoveAt")
{
if(args.size() != 1)
{
throw VMException("List.RemoveAt must only accept one argument");
}
if(!std::holds_alternative<int64_t>(args[0]))
{
throw VMException("List.RemoveAt must only accept a long");
}
cse.back()->Push(gc,dynList->RemoveAt(ls,std::get<int64_t>(args[0])));
return false;
}
if(key == "Clear")
{
cse.back()->Push(gc, dynList->Clear(ls));
return false;
}
if(key == "GetAt")
{
if(args.size() != 1)
{
throw VMException("List.GetAt must only accept one argument");
}
if(!std::holds_alternative<int64_t>(args[0]))
{
throw VMException("List.GetAt must only accept a long");
}
int64_t index = std::get<int64_t>(args[0]);
if(index >= 0)
{
cse.back()->Push(gc, dynList->GetAt(ls,index));
return false;
}
}
if(key == "SetAt")
{
if(args.size() != 2)
{
throw VMException("List.SetAt must only accept two arguments");
}
if(!std::holds_alternative<int64_t>(args[0]))
{
throw VMException("List.SetAt first argument must only accept a long");
}
int64_t index = std::get<int64_t>(args[0]);
if(index >= 0)
{
cse.back()->Push(gc,dynList->SetAt(ls,index,args[1]));
return false;
}
}
if(key == "Count" || key == "Length")
{
cse.back()->Push(gc, dynList->Count(ls));
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
else if(dict != nullptr)
{
if(key == "ToString" && !dict->MethodExists(ls, key) && args.empty())
@ -4010,6 +4145,14 @@ namespace Tesses::CrossLang {
return InvokeMethod(ls,o,dict,args);
}
else if(dynDict != nullptr)
{
cse.back()->Push(gc,dict->CallMethod(ls, key, args));
return false;
}
else if(callable != nullptr)
{
if(key == "Call")
@ -4237,6 +4380,8 @@ namespace Tesses::CrossLang {
auto bA = dynamic_cast<TByteArray*>(obj);
auto list = dynamic_cast<TList*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto dynList = dynamic_cast<TDynamicList*>(obj);
auto tcallable = dynamic_cast<TCallable*>(obj);
auto closure = dynamic_cast<TClosure*>(obj);
auto externalMethod = dynamic_cast<TExternalMethod*>(obj);
@ -4246,6 +4391,7 @@ namespace Tesses::CrossLang {
auto callstackEntry = dynamic_cast<CallStackEntry*>(obj);
auto file = dynamic_cast<TFile*>(obj);
auto chunk = dynamic_cast<TFileChunk*>(obj);
if(file != nullptr)
{
@ -4538,6 +4684,29 @@ namespace Tesses::CrossLang {
return false;
}
}
if(dynList != nullptr)
{
if(key == "Count" || key == "Length")
{
int64_t len = dynList->Count(ls);
if(len < 0) len = 0;
stk->Push(gc, len);
return false;
}
}
if(dynDict != nullptr)
{
if(dynDict->MethodExists(ls,"get" + key))
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"get" + key, {}));
}
else
{
cse.back()->Push(gc, dynDict->GetField(ls,key));
}
return false;
}
if(dict != nullptr)
{
@ -4590,6 +4759,8 @@ namespace Tesses::CrossLang {
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto tcallable = dynamic_cast<TCallable*>(obj);
if(tcallable != nullptr)
{
@ -4627,6 +4798,19 @@ namespace Tesses::CrossLang {
}
}
if(dynDict != nullptr)
{
if(dynDict->MethodExists(ls,"set" + key))
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"set" + key, {value}));
}
else
{
dynDict->SetField(ls,key,value);
cse.back()->Push(gc,value);
}
return false;
}
if(dict != nullptr)
{
gc->BarrierBegin();