Clement Julia
Clement Julia

Reputation: 109

Use imported Algebraic Data Type in eval

I'm using the eval function to evaluate an abstract list pattern against a list and it keeps coming up with an Undeclared Variable error. Below is included a small reproducible example.

module PuzzleScript::Test::Engine::EvalExample

import util::Eval;
import IO;

data Animal = dog() | cat();

void main(){    
    bool boolean = [*_, cat(), *_] := [dog(), cat()];
    if (boolean) println("True 1");
    
    println("[*_, cat(), *_] := [dog(), cat()];");
    Result[bool] re = eval(#bool, "[*_, cat(), *_] := [dog(), cat()];");
    if (re.val) println("True 2");

}

Which generates the following error

Rascal Version: 0.18.2, see |release-notes://0.18.2|
rascal>import PuzzleScript::Test::Engine::EvalExample;
ok
rascal>main()
True 1
[*_, cat(), *_] := [dog(), cat()];
|std:///util/Eval.rsc|(622,1030,<23,0>,<60,95>): StaticError(
  "Undeclared variable: dog\nAdvice: |http://tutor.rascal-mpl.org/Errors/Static/UndeclaredVariable/UndeclaredVariable.html|",
  |eval:///?command=[*_,%2520cat(),%2520*_]%20:=%20[dog(),%2520cat()];|(20,3,<1,20>,<1,23>))
        at $evalinstance$0(|main://$evalinstance$0|)
        at *** somewhere ***(|std:///util/Eval.rsc|(622,1030,<23,0>,<60,95>))
        at eval(|project://AutomatedPuzzleScript/src/PuzzleScript/Test/Engine/EvalExample.rsc|(288,36,<13,31>,<13,67>))
        at $root$(|prompt:///|(0,47,<1,0>,<1,47>)ok
rascal>

As far as I understand, the error happens when it tries to evaluate the dog constructor on the right side of the pattern. I'm looking for a solution that would allow me to make the environment available to the eval function without having to re-import everything in the eval. The reason I'm doing it this way is that I haven't found a way to dynamically generate abstract patterns, if there's a way I'd be glad to hear about it since it is the root of my current issue.

Upvotes: 2

Views: 76

Answers (1)

Jurgen Vinju
Jurgen Vinju

Reputation: 6696

  • eval is not an often used function in Rascal; do you really need to dynamically create patterns?
  • there is the node pattern: (str name)() which in this case would match any constructor with no arguments
  • the real answer is that if you do import the right modules in the call to eval those modules will be cached by the interpreter which is used by the eval function
  • so that would not be slow
  • however, module reloading is not well-supported and you might have to restart the shell to get a fresh version into the eval evaluator.

Upvotes: 1

Related Questions