Chaiscript metaprogramming


#1

Hi !

I am trying to do “metaprogramming” in Chaiscript : write a script that will generate another script and evaluate it. This works fine, but I also want it to be able to reference variables from the first script. For example :

var k := 2;
eval("print(k);");

This throws an error saying that the variable “k” does not exist.

Is it possible to evaluate a script without creating a new stack ?

Florian


#2

You can save locals from the first script and load them in the second one maybe ?


#3

Hi Sygmei !

I tried what you suggested, but without success.

I exposed two functions to Chaiscript :

  • saveLocals that will save the locals in a C++ variable;
  • loadLocals that will load them in chaiscript.

The problem is that when I call saveLocals from within Chaiscript, there is no “locals” in the returned map (When I call it after the execution of the script it works). And even if I save locals after the execution of the first script, I would have to call loadLocals in the eval of the second one, and this does not work either…

Any other suggestion ?

Thanks for your help !

Florian


#4

One thing I did in my game is that when my script want to saveLocals, he calls the function. The function will kill the thread and end the current eval. But it will also send a signal named “reload:[S]” for : reload & save.

The place where the script has been created (Console for me) will see that the script is dead and it will check the signal. If the signal is reload it will reboot the thread, it also check the attributes of the reload signal : S for save, L for load, etc…
The parameter in the reload function represents which part of the reload I want to do (Loading and Saving in the save reload is not really useful for example).

void ScriptEnv::reload(bool partPModule, bool partOctopus, bool partLoad, bool partSave) {
    reloadStates["partPModule"] = true;
    reloadStates["partOctopus"] = true;
    reloadStates["partLoad"] = true;
    reloadStates["partSave"] = true;
    if (partPModule)
    {
        for (int i = 0; i < permaModules.size(); i++)
        {
            loadModule(permaModules[i]);
        }
    }
    this->log("Script Reload..", 255, 128, 0);
    this->kill();
    if (threadExec)
        this->scrThread->join();
    if (partSave && willSaveState)
    {
        this->log("Save New Script State..", 255, 0, 255);
        this->stateDatabase[stateToSave] = this->scrExec->get_locals();
        willSaveState = false;
    }
    if (partLoad && willApplyState)
    {
        this->log("Apply New Script State..", 255, 0, 255);
        this->scrExec->set_locals(stateDatabase[stateToApply]);
        willApplyState = false;
    }
    if (partOctopus)
    {
        for (int i = 0; i < feedList.size(); i++)
        {
            objectLoader(this->scrExec, feedList[i].first, feedList[i].second);
            this->log("[Octopus] fLoad of : " + feedList[i].first + " successful", 0, 255, 0);
        }
        feedList.clear();
    }
    free(this->scrThread);
    this->scrThread = new std::thread(&ScriptEnv::run, this);
}