Time for some changes! Get Dialog version 0k/01 (library 0.39) here.
Simplified grammar
Language change: Access predicates can now have multiple definitions, and pattern matching is applied to the parameters. Thus:
@(magic rule [$Head | $Tail]) (ordinary rule $Head) (magic rule $Tail)
@(magic rule $Other) (ordinary rule $Other)
With the above access predicate definitions, the query (magic rule [hello little world])
would be transformed, at compile-time, into:
(ordinary rule @hello)
(ordinary rule @little)
(ordinary rule @world)
(ordinary rule [])
Such compile-time transformations are a sharp tool, to be used sparingly and with caution. But with this small language change, the library can now offer a simplified syntax for extending the parser grammar and adding new actions.
Previously, adding an action such as “TRANSMOGRIFY object WITH object” required a lot of boilerplate code:
(understand [transmogrify | $Words] as [transmogrify $Obj with $Tool])
*(split $Words by [with] into $Left and $Right)
*(understand $Left as non-all object $Obj)
*(understand $Right as single object $Tool preferably held)
But now, all you need is:
(grammar [transmogrify [object] with [single held]] for [transmogrify $ with $])
In light of this new syntax, most of the Understanding player input chapter of the manual has been reworked, and should be much easier to follow now.
You can still define (understand $ as $)
rules, for those odd situations where the new grammar-syntax is too simplistic. In fact, the parser still queries (understand $ as $)
as before, but the library provides a new rule for this predicate, which looks into a grammar table constructed at compile-time from (grammar $ for $)
definitions.
Not only is the new grammar syntax easier to read and work with, it also results in a more compact runtime representation, thus lowering the memory requirements of the parser and improving performance on 8-bit systems.
Accumulating sums
A new variant of the collect-into mechanism has been added to the language. This will exhaust every branch of the inner statement, look at the values taken on by a given expression, and add those values together.
You can use it e.g. to compute a score:
(accumulate $Score)
(puzzle a is solved) ($Score = 5)
(or)
(puzzle b is solved) ($Score = 1)
(or)
(puzzle c is solved) ($Score = 10)
(into $Sum)
You have a total score of $Sum.
Or merely count the branches:
(accumulate 1)
(puzzle a is solved)
(or)
(puzzle b is solved)
(or)
(puzzle c is solved)
(into $Sum)
You have solved $Sum puzzles.
You could also e.g. compute the total recursive weight of an object and its descendants. Assuming you’ve defined ($ has weight $)
for all relevant objects:
(accumulate $W)
{
($Obj = #player)
(or)
*($Obj has ancestor #player)
}
($Obj has weight $W)
(into $Sum)
The total weight is $Sum.
Other language changes
-
Added builtin
(fully bound $)
to check if a value is bound and, in case of a list, contains only fully bound elements. -
(split $ by $ into $ and $)
now accepts a single keyword as its second parameter (or a list of keywords, as before). -
Added special keypress words
@\u
,@\d
,@\l
,@\r
,@\n
,@\s
, and@\b
. Removed(word representing up $)
and friends. -
The character
+
may now be used in the source-code names of objects and local variables.
Other library changes
-
Relation objects (
#on
etc.) no longer have dictionary words. They appear directly inside action grammar rules instead, e.g.[put [held] on/onto [single]]
. -
Added intermediate action
[switch $]
that delegates to[switch on $]
or[switch off $]
. -
Bugfix: Duplicates are now removed from the list of choices in choice-mode.
And finally, there are some bugfixes and improvements to the optimizing compiler.