aichaos / rivescript-wd

The RiveScript Working Draft describes the language specification for RiveScript.
https://www.rivescript.com/
7 stars 3 forks source link

Add map and array support #1

Open kirsle opened 9 years ago

kirsle commented 9 years ago

Add support for hash maps and arrays in RiveScript.

Maps

Maps would be global variables (like bot variables). Their purpose is to hold simple key/value style data to simplify the reply structure for holding knowledge (examples would be: capitals of the states, etc.)

Syntax example:

// Define a map name and add key/value pairs one at a time
! map capitals CA = Sacramento
! map capitals MI = Lansing

// Define a map, provide the mappings immediately
! map capitals =
^ CA = Sacramento
^ MI = Lansing

// This would also have worked, but isn't as readable and won't be
// the preferred syntax:
! map capitals = CA = Sacramento
^ MI = Lansing

// If you "re-define" a map using the above syntax (provide the mappings
// immediately) on a map that already exists, your new key/value pairs
// will be merged with the existing ones. So you can add key/value pairs
// in bulk multiple times throughout your code with no problems. Map keys
// are always unique, though, so if you use the same key twice the value
// will be overwritten.

// Example of maps in use:
+ what is the capital of _
* <exists capitals <uppercase>> == true => The capital of <uppercase> is:\s
  ^ <map capitals <uppercase>>.
- I don't know what the capital of <uppercase> is.

New tags added to support maps:

Some syntax ideas to support maps as user variables.

+ i have a (@colors) *
- <set %colors:<star1>=<star2>>Okay.

+ do you know about my *
* <get %colors:<star>> != undefined => Yes, your\s
  ^ <star> was colored <get %colors:<star>> right?
- You didn't tell me what color it is.

Human> I have a blue car Bot> Okay. Human> Do you know about my car? Bot> Yes, your car was colored blue right?

The existing <get> and <set> tags would be repurposed for map variables. A map variable always has its name prefixed with a % symbol (like in Perl). To refer to a specific key, use a colon symbol ":".

Sets would be arrays for user variables, for holding a list of things in one variable.

Syntax examples:

+ i like the color *
- <add @color=<star>>I'll remember that you like <star>.

+ what colors do i like
- You like: <get @color>.
// would output e.g.: "You like: red, green, blue."

Existing variable-setting tags would be re-used, but array names are prefixed with an @ symbol.

Sets would work like the data type of the same name in Python: its contents would be de-duplicated. If you add the same item to the set twice, it only ends up going in one time.

Tags:

Some ideas to support iterating over set elements without making the syntax too ugly?

+ what are my favorite colors
* <get @colors:length> >= 2 => They are:\s
  ^ {iter @colors[:-1]}<item>,{/iter} and <get @colors[-1]>.
* <get @colors:length> == 1 => There is only <get @colors[0]>.
- You didn't tell me any.

Human> What are my favorite colors? (if they have 2 or more) Bot> They are: red, blue, yellow, and green. (if they have 1) Bot> There is only red. (if none) Bot> You didn't tell me any.

Tags:

Array index slices would work like in Python, so colors[:-1] meant "all colors except for the last one", example:

>>> colors = ["red", "blue", "yellow", "green"]
>>> colors[:-1]
['red', 'blue', 'yellow']