crosslang/src/types/closure.cpp

90 lines
2.7 KiB
C++

#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
GC* gc = ls.GetGC();
ls.Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TArgWrapper* TArgWrapper::Create(GCList* ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
GC* gc = ls->GetGC();
ls->Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TObject TArgWrapper::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
TList* argList = TList::Create(ls);
argList->items = args;
TObject v=this->callable->Call(ls,{argList});
current_function = cse;
return v;
}
void TArgWrapper::Mark()
{
if(this->marked) return;
this->marked = true;
this->callable->Mark();
}
void TClosure::Mark()
{
if(this->marked) return;
this->marked=true;
this->file->Mark();
this->env->Mark();
this->closure->Mark();
}
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->ownScope=ownScope;
GC* _gc = ls.GetGC();
ls.Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TClosure* TClosure::Create(GCList* ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->ownScope=ownScope;
GC* _gc = ls->GetGC();
ls->Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TObject TClosure::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
InterperterThread* thrd=InterperterThread::Create(ls);
thrd->AddCallStackEntry(ls,this, args);
thrd->Execute(ls.GetGC());
TObject v= thrd->call_stack_entries[0]->Pop(ls);
current_function = cse;
return v;
}
}