ASH changes in 7.8

Veracity

Developer
Staff member
- ASH provides the ability to save and retrieve settings in the character-specific .kcs file.

Code:
     string get_property(string) 
     void set_property(string,string)

- ASH provides aggregate variables in the form of a "map".

A map is indexed by one data type (the key) and associates that key with another (or the same) data type (the value). The key can be any ASH simple data type: boolean, int, float, string, item, zodiac, location, class, stat, skill, effect, familiar, slot, or monster. The value can be any of those or can be an aggregate: another map. This effectively allows multi-dimensional maps and. In fact, that's how the syntax we provide for multi-dimensional aggregates actually operates: maps of maps of maps ...

You can declare a map any time you can declare a variable: as a top level (global) variable, as a function parameter, or as a local variable in any scope.

You can fetch data from a map any time you can provide a data value: in an expression, as a function parameter, on the right side of an assignment statement, from a "return" statement, as so on. You can pass around entire maps, individual elements, or intermediate maps: "slices".

If you use a map on the left side of an assignment, you set the whole map at once to the new value. If you specify a map and a complete set of indices (of the correct types) on the left side of an assignment statement, you set a single element. If you specify a map and a prefix of indices (of the correct type), you directly set one of the intermediate maps, a "slice".

The syntax for declaring the data type of a map:

Code:
      <data type> [ <key type>, ... ] <variablename>

The syntax for referencing an element (or slice) of a map:

Code:
      <variablename>[ <key expression>, ... ]

All the key expressions will be evaluated at run time. If you specify all the keys the map expects, you fetch data of the type specified by the map. If you specify fewer keys than the map expects, you get an intermediate map, a "slice".

As an example:

Code:
      boolean [string, string] props;

might be used to hold "properties" associated with names.

Code:
      props[ "dog", "mammal" ] = true;
      props[ "dog", "pet" ] = true;
      props[ "dog", "fun" ] = false;
      props[ "turtle", "mammal" ] = false;
      props[ "turtle", "pet" ] = true;
      props[ "turtle", "fun" ] = false;
      props[ "aardvark", "mammal" ] = true;
      props[ "aardvark", "pet" ] = false;
      props[ "aardvark", "fun" ] = true;

references:

Code:
      print( props[ "dog", "mammal"] );
      => true
      boolean [string] animal = props[ "turtle" ];
      print( animal[ "fun" ] );
      ==> false

You can test the presence of a key in a map using the "contains" operator:

Code:
      <aggregate reference expression> contains <key expression>

Where <aggregate reference expression> must evaluate at run time to a map or slice, and <key expression> must evaluate at run time to a key of the appropriate type. (Note that that is enforced at parse time; ASH can tell the datatype any expression will produce).

Code:
      props contains "dog" => true
      props contains "elephant" => false
      props[ "aardvark" ] contains "fun" => true
      animal contains "pet" => true
      animal contains "favorite food" => false

And that's it for aggregates in 7.8. Missing features:

- A way to iterate over all the keys of a map (or slice). I have submitted the "foreach" command into the codebase, so next release (or next daily build) will let you do:

Code:
      int [int, int] map2;

      foreach key1 in map2
          foreach key2 in map2[key1]
              print( "map2[" + key1 + "," + key2 + "] = " + map2[key1,key2] );

- A way to initialize a map with values when you declare it, just as you can do with simple data type variables. I'm in no hurry to add this, since it doesn't provide you anything you can't already do with a sequence of assignment statements after the declaration, and it's no less efficient to do it that way, as opposed to simple variables, where not specifying an initialization results in it getting initialized to a default value, which is then replaced.

- The main() function can have parameters, which makes ASH prompt the user for them when you invoke the script. There's no support for having aggregates in that role; we have no syntax for letting the user specify the contents.
 

macman104

Member
[quote author=Veracity link=topic=184.msg915#msg915 date=1148913423]- The main() function can have parameters, which makes ASH prompt the user for them when you invoke the script. There's no support for having aggregates in that role; we have no syntax for letting the user specify the contents.
[/quote]So, when you say prompt the user for them, how does it prompt them? I assume you weren't meaning for a cin type feature, but hey, that'd be pretty awesome!
 

Veracity

Developer
Staff member
[quote author=macman104 link=topic=184.msg918#msg918 date=1148926765]
So, when you say prompt the user for them, how does it prompt them?  I assume you weren't meaning for a cin type feature, but hey, that'd be pretty awesome!
[/quote]

It doesn't prompt for them.

In fact, it probably leaves the variable uninitialized, such that if you reference it in your main() function, you'll get an Exception. I should fix that; I put in no code to deal with it since I expected that people wouldn't do it - especially after I told them that it didn't work.

"Doc, it crashes when I do that."
"Stop doing that."

:)
 
Top