The Eval function and other issues in 5.4

The Pixie
03 Jul 2013, 07:52
As of Quest 5.4, the eval function requires a dictionary as a second parameter; previously this was optional. Consequently this will no longer work:

<!--Saved by Quest 5.4.4873.16527-->
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test_eval">
<gameid>d2528707-4046-43a3-a019-fdcbb3832ab9</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<start type="script">
val = Eval("2 + 2")
msg ("val is " + val)
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>


Is this a bug? I do not even know what the required dictionary even does. The documentation should at least be updated, hopefully to explain how to use that dictionary.

One work around is to send an empty dictionary:

<!--Saved by Quest 5.4.4873.16527-->
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test_eval">
<gameid>d2528707-4046-43a3-a019-fdcbb3832ab9</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<start type="script">
val = Eval("2 + 2", game.empty)
msg ("val is " + val)
</start>
<empty type="stringdictionary" />
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>


A second is to define your own functions that will add the empty dictionary. As far as I can see, you need one per return type, though Eval itself gets around that

<!--Saved by Quest 5.4.4873.16527-->
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test_eval">
<gameid>d2528707-4046-43a3-a019-fdcbb3832ab9</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<empty type="stringdictionary" />
<start type="script">
val = IntEval("2 + 2")
msg ("val is " + val)
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
<function name="StrEval" parameters="s" type="string">
return (Eval (s, game.empty))
</function>
<function name="IntEval" parameters="s" type="int">
return (Eval (s, game.empty))
</function>
</asl>


It is a strange function, Eval, as Quest seems to be happy if you call it "eval" or "EVAL"; most functions (and script commands) you need to get the capitalisation spot on.

jaynabonne
03 Jul 2013, 08:52
Yes, eval is a bit odd. :)

The dictionary allows you to pass additional parameters into the eval context. They show up as variables when eval executes. A lame example:

      params = NewDictionary()
dictionary add(params, "x", 50)
dictionary add(params, "y", 100)
msg(eval ("x + y", params))


yields 150. It might seem pointless there, but I have found it useful where I've varied the string being eval'd and use the parameters to provide context variables the different eval strings can choose from (e.g. when evaluating conditions or building output strings, where the eval string is a varying format).

For no parameters, you can do:

val = Eval("2 + 2", NewDictionary())


I think "eval" is a function of FLEE. I, too, have been confused about which is the correct casing. :)

Alex
03 Jul 2013, 09:15
I can see where the bug is, so I've just checked in a fix.

The Pixie
03 Jul 2013, 11:20
Thanks.

Jay, why don't you put that example into the Wiki document?

jaynabonne
03 Jul 2013, 11:47
Done!

The Pixie
03 Jul 2013, 12:50
Okay, here is another for you. I worked out what was wrong eventually, but instead of seeing a list of exits, you see the same number repeated each time:

<!--Saved by Quest 5.4.4873.16527-->
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test_allexits">
<gameid>2de3fb94-7205-4a1a-a1ca-177befc7756b</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<start type="script">
foreach (e, AllExits()) {
msg ("e is " + e + ", a " + TypeOf(e))
}
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="east" to="room2">
<inherit name="eastdirection" />
</exit>
<exit alias="north" to="room2">
<inherit name="northdirection" />
</exit>
</object>
<object name="room2">
<inherit name="editor_room" />
<exit alias="west" to="room">
<inherit name="westdirection" />
</exit>
<exit alias="south" to="room">
<inherit name="southdirection" />
</exit>
</object>
</asl>


I will post why it fails in a little while...

jaynabonne
03 Jul 2013, 13:01
Yep... don't name your variable "pi" either. :)

jaynabonne
03 Jul 2013, 13:20
I had a problem once before, as well, where I tried to have a variable named "cast". It turns out that that is a FLEE built-in function, so it gave me odd errors. At least in that case it did give errors. This one you ran into seems wrong - it shouldn't be silent about assigning to a built-in constant if that's not going to work.

The Pixie
03 Jul 2013, 18:57
Oops, my mistake. Ignore that.

The Pixie
03 Jul 2013, 19:08
Okay, what has happened to ListCombine? Still documented, but no sign of it.

The Pixie
04 Jul 2013, 06:47
Actually ListCombine is there, Quest just says it is not if you try to use it like this:

ListCombine (list1, list2)


Rather than like this:

list3 = ListCombine (list1, list2)


This is the error generated:

Error: Error adding script attribute 'start' to element 'game': Function not found: 'ListCombine'


Can I suggest a more informative error message?

The Pixie
04 Jul 2013, 06:59
It looks as though Quest 5.4 will preserve XML comments in the code (which is something I have wanted to see for some time). Can someone confirm that before I write a whole bunch of text that then disappears?

Also, for me the really big improvement in 5.4 is that you can edit code from within the GUI, saving you from switching from one view to the other. Big time saver.

jaynabonne
04 Jul 2013, 08:43
ListCombine is one of those built-in "expression functions". (My words.) It is hooked into FLEE rather than as a standard ASLX function. As such, it only exists within the context of an expression (e.g. an assignment expression). From the Quest compiler's point of view, the function actually doesn't exist, because it exists only for the expression evaluator.

For example, that's the difference between rundelegate and RunDelegateFunction. The former can be used outside of an expression (it has no return value). The latter has a return value and exists only in expressions, and it will come up "not found" if not used that way. That caused me some confusion initially...

The Pixie
12 Jul 2013, 12:51
This one is an example of an unhelpful error message (and probably predates 5.4):

Error running script: An item with the same key has already been added.

Caused by two cases in a switch statement having the same value. Took me a while to get that one.

switch (n) {
case (0) {}
case (0) {}

Alex
13 Jul 2013, 12:37
Please log these kinds of issues as bugs on the issue tracker and they'll be fixed.